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-head
mailing list