svn commit: r269094 - head/usr.sbin/bhyve

Neel Natu neel at FreeBSD.org
Fri Jul 25 20:18:37 UTC 2014


Author: neel
Date: Fri Jul 25 20:18:35 2014
New Revision: 269094
URL: http://svnweb.freebsd.org/changeset/base/269094

Log:
  Simplify the meaning of return values from the inout handlers. After this
  change 0 means success and non-zero means failure.
  
  This also helps to eliminate VMEXIT_POWEROFF and VMEXIT_RESET as return values
  from VM-exit handlers.
  
  CR:		D480
  Reviewed by:	grehan, jhb

Modified:
  head/usr.sbin/bhyve/atkbdc.c
  head/usr.sbin/bhyve/bhyverun.c
  head/usr.sbin/bhyve/bhyverun.h
  head/usr.sbin/bhyve/inout.c
  head/usr.sbin/bhyve/inout.h
  head/usr.sbin/bhyve/pm.c

Modified: head/usr.sbin/bhyve/atkbdc.c
==============================================================================
--- head/usr.sbin/bhyve/atkbdc.c	Fri Jul 25 18:41:56 2014	(r269093)
+++ head/usr.sbin/bhyve/atkbdc.c	Fri Jul 25 20:18:35 2014	(r269094)
@@ -31,6 +31,10 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/vmm.h>
 
+#include <vmmapi.h>
+
+#include <assert.h>
+#include <errno.h>
 #include <stdio.h>
 
 #include "inout.h"
@@ -48,29 +52,30 @@ atkbdc_data_handler(struct vmctx *ctx, i
     uint32_t *eax, void *arg)
 {
 	if (bytes != 1)
-		return (INOUT_ERROR);
+		return (-1);
 
 	*eax = 0;
 
-	return (INOUT_OK);
+	return (0);
 }
 
 static int
 atkbdc_sts_ctl_handler(struct vmctx *ctx, int vcpu, int in, int port,
     int bytes, uint32_t *eax, void *arg)
 {
-	int retval;
+	int error, retval;
 
 	if (bytes != 1)
-		return (INOUT_ERROR);
+		return (-1);
 
-	retval = INOUT_OK;
+	retval = 0;
 	if (in) {
 		*eax = KBD_SYS_FLAG;	/* system passed POST */
 	} else {
 		switch (*eax) {
 		case KBDC_RESET:	/* Pulse "reset" line. */
-			retval = INOUT_RESET;
+			error = vm_suspend(ctx, VM_SUSPEND_RESET);
+			assert(error == 0 || errno == EALREADY);
 			break;
 		}
 	}

Modified: head/usr.sbin/bhyve/bhyverun.c
==============================================================================
--- head/usr.sbin/bhyve/bhyverun.c	Fri Jul 25 18:41:56 2014	(r269093)
+++ head/usr.sbin/bhyve/bhyverun.c	Fri Jul 25 20:18:35 2014	(r269094)
@@ -107,8 +107,6 @@ struct bhyvestats {
         uint64_t        vmexit_inst_emul;
         uint64_t        cpu_switch_rotate;
         uint64_t        cpu_switch_direct;
-        int             io_reset;
-	int		io_poweroff;
 } stats;
 
 struct mt_vmm_info {
@@ -331,27 +329,18 @@ vmexit_inout(struct vmctx *ctx, struct v
 	}
 
 	error = emulate_inout(ctx, vcpu, vme, strictio);
-	if (error == INOUT_OK && in && !string) {
+	if (!error && in && !string) {
 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX,
 		    vme->u.inout.eax);
+		assert(error == 0);
 	}
 
-	switch (error) {
-	case INOUT_OK:
-		return (VMEXIT_CONTINUE);
-	case INOUT_RESTART:
-		return (VMEXIT_RESTART);
-	case INOUT_RESET:
-		stats.io_reset++;
-		return (VMEXIT_RESET);
-	case INOUT_POWEROFF:
-		stats.io_poweroff++;
-		return (VMEXIT_POWEROFF);
-	default:
-		fprintf(stderr, "Unhandled %s%c 0x%04x\n",
-			in ? "in" : "out",
-			bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), port);
+	if (error) {
+		fprintf(stderr, "Unhandled %s%c 0x%04x\n", in ? "in" : "out",
+		    bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), port);
 		return (VMEXIT_ABORT);
+	} else {
+		return (VMEXIT_CONTINUE);
 	}
 }
 
@@ -581,7 +570,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uin
 {
 	int error, rc, prevcpu;
 	enum vm_exitcode exitcode;
-	enum vm_suspend_how how;
 	cpuset_t active_cpus;
 
 	if (vcpumap[vcpu] != NULL) {
@@ -616,16 +604,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uin
 		case VMEXIT_RESTART:
                         rip = vmexit[vcpu].rip;
 			break;
-		case VMEXIT_RESET:
-		case VMEXIT_POWEROFF:
-			if (rc == VMEXIT_RESET)
-				how = VM_SUSPEND_RESET;
-			else
-				how = VM_SUSPEND_POWEROFF;
-			error = vm_suspend(ctx, how);
-			assert(error == 0 || errno == EALREADY);
-                        rip = vmexit[vcpu].rip + vmexit[vcpu].inst_length;
-			break;
 		case VMEXIT_ABORT:
 			abort();
 		default:

Modified: head/usr.sbin/bhyve/bhyverun.h
==============================================================================
--- head/usr.sbin/bhyve/bhyverun.h	Fri Jul 25 18:41:56 2014	(r269093)
+++ head/usr.sbin/bhyve/bhyverun.h	Fri Jul 25 20:18:35 2014	(r269094)
@@ -38,8 +38,6 @@
 #define	VMEXIT_CONTINUE		1	/* continue from next instruction */
 #define	VMEXIT_RESTART		2	/* restart current instruction */
 #define	VMEXIT_ABORT		3	/* abort the vm run loop */
-#define	VMEXIT_RESET		4	/* guest machine has reset */
-#define	VMEXIT_POWEROFF		5	/* guest machine has powered off */
 
 struct vmctx;
 extern int guest_ncpus;

Modified: head/usr.sbin/bhyve/inout.c
==============================================================================
--- head/usr.sbin/bhyve/inout.c	Fri Jul 25 18:41:56 2014	(r269093)
+++ head/usr.sbin/bhyve/inout.c	Fri Jul 25 20:18:35 2014	(r269094)
@@ -154,27 +154,28 @@ emulate_inout(struct vmctx *ctx, int vcp
 		/* Limit number of back-to-back in/out emulations to 16 */
 		iterations = MIN(count, 16);
 		while (iterations > 0) {
+			assert(retval == 0);
 			if (vie_calculate_gla(vis->paging.cpu_mode,
 			    vis->seg_name, &vis->seg_desc, index, bytes,
 			    addrsize, prot, &gla)) {
 				vm_inject_gp(ctx, vcpu);
-				retval = INOUT_RESTART;
 				break;
 			}
 
 			error = vm_copy_setup(ctx, vcpu, &vis->paging, gla,
 			    bytes, prot, iov, nitems(iov));
-			assert(error == 0 || error == 1 || error == -1);
-			if (error) {
-				retval = (error == 1) ? INOUT_RESTART :
-				    INOUT_ERROR;
+			if (error == -1) {
+				retval = -1;  /* Unrecoverable error */
+				break;
+			} else if (error == 1) {
+				retval = 0;  /* Resume guest to handle fault */
 				break;
 			}
 
 			if (vie_alignment_check(vis->paging.cpl, bytes,
 			    vis->cr0, vis->rflags, gla)) {
 				vm_inject_ac(ctx, vcpu, 0);
-				return (INOUT_RESTART);
+				break;
 			}
 
 			val = 0;
@@ -213,8 +214,8 @@ emulate_inout(struct vmctx *ctx, int vcp
 		}
 
 		/* Restart the instruction if more iterations remain */
-		if (retval == INOUT_OK && count != 0)
-			retval = INOUT_RESTART;
+		if (retval == 0 && count != 0)
+			vmexit->inst_length = 0;
 	} else {
 		if (!in) {
 			val = vmexit->u.inout.eax & vie_size2mask(bytes);

Modified: head/usr.sbin/bhyve/inout.h
==============================================================================
--- head/usr.sbin/bhyve/inout.h	Fri Jul 25 18:41:56 2014	(r269093)
+++ head/usr.sbin/bhyve/inout.h	Fri Jul 25 20:18:35 2014	(r269094)
@@ -34,13 +34,9 @@
 struct vmctx;
 struct vm_exit;
 
-/* Handler return values. */
-#define	INOUT_ERROR	-1
-#define	INOUT_OK	0
-#define	INOUT_RESTART	1
-#define	INOUT_RESET	2
-#define	INOUT_POWEROFF	3
-
+/*
+ * inout emulation handlers return 0 on success and -1 on failure.
+ */
 typedef int (*inout_func_t)(struct vmctx *ctx, int vcpu, int in, int port,
 			    int bytes, uint32_t *eax, void *arg);
 

Modified: head/usr.sbin/bhyve/pm.c
==============================================================================
--- head/usr.sbin/bhyve/pm.c	Fri Jul 25 18:41:56 2014	(r269093)
+++ head/usr.sbin/bhyve/pm.c	Fri Jul 25 20:18:35 2014	(r269094)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/vmm.h>
 
 #include <assert.h>
+#include <errno.h>
 #include <pthread.h>
 #include <signal.h>
 #include <vmmapi.h>
@@ -56,6 +57,8 @@ static int
 reset_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
     uint32_t *eax, void *arg)
 {
+	int error;
+
 	static uint8_t reset_control;
 
 	if (bytes != 1)
@@ -66,8 +69,10 @@ reset_handler(struct vmctx *ctx, int vcp
 		reset_control = *eax;
 
 		/* Treat hard and soft resets the same. */
-		if (reset_control & 0x4)
-			return (INOUT_RESET);
+		if (reset_control & 0x4) {
+			error = vm_suspend(ctx, VM_SUSPEND_RESET);
+			assert(error == 0 || errno == EALREADY);
+		}
 	}
 	return (0);
 }
@@ -224,6 +229,7 @@ static int
 pm1_control_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
     uint32_t *eax, void *arg)
 {
+	int error;
 
 	if (bytes != 2)
 		return (-1);
@@ -243,8 +249,10 @@ pm1_control_handler(struct vmctx *ctx, i
 		 * says that '5' should be stored in SLP_TYP for S5.
 		 */
 		if (*eax & PM1_SLP_EN) {
-			if ((pm1_control & PM1_SLP_TYP) >> 10 == 5)
-				return (INOUT_POWEROFF);
+			if ((pm1_control & PM1_SLP_TYP) >> 10 == 5) {
+				error = vm_suspend(ctx, VM_SUSPEND_POWEROFF);
+				assert(error == 0 || errno == EALREADY);
+			}
 		}
 	}
 	return (0);


More information about the svn-src-head mailing list