Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Jan 2010 11:28:01 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r201890 - head/sys/amd64/amd64
Message-ID:  <201001091128.o09BS1MQ086738@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001091128.o09BS1MQ086738>