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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to