Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Oct 2017 12:50:03 +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: r324313 - head/sys/amd64/amd64
Message-ID:  <201710051250.v95Co31e048931@repo.freebsd.org>

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



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