Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Oct 2014 01:54:37 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r273807 - stable/10/sys/amd64/vmm
Message-ID:  <201410290154.s9T1sbQJ012361@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Wed Oct 29 01:54:37 2014
New Revision: 273807
URL: https://svnweb.freebsd.org/changeset/base/273807

Log:
  MFC r273666.
  Don't pass the 'error' return from an I/O port handler directly to vm_run().

Modified:
  stable/10/sys/amd64/vmm/vmm_ioport.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/amd64/vmm/vmm_ioport.c
==============================================================================
--- stable/10/sys/amd64/vmm/vmm_ioport.c	Wed Oct 29 01:15:48 2014	(r273806)
+++ stable/10/sys/amd64/vmm/vmm_ioport.c	Wed Oct 29 01:54:37 2014	(r273807)
@@ -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?201410290154.s9T1sbQJ012361>