svn commit: r201890 - head/sys/amd64/amd64

Konstantin Belousov kib at FreeBSD.org
Sat Jan 9 11:28:01 UTC 2010


Author: kib
Date: Sat Jan  9 11:28:01 2010
New Revision: 201890
URL: http://svn.freebsd.org/changeset/base/201890

Log:
  Set md_ldt (pointer to the LDT) after md_ldt_sd (system segment
  descriptor for the LDT) is populated. md_ldt is used by context-switch
  code as indicator that LDT segment register shall be loaded with
  GUSERLDT segment instead of 0, so context switch at the wrong time may
  cause attempt to load non-populated descriptor.
  
  Use store with the barrier to prevent other CPUs from seeing updated
  md_ldt but not seeing updated md_ldt_sd. Multithreaded process may
  context-switch to another thread of the process on another CPU and read
  md_ldt.
  
  MFC after:	1 week

Modified:
  head/sys/amd64/amd64/sys_machdep.c

Modified: head/sys/amd64/amd64/sys_machdep.c
==============================================================================
--- head/sys/amd64/amd64/sys_machdep.c	Sat Jan  9 10:24:09 2010	(r201889)
+++ head/sys/amd64/amd64/sys_machdep.c	Sat Jan  9 11:28:01 2010	(r201890)
@@ -420,13 +420,14 @@ user_ldt_alloc(struct proc *p, int force
 		return (pldt);
 	}
 
-	mdp->md_ldt = new_ldt;
 	if (pldt != NULL) {
 		bcopy(pldt->ldt_base, new_ldt->ldt_base, max_ldt_segment *
 		    sizeof(struct user_segment_descriptor));
 		user_ldt_derefl(pldt);
 	}
 	ssdtosyssd(&sldt, &p->p_md.md_ldt_sd);
+	atomic_store_rel_ptr((volatile uintptr_t *)&mdp->md_ldt,
+	    (uintptr_t)new_ldt);
 	if (p == curproc)
 		set_user_ldt(mdp);
 


More information about the svn-src-all mailing list