Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Oct 2014 01:06:58 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r273356 - head/sys/amd64/amd64
Message-ID:  <201410210106.s9L16wXd016764@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Tue Oct 21 01:06:58 2014
New Revision: 273356
URL: https://svnweb.freebsd.org/changeset/base/273356

Log:
  Fix a race in pmap_emulate_accessed_dirty() that could trigger a EPT
  misconfiguration VM-exit.
  
  An EPT misconfiguration is triggered when the processor encounters a PTE
  that is writable but not readable (WR=10). On processors that require A/D
  bit emulation PG_M and PG_A map to EPT_PG_WRITE and EPT_PG_READ respectively.
  
  If the PTE is updated as in the following code snippet:
  	*pte |= PG_M;
  	*pte |= PG_A;
  then it is possible for another processor to observe the PTE after the PG_M
  (aka EPT_PG_WRITE) bit is set but before PG_A (aka EPT_PG_READ) bit is set.
  
  This will trigger an EPT misconfiguration VM-exit on the other processor.
  
  Reported by:	rodrigc
  Reviewed by:	grehan
  MFC after:	3 days

Modified:
  head/sys/amd64/amd64/pmap.c

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Tue Oct 21 00:07:37 2014	(r273355)
+++ head/sys/amd64/amd64/pmap.c	Tue Oct 21 01:06:58 2014	(r273356)
@@ -6810,9 +6810,19 @@ retry:
 	if (ftype == VM_PROT_WRITE) {
 		if ((*pte & PG_RW) == 0)
 			goto done;
-		*pte |= PG_M;
+		/*
+		 * Set the modified and accessed bits simultaneously.
+		 *
+		 * Intel EPT PTEs that do software emulation of A/D bits map
+		 * PG_A and PG_M to EPT_PG_READ and EPT_PG_WRITE respectively.
+		 * An EPT misconfiguration is triggered if the PTE is writable
+		 * but not readable (WR=10). This is avoided by setting PG_A
+		 * and PG_M simultaneously.
+		 */
+		*pte |= PG_M | PG_A;
+	} else {
+		*pte |= PG_A;
 	}
-	*pte |= PG_A;
 
 	/* try to promote the mapping */
 	if (va < VM_MAXUSER_ADDRESS)



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