Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Oct 2014 16:49:29 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org
Subject:   svn commit: r273832 - in releng/10.1/sys/amd64: amd64 vmm
Message-ID:  <201410291649.s9TGnTkH034400@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Wed Oct 29 16:49:28 2014
New Revision: 273832
URL: https://svnweb.freebsd.org/changeset/base/273832

Log:
  MFS10 r273573, MFC r273356:
  Fix a race in pmap_emulate_accessed_dirty() that could trigger a EPT
  misconfiguration VM-exit.
  
  MFS10 r273807, MFC r273666:
  Don't pass the 'error' return from an I/O port handler directly to vm_run().
  
  Approved by:	re (kib)

Modified:
  releng/10.1/sys/amd64/amd64/pmap.c
  releng/10.1/sys/amd64/vmm/vmm_ioport.c
Directory Properties:
  releng/10.1/   (props changed)

Modified: releng/10.1/sys/amd64/amd64/pmap.c
==============================================================================
--- releng/10.1/sys/amd64/amd64/pmap.c	Wed Oct 29 16:48:18 2014	(r273831)
+++ releng/10.1/sys/amd64/amd64/pmap.c	Wed Oct 29 16:49:28 2014	(r273832)
@@ -6787,9 +6787,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)

Modified: releng/10.1/sys/amd64/vmm/vmm_ioport.c
==============================================================================
--- releng/10.1/sys/amd64/vmm/vmm_ioport.c	Wed Oct 29 16:48:18 2014	(r273831)
+++ releng/10.1/sys/amd64/vmm/vmm_ioport.c	Wed Oct 29 16:49:28 2014	(r273832)
@@ -106,15 +106,14 @@ emulate_inout_port(struct vm *vm, int vc
 	uint32_t mask, val;
 	int error;
 
-	error = 0;
-	*retu = true;
-
-	if (vmexit->u.inout.port >= MAX_IOPORTS)
-		goto done;
-
-	handler = ioport_handler[vmexit->u.inout.port];
-	if (handler == NULL)
-		goto done;
+	/*
+	 * If there is no handler for the I/O port then punt to userspace.
+	 */
+	if (vmexit->u.inout.port >= MAX_IOPORTS ||
+	    (handler = ioport_handler[vmexit->u.inout.port]) == NULL) {
+		*retu = true;
+		return (0);
+	}
 
 	mask = vie_size2mask(vmexit->u.inout.bytes);
 
@@ -124,20 +123,27 @@ emulate_inout_port(struct vm *vm, int vc
 
 	error = (*handler)(vm, vcpuid, vmexit->u.inout.in,
 	    vmexit->u.inout.port, vmexit->u.inout.bytes, &val);
+	if (error) {
+		/*
+		 * The value returned by this function is also the return value
+		 * of vm_run(). This needs to be a positive number otherwise it
+		 * can be interpreted as a "pseudo-error" like ERESTART.
+		 *
+		 * Enforce this by mapping all errors to EIO.
+		 */
+		return (EIO);
+	}
 
-	if (!error) {
-		*retu = false;
-		if (vmexit->u.inout.in) {
-			vmexit->u.inout.eax &= ~mask;
-			vmexit->u.inout.eax |= val & mask;
-			error = vm_set_register(vm, vcpuid,
-			    VM_REG_GUEST_RAX, vmexit->u.inout.eax);
-			KASSERT(error == 0, ("emulate_ioport: error %d "
-			    "setting guest rax register", error));
-		}
+	if (vmexit->u.inout.in) {
+		vmexit->u.inout.eax &= ~mask;
+		vmexit->u.inout.eax |= val & mask;
+		error = vm_set_register(vm, vcpuid, VM_REG_GUEST_RAX,
+		    vmexit->u.inout.eax);
+		KASSERT(error == 0, ("emulate_ioport: error %d setting guest "
+		    "rax register", error));
 	}
-done:
-	return (error);
+	*retu = false;
+	return (0);
 }
 
 static int



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