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>