svn commit: r324313 - head/sys/amd64/amd64
Konstantin Belousov
kib at FreeBSD.org
Thu Oct 5 12:50:04 UTC 2017
Author: kib
Date: Thu Oct 5 12:50:03 2017
New Revision: 324313
URL: https://svnweb.freebsd.org/changeset/base/324313
Log:
Avoid a race betweem freeing LDT and context switches.
cpu_switch.S uses curproc->p_md.md_ldt value as the flag indicating
presence of the process LDT. The flag is checked and then ldt segment
descriptor is copied into the CPU' GDT slot.
Disallow context switches around clearing of the curproc LDT state by
performing the cleanup in critical section. Ensure that the md_ldt
flag is cleared before md_ldt_sd descriptor content is destroyed by
inserting fence between the operations.
We depend on the x86 memory model strong ordering guarantees, in
particular, that cpu_switch.S observes the writes to md_ldt and
md_ldt_sd in the expected order.
Discussed with: bde
Sponsored by: The FreeBSD Foundation
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 Thu Oct 5 12:38:26 2017 (r324312)
+++ head/sys/amd64/amd64/sys_machdep.c Thu Oct 5 12:50:03 2017 (r324313)
@@ -514,10 +514,13 @@ user_ldt_free(struct thread *td)
return;
}
+ critical_enter();
mdp->md_ldt = NULL;
+ atomic_thread_fence_rel();
bzero(&mdp->md_ldt_sd, sizeof(mdp->md_ldt_sd));
if (td == curthread)
lldt(GSEL(GNULL_SEL, SEL_KPL));
+ critical_exit();
user_ldt_deref(pldt);
}
More information about the svn-src-all
mailing list