Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Succesful transition to vmxassist, then to the bios, where it dies in keyboard init.
Andy Gocke [Thu, 13 Aug 2009 22:45:23 +0000 (17:45 -0500)]
bios/vmxassist/setup.c
bios/vmxassist/vmxassist.bin
palacios/include/palacios/vmcs.h
palacios/include/palacios/vmx.h
palacios/include/palacios/vmx_handler.h
palacios/src/devices/8259a.c
palacios/src/palacios/vmx.c
palacios/src/palacios/vmx_handler.c
palacios/src/palacios/vmx_io.c
palacios/src/palacios/vmx_lowlevel.S

index 0576900..c453ecd 100644 (file)
@@ -368,8 +368,7 @@ start_bios(void)
 int
 main(void)
 {
-
-  printf("Hello from VMXAssist\n");
+    printf("Hello from VMXAssist\n");
 
        if (booting_cpu == 0)
                banner();
index af5d958..1cafb02 100644 (file)
Binary files a/bios/vmxassist/vmxassist.bin and b/bios/vmxassist/vmxassist.bin differ
index 491f80e..bff2e21 100644 (file)
 #define   HOST_ADDR_SPACE_SIZE          0x00000200
 #define   ACK_IRQ_ON_EXIT               0x00008000
 
+/* Control register exit masks */
+#define   CR0_PE        0x00000001
+#define   CR0_PG        0x80000000
+#define   CR4_VMXE      0x00002000
+
 typedef enum {
     VMCS_GUEST_ES_SELECTOR       = 0x00000800,
     VMCS_GUEST_CS_SELECTOR       = 0x00000802,
@@ -216,56 +221,6 @@ void v3_print_vmcs();
 
 
 
-/* VMCS Exit QUALIFICATIONs */
-struct vmcs_io_qual {
-    uint32_t accessSize : 3; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
-    uint32_t dir        : 1; // (0: Out ;; 1: In)
-    uint32_t string     : 1; // (0: not string ;; 1: string)
-    uint32_t REP        : 1; // (0: not REP ;; 1: REP)
-    uint32_t opEnc      : 1; // (0: DX ;; 1: immediate)
-    uint32_t rsvd       : 9; // Set to 0
-    uint32_t port       : 16; // IO Port Number
-} __attribute__((packed));
-
-
-
-struct VMExitDBGQual {
-    uint32_t B0         : 1; // Breakpoint 0 condition met
-    uint32_t B1         : 1; // Breakpoint 1 condition met
-    uint32_t B2         : 1; // Breakpoint 2 condition met
-    uint32_t B3         : 1; // Breakpoint 3 condition met
-    uint32_t rsvd       : 9; // reserved to 0
-    uint32_t BD         : 1; // detected DBG reg access
-    uint32_t BS         : 1; // cause either single instr or taken branch
-} __attribute__((packed));
-
-
-struct VMExitTSQual {
-    uint32_t selector   : 16; // selector of destination TSS 
-    uint32_t rsvd       : 14; // reserved to 0
-    uint32_t src        : 2; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
-} __attribute__((packed));
-
-struct VMExitCRQual {
-    uint32_t crID       : 4; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
-    uint32_t accessType : 2; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
-    uint32_t lmswOpType : 1; // (0: register ; 1: memory)
-    uint32_t rsvd1      : 1; // reserved to 0
-    uint32_t gpr        : 4; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
-    uint32_t rsvd2      : 4; // reserved to 0
-    uint32_t lmswSrc    : 16; // src data for lmsw
-} __attribute__((packed));
-
-struct VMExitMovDRQual {
-    uint32_t regID      : 3; // debug register number
-    uint32_t rsvd1      : 1; // reserved to 0
-    uint32_t dir        : 1; // (0: MOV to DR , 1: MOV from DR)
-    uint32_t rsvd2      : 3; // reserved to 0
-    uint32_t gpr        : 4; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
-} __attribute__((packed));
-
-/* End Exit Qualifications */
-
 /* Exit Vector Info */
 struct VMExitIntInfo {
     uint32_t nr         : 8; // IRQ number, exception vector, NMI = 2 
@@ -281,6 +236,46 @@ struct VMExitIntInfo {
 
 /*  End Exit Vector Info */
 
+struct vmx_exception_bitmap {
+    union {
+        uint32_t value;
+    struct {
+        uint_t de          : 1; // (0) divide by zero
+        uint_t db          : 1; // (1) Debug
+        uint_t nmi         : 1; // (2) Non-maskable interrupt
+        uint_t bp          : 1; // (3) Breakpoint
+        uint_t of          : 1; // (4) Overflow
+        uint_t br          : 1; // (5) Bound-Range
+        uint_t ud          : 1; // (6) Invalid-Opcode
+        uint_t nm          : 1; // (7) Device-not-available
+        uint_t df          : 1; // (8) Double Fault
+        uint_t ex9         : 1; 
+        uint_t ts          : 1; // (10) Invalid TSS
+        uint_t np          : 1; // (11) Segment-not-present
+        uint_t ss          : 1; // (12) Stack
+        uint_t gp          : 1; // (13) General Protection Fault
+        uint_t pf          : 1; // (14) Page fault
+        uint_t ex15        : 1;
+        uint_t mf          : 1; // (15) Floating point exception
+        uint_t ac          : 1; // (16) Alignment-check
+        uint_t mc          : 1; // (17) Machine Check
+        uint_t xf          : 1; // (18) SIMD floating-point
+        uint_t ex20        : 1;
+        uint_t ex21        : 1;
+        uint_t ex22        : 1;
+        uint_t ex23        : 1;
+        uint_t ex24        : 1;
+        uint_t ex25        : 1;
+        uint_t ex26        : 1;
+        uint_t ex27        : 1;
+        uint_t ex28        : 1;
+        uint_t ex29        : 1;
+        uint_t sx          : 1; // (30) Security Exception
+        uint_t ex31        : 1;
+    } __attribute__ ((packed));
+    } __attribute__ ((packed));
+} __attribute__((packed));
+
 
 
 
index 4ac707b..e5fe949 100644 (file)
@@ -33,7 +33,7 @@
 
 // Intel VMX Specific MSRs
 #define VMX_FEATURE_CONTROL_MSR     0x0000003a
-#define VMX_BASIC_MSR          0x00000480
+#define VMX_BASIC_MSR               0x00000480
 #define VMX_PINBASED_CTLS_MSR       0x00000481
 #define VMX_PROCBASED_CTLS_MSR      0x00000482
 #define VMX_EXIT_CTLS_MSR           0x00000483
@@ -120,7 +120,6 @@ struct vmx_data {
     uint32_t sec_procbased_ctrls;
     uint32_t exit_ctrls;
     uint32_t entry_ctrls;
-    uint32_t excp_bitmap;
 };
 
 
@@ -140,6 +139,9 @@ struct Instruction {
 
 int v3_is_vmx_capable();
 void v3_init_vmx(struct v3_ctrl_ops* vm_ops);
+int v3_update_vmcs_guest_state(struct guest_info * info);
+int v3_update_vmcs_ctrl_fields(struct guest_info * info);
+int v3_update_vmcs_host_state(struct guest_info * info);
 
 
 
index 956136e..7525edb 100644 (file)
@@ -80,6 +80,57 @@ typedef enum {
     VMEXIT_XSETBV                           = 55
 } vmx_exit_t;
 
+/* VMCS Exit QUALIFICATIONs */
+struct vmexit_io_qual {
+    uint32_t access_size : 3; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
+    uint32_t dir        : 1; // (0: Out ;; 1: In)
+    uint32_t string     : 1; // (0: not string ;; 1: string)
+    uint32_t REP        : 1; // (0: not REP ;; 1: REP)
+    uint32_t op_enc      : 1; // (0: DX ;; 1: immediate)
+    uint32_t rsvd       : 9; // Set to 0
+    uint32_t port       : 16; // IO Port Number
+} __attribute__((packed));
+
+
+
+struct VMExitDBGQual {
+    uint32_t B0         : 1; // Breakpoint 0 condition met
+    uint32_t B1         : 1; // Breakpoint 1 condition met
+    uint32_t B2         : 1; // Breakpoint 2 condition met
+    uint32_t B3         : 1; // Breakpoint 3 condition met
+    uint32_t rsvd       : 9; // reserved to 0
+    uint32_t BD         : 1; // detected DBG reg access
+    uint32_t BS         : 1; // cause either single instr or taken branch
+} __attribute__((packed));
+
+
+struct VMExitTSQual {
+    uint32_t selector   : 16; // selector of destination TSS 
+    uint32_t rsvd       : 14; // reserved to 0
+    uint32_t src        : 2; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
+} __attribute__((packed));
+
+struct vmexit_cr_qual {
+    uint32_t cr_id       : 4; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
+    uint32_t access_type : 2; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
+    uint32_t lmsw_op_type : 1; // (0: register ; 1: memory)
+    uint32_t rsvd1      : 1; // reserved to 0
+    uint32_t gpr        : 4; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
+    uint32_t rsvd2      : 4; // reserved to 0
+    uint32_t lmsw_src    : 16; // src data for lmsw
+} __attribute__((packed));
+
+struct VMExitMovDRQual {
+    uint32_t regID      : 3; // debug register number
+    uint32_t rsvd1      : 1; // reserved to 0
+    uint32_t dir        : 1; // (0: MOV to DR , 1: MOV from DR)
+    uint32_t rsvd2      : 3; // reserved to 0
+    uint32_t gpr        : 4; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
+} __attribute__((packed));
+
+/* End Exit Qualifications */
+
+
 int v3_handle_vmx_exit(struct v3_gprs * gprs, struct guest_info * info);
 
 #endif
index 1d47e73..8019f82 100644 (file)
@@ -416,56 +416,56 @@ static int write_master_port1(ushort_t port, void * src, uint_t length, struct v
     PrintDebug("8259 PIC: Write master port 1 with 0x%x\n",cw);
 
     if (length != 1) {
-       PrintError("8259 PIC: Invalid Write length (wr_Master1)\n");
-       return -1;
+        PrintError("8259 PIC: Invalid Write length (wr_Master1)\n");
+        return -1;
     }
-  
+
     if (IS_ICW1(cw)) {
 
-       PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Master1)\n", cw);
-    
-       state->master_icw1 = cw;
-       state->master_state = ICW2;
+        PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Master1)\n", cw);
 
-    } else if (state->master_state == READY) {
-       if (IS_OCW2(cw)) {
-           // handle the EOI here
-           struct ocw2 * cw2 =  (struct ocw2*)&cw;
-
-           PrintDebug("8259 PIC: Handling OCW2 = %x (wr_Master1)\n", cw);
-      
-           if ((cw2->EOI) && (!cw2->R) && (cw2->SL)) {
-               // specific EOI;
-               state->master_isr &= ~(0x01 << cw2->level);
-           } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) {
-               int i;
-               // Non-specific EOI
-               PrintDebug("8259 PIC: Pre ISR = %x (wr_Master1)\n", state->master_isr);
-               for (i = 0; i < 8; i++) {
-                   if (state->master_isr & (0x01 << i)) {
-                       state->master_isr &= ~(0x01 << i);
-                       break;
-                   }
-               }       
-               PrintDebug("8259 PIC: Post ISR = %x (wr_Master1)\n", state->master_isr);
-           } else {
-               PrintError("8259 PIC: Command not handled, or in error (wr_Master1)\n");
-               return -1;
-           }
+        state->master_icw1 = cw;
+        state->master_state = ICW2;
 
-           state->master_ocw2 = cw;
-       } else if (IS_OCW3(cw)) {
-           PrintDebug("8259 PIC: Handling OCW3 = %x (wr_Master1)\n", cw);
-           state->master_ocw3 = cw;
-       } else {
-           PrintError("8259 PIC: Invalid OCW to PIC (wr_Master1)\n");
-           PrintError("8259 PIC: CW=%x\n", cw);
-           return -1;
-       }
+    } else if (state->master_state == READY) {
+        if (IS_OCW2(cw)) {
+            // handle the EOI here
+            struct ocw2 * cw2 =  (struct ocw2*)&cw;
+
+            PrintDebug("8259 PIC: Handling OCW2 = %x (wr_Master1)\n", cw);
+
+            if ((cw2->EOI) && (!cw2->R) && (cw2->SL)) {
+                // specific EOI;
+                state->master_isr &= ~(0x01 << cw2->level);
+            } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) {
+                int i;
+                // Non-specific EOI
+                PrintDebug("8259 PIC: Pre ISR = %x (wr_Master1)\n", state->master_isr);
+                for (i = 0; i < 8; i++) {
+                    if (state->master_isr & (0x01 << i)) {
+                        state->master_isr &= ~(0x01 << i);
+                        break;
+                    }
+                }      
+                PrintDebug("8259 PIC: Post ISR = %x (wr_Master1)\n", state->master_isr);
+            } else {
+                PrintError("8259 PIC: Command not handled, or in error (wr_Master1)\n");
+                return -1;
+            }
+
+            state->master_ocw2 = cw;
+        } else if (IS_OCW3(cw)) {
+            PrintDebug("8259 PIC: Handling OCW3 = %x (wr_Master1)\n", cw);
+            state->master_ocw3 = cw;
+        } else {
+            PrintError("8259 PIC: Invalid OCW to PIC (wr_Master1)\n");
+            PrintError("8259 PIC: CW=%x\n", cw);
+            return -1;
+        }
     } else {
-       PrintError("8259 PIC: Invalid PIC State (wr_Master1)\n");
-       PrintError("8259 PIC: CW=%x\n", cw);
-       return -1;
+        PrintError("8259 PIC: Invalid PIC State (wr_Master1)\n");
+        PrintError("8259 PIC: CW=%x\n", cw);
+        return -1;
     }
 
     return 1;
@@ -476,50 +476,51 @@ static int write_master_port2(ushort_t port, void * src, uint_t length, struct v
     uchar_t cw = *(uchar_t *)src;    
 
     PrintDebug("8259 PIC: Write master port 2 with 0x%x\n",cw);
-  
+
     if (length != 1) {
-       PrintError("8259 PIC: Invalid Write length (wr_Master2)\n");
-       return -1;
+        PrintError("8259 PIC: Invalid Write length (wr_Master2)\n");
+        return -1;
     }
-    
+
     if (state->master_state == ICW2) {
-       struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
+        struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
 
-       PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Master2)\n", cw);
-       state->master_icw2 = cw;
+        PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Master2)\n", cw);
+        state->master_icw2 = cw;
 
-       if (cw1->sngl == 0) {
-           state->master_state = ICW3;
-       } else if (cw1->ic4 == 1) {
-           state->master_state = ICW4;
-       } else {
-           state->master_state = READY;
-       }
+        if (cw1->sngl == 0) {
+            state->master_state = ICW3;
+        } else if (cw1->ic4 == 1) {
+            state->master_state = ICW4;
+        } else {
+            state->master_state = READY;
+        }
 
     } else if (state->master_state == ICW3) {
-       struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
+        struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1);
 
-       PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Master2)\n", cw);
+        PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Master2)\n", cw);
 
-       state->master_icw3 = cw;
+        state->master_icw3 = cw;
 
-       if (cw1->ic4 == 1) {
-           state->master_state = ICW4;
-       } else {
-           state->master_state = READY;
-       }
+        if (cw1->ic4 == 1) {
+            state->master_state = ICW4;
+        } else {
+            state->master_state = READY;
+        }
 
     } else if (state->master_state == ICW4) {
-       PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Master2)\n", cw);
-       state->master_icw4 = cw;
-       state->master_state = READY;
-    } else if (state->master_state == READY) {
-       PrintDebug("8259 PIC: Setting IMR = %x (wr_Master2)\n", cw);
-       state->master_imr = cw;
+        PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Master2)\n", cw);
+        state->master_icw4 = cw;
+        state->master_state = READY;
+    } else if ((state->master_state == ICW1) || (state->master_state == READY)) {
+        PrintDebug("8259 PIC: Setting IMR = %x (wr_Master2)\n", cw);
+        state->master_imr = cw;
     } else {
-       // error
-       PrintError("8259 PIC: Invalid master PIC State (wr_Master2)\n");
-       return -1;
+        // error
+        PrintError("8259 PIC: Invalid master PIC State (wr_Master2) (state=%d)\n", 
+                state->master_state);
+        return -1;
     }
 
     return 1;
@@ -591,48 +592,48 @@ static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm
     PrintDebug("8259 PIC: Write slave port 2 with 0x%x\n",cw);
 
     if (length != 1) {
-       PrintError("8259 PIC: Invalid write length (wr_Slave2)\n");
-       return -1;
+        PrintError("8259 PIC: Invalid write length (wr_Slave2)\n");
+        return -1;
     }
 
     if (state->slave_state == ICW2) {
-       struct icw1 * cw1 =  (struct icw1 *)&(state->master_icw1);
+        struct icw1 * cw1 =  (struct icw1 *)&(state->master_icw1);
 
-       PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Slave2)\n", cw);
+        PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Slave2)\n", cw);
 
-       state->slave_icw2 = cw;
+        state->slave_icw2 = cw;
 
-       if (cw1->sngl == 0) {
-           state->slave_state = ICW3;
-       } else if (cw1->ic4 == 1) {
-           state->slave_state = ICW4;
-       } else {
-           state->slave_state = READY;
-       }
+        if (cw1->sngl == 0) {
+            state->slave_state = ICW3;
+        } else if (cw1->ic4 == 1) {
+            state->slave_state = ICW4;
+        } else {
+            state->slave_state = READY;
+        }
 
     } else if (state->slave_state == ICW3) {
-       struct icw1 * cw1 =  (struct icw1 *)&(state->master_icw1);
+        struct icw1 * cw1 =  (struct icw1 *)&(state->master_icw1);
 
-       PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Slave2)\n", cw);
+        PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Slave2)\n", cw);
 
-       state->slave_icw3 = cw;
+        state->slave_icw3 = cw;
 
-       if (cw1->ic4 == 1) {
-           state->slave_state = ICW4;
-       } else {
-           state->slave_state = READY;
-       }
+        if (cw1->ic4 == 1) {
+            state->slave_state = ICW4;
+        } else {
+            state->slave_state = READY;
+        }
 
     } else if (state->slave_state == ICW4) {
-       PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Slave2)\n", cw);
-       state->slave_icw4 = cw;
-       state->slave_state = READY;
-    } else if (state->slave_state == READY) {
-       PrintDebug("8259 PIC: Setting IMR = %x (wr_Slave2)\n", cw);
-       state->slave_imr = cw;
+        PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Slave2)\n", cw);
+        state->slave_icw4 = cw;
+        state->slave_state = READY;
+    } else if ((state->slave_state == ICW1) || (state->slave_state == READY)) {
+        PrintDebug("8259 PIC: Setting IMR = %x (wr_Slave2)\n", cw);
+        state->slave_imr = cw;
     } else {
-       PrintError("8259 PIC: Invalid State at write (wr_Slave2)\n");
-       return -1;
+        PrintError("8259 PIC: Invalid State at write (wr_Slave2)\n");
+        return -1;
     }
 
     return 1;
index 9a1ed31..ed3fe92 100644 (file)
@@ -25,8 +25,8 @@
 #include <palacios/vmm.h>
 #include <palacios/vmx_lowlevel.h>
 #include <palacios/vmm_lowlevel.h>
-#include <palacios/vmm_config.h>
 #include <palacios/vmm_ctrl_regs.h>
+#include <palacios/vmm_config.h>
 #include <palacios/vm_guest_mem.h>
 #include <palacios/vmm_direct_paging.h>
 #include <palacios/vmx_io.h>
@@ -62,7 +62,7 @@ static void inline translate_segment_access(struct v3_segment * v3_seg,
     access->granularity = v3_seg->granularity;
 }
 
-static int update_vmcs_ctrl_fields(struct guest_info * info) {
+int v3_update_vmcs_ctrl_fields(struct guest_info * info) {
     int vmx_ret = 0;
     struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data);
 
@@ -75,12 +75,11 @@ static int update_vmcs_ctrl_fields(struct guest_info * info) {
 
     vmx_ret |= check_vmcs_write(VMCS_EXIT_CTRLS, arch_data->exit_ctrls);
     vmx_ret |= check_vmcs_write(VMCS_ENTRY_CTRLS, arch_data->entry_ctrls);
-    vmx_ret |= check_vmcs_write(VMCS_EXCP_BITMAP, arch_data->excp_bitmap);
 
     return vmx_ret;
 }
 
-static int update_vmcs_host_state(struct guest_info * info) {
+int v3_update_vmcs_host_state(struct guest_info * info) {
     int vmx_ret = 0;
     addr_t tmp;
     struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data);
@@ -184,9 +183,8 @@ static int update_vmcs_host_state(struct guest_info * info) {
 }
 
 
-static int inline update_vmcs_guest_state(struct guest_info * info)
+int v3_update_vmcs_guest_state(struct guest_info * info)
 {
-    struct v3_msr tmp_msr;
     int vmx_ret = 0;
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_RIP, info->rip);
@@ -198,14 +196,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
     vmx_ret |= check_vmcs_write(VMCS_GUEST_CR4, info->ctrl_regs.cr4);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_RFLAGS, info->ctrl_regs.rflags);
-#define DEBUGCTL_MSR 0x1d9
-
-    v3_get_msr(DEBUGCTL_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
-    vmx_ret |= check_vmcs_write(VMCS_GUEST_DBG_CTL, tmp_msr.value);
-
-    vmx_ret |= check_vmcs_write(VMCS_GUEST_DR7, 0x400);
 
-    vmx_ret |= check_vmcs_write(VMCS_LINK_PTR, 0xffffffffffffffff);
 
 
     /*** Write VMCS Segments ***/
@@ -222,6 +213,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
     vmx_ret |= check_vmcs_write(VMCS_GUEST_CS_ACCESS, access.value);
 
     /* SS Segment */
+    memset(&access, 0, sizeof(access));
     translate_segment_access(&(info->segments.ss), &access);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_SS_BASE, info->segments.ss.base);
@@ -230,6 +222,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
     vmx_ret |= check_vmcs_write(VMCS_GUEST_SS_ACCESS, access.value);
 
     /* DS Segment */
+    memset(&access, 0, sizeof(access));
     translate_segment_access(&(info->segments.ds), &access);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_DS_BASE, info->segments.ds.base);
@@ -239,6 +232,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
 
 
     /* ES Segment */
+    memset(&access, 0, sizeof(access));
     translate_segment_access(&(info->segments.es), &access);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_ES_BASE, info->segments.es.base);
@@ -247,6 +241,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
     vmx_ret |= check_vmcs_write(VMCS_GUEST_ES_ACCESS, access.value);
 
     /* FS Segment */
+    memset(&access, 0, sizeof(access));
     translate_segment_access(&(info->segments.fs), &access);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_FS_BASE, info->segments.fs.base);
@@ -255,6 +250,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
     vmx_ret |= check_vmcs_write(VMCS_GUEST_FS_ACCESS, access.value);
 
     /* GS Segment */
+    memset(&access, 0, sizeof(access));
     translate_segment_access(&(info->segments.gs), &access);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_GS_BASE, info->segments.gs.base);
@@ -263,6 +259,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
     vmx_ret |= check_vmcs_write(VMCS_GUEST_GS_ACCESS, access.value);
 
     /* LDTR segment */
+    memset(&access, 0, sizeof(access));
     translate_segment_access(&(info->segments.ldtr), &access);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_LDTR_BASE, info->segments.ldtr.base);
@@ -271,6 +268,7 @@ static int inline update_vmcs_guest_state(struct guest_info * info)
     vmx_ret |= check_vmcs_write(VMCS_GUEST_LDTR_ACCESS, access.value);
 
     /* TR Segment */
+    memset(&access, 0, sizeof(access));
     translate_segment_access(&(info->segments.tr), &access);
 
     vmx_ret |= check_vmcs_write(VMCS_GUEST_TR_BASE, info->segments.tr.base);
@@ -358,59 +356,7 @@ static addr_t allocate_vmcs()
 }
 
 #if 0
-static void setup_v8086_mode_for_boot(struct guest_info * vm_info)
-{
 
-    ((struct vmx_data *)vm_info->vmm_data)->state = VMXASSIST_V8086_BIOS;
-    struct rflags * flags = (struct rflags *)&(vm_info->ctrl_regs.rflags);
-    flags->rsvd1 = 1;
-    flags->vm = 1;
-    flags->iopl = 3;
-
-#define GUEST_CR0_MASK 0x80000021
-#define GUEST_CR4_MASK 0x00002000
-    vm_info->ctrl_regs.cr0 = GUEST_CR0_MASK;
-    vm_info->ctrl_regs.cr4 = GUEST_CR4_MASK;
-   
-    vm_info->rip = 0xd0000;
-    vm_info->vm_regs.rsp = 0x80000;
-
-    vm_info->segments.cs.selector = 0xf000;
-    vm_info->segments.cs.base = 0xf000 << 4;
-    vm_info->segments.cs.limit = 0xffff;
-    vm_info->segments.cs.type = 3;
-    vm_info->segments.cs.system = 1;
-    vm_info->segments.cs.dpl = 3;
-    vm_info->segments.cs.present = 1;
-    vm_info->segments.cs.granularity = 0;
-
-    int i = 0;
-    struct v3_segment * seg_ptr = (struct v3_segment *)&(vm_info->segments);
-
-    /* Set values for selectors ds through ss */
-    for(i = 1; i < 6 ; i++) {
-        seg_ptr[i].selector = 0x0000;
-        seg_ptr[i].base = 0x00000;
-        seg_ptr[i].limit = 0xffff;
-           }
-
-    for(i = 6; i < 10; i++) {
-        seg_ptr[i].base = 0x0;
-        seg_ptr[i].limit = 0xffff;
-    }
-
-    vm_info->segments.ldtr.selector = 0x0;
-    vm_info->segments.ldtr.type = 2;
-    vm_info->segments.ldtr.system = 0;
-    vm_info->segments.ldtr.present = 1;
-    vm_info->segments.ldtr.granularity = 0;
-
-    vm_info->segments.tr.selector = 0x0;
-    vm_info->segments.tr.type = 3;
-    vm_info->segments.tr.system = 0;
-    vm_info->segments.tr.present = 1;
-    vm_info->segments.tr.granularity = 0;
-}
 #endif
 
 #if 0
@@ -556,13 +502,14 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config
     vmx_data->pri_procbased_ctrls = tmp_msr.lo;
 
     v3_get_msr(VMX_EXIT_CTLS_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
-    vmx_data->exit_ctrls = tmp_msr.lo | HOST_ADDR_SPACE_SIZE;
+    vmx_data->exit_ctrls = tmp_msr.lo ;
 
     v3_get_msr(VMX_ENTRY_CTLS_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
     vmx_data->entry_ctrls = tmp_msr.lo;
 
-    vmx_data->excp_bitmap = 0xffffffff;
-
+    struct vmx_exception_bitmap excp_bmap;
+    excp_bmap.value = 0xffffffff;
+    vmx_ret |= check_vmcs_write(VMCS_EXCP_BITMAP, excp_bmap.value);
 
 
     /******* Setup VMXAssist guest state ***********/
@@ -594,19 +541,23 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config
             return -1;
         }
 
-        info->shdw_pg_state.guest_cr0 = 0x10LL;
+        info->shdw_pg_state.guest_cr0 = CR0_PE;
         PrintDebug("Created\n");
 
-        vmx_ret |= check_vmcs_write(VMCS_CR0_MASK, 0xffffffffffffffffLL);
-        vmx_ret |= check_vmcs_write(VMCS_CR4_MASK, 0xffffffffffffffffLL);
+        vmx_ret |= check_vmcs_write(VMCS_CR0_MASK, (CR0_PE | CR0_PG) );
+        vmx_ret |= check_vmcs_write(VMCS_CR0_READ_SHDW, info->shdw_pg_state.guest_cr0);
+        vmx_ret |= check_vmcs_write(VMCS_CR4_MASK, CR4_VMXE);
 
         info->ctrl_regs.cr3 = info->direct_map_pt;
 
+        // vmx_data->pinbased_ctrls |= NMI_EXIT;
+
         /* Add unconditional I/O and CR exits */
-        vmx_data->pri_procbased_ctrls |= UNCOND_IO_EXIT  |
-                                         CR3_LOAD_EXIT   |
-                                         CR3_STORE_EXIT;  
+        vmx_data->pri_procbased_ctrls |= UNCOND_IO_EXIT  
+                                        | CR3_LOAD_EXIT  
+                                        | CR3_STORE_EXIT;
  
+        vmx_data->exit_ctrls |= HOST_ADDR_SPACE_SIZE;
     }
 
     struct v3_segment * seg_reg = (struct v3_segment *)&(info->segments);
@@ -647,7 +598,7 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config
     uint64_t  gdt[] __attribute__ ((aligned(32))) = {
         0x0000000000000000ULL,         /* 0x00: reserved */
         0x0000830000000000ULL,         /* 0x08: 32-bit TSS */
-        //     0x0000890000000000ULL,          /* 0x08: 32-bit TSS */
+       //0x0000890000000000ULL,                /* 0x08: 32-bit TSS */
         0x00CF9b000000FFFFULL,         /* 0x10: CS 32-bit */
         0x00CF93000000FFFFULL,         /* 0x18: DS 32-bit */
         0x000082000000FFFFULL,         /* 0x20: LDTR 32-bit */
@@ -674,7 +625,7 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config
     info->segments.tr.selector = 0x08;
     info->segments.tr.base = vmxassist_tss;
 
-    // info->segments.tr.type = 0x9; 
+    //info->segments.tr.type = 0x9; 
     info->segments.tr.type = 0x3;
     info->segments.tr.system = 0;
     info->segments.tr.present = 1;
@@ -693,24 +644,34 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config
     memcpy((void*)vmxassist_dst, v3_vmxassist_start, v3_vmxassist_end - v3_vmxassist_start);
     
     /*** Write all the info to the VMCS ***/
-    if(update_vmcs_ctrl_fields(info)) {
+
+#define DEBUGCTL_MSR 0x1d9
+    v3_get_msr(DEBUGCTL_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
+    vmx_ret |= check_vmcs_write(VMCS_GUEST_DBG_CTL, tmp_msr.value);
+
+    vmx_ret |= check_vmcs_write(VMCS_GUEST_DR7, 0x400);
+
+    vmx_ret |= check_vmcs_write(VMCS_LINK_PTR, 0xffffffffffffffff);
+    
+    if(v3_update_vmcs_ctrl_fields(info)) {
         PrintError("Could not write control fields!\n");
         return -1;
     }
     
-    if(update_vmcs_host_state(info)) {
+    if(v3_update_vmcs_host_state(info)) {
         PrintError("Could not write host state\n");
         return -1;
     }
 
 
-    if(update_vmcs_guest_state(info) != VMX_SUCCESS) {
+    if(v3_update_vmcs_guest_state(info) != VMX_SUCCESS) {
         PrintError("Writing guest state failed!\n");
         return -1;
     }
 
     v3_print_vmcs();
 
+    vmx_data->state = VMXASSIST_STARTUP;
 
     v3_post_config_guest(info, config_ptr);
 
index 2bcc394..d6eebdc 100644 (file)
@@ -23,6 +23,8 @@
 #include <palacios/vmcs.h>
 #include <palacios/vmx_lowlevel.h>
 #include <palacios/vmx_io.h>
+#include <palacios/vmx.h>
+#include <palacios/vmm_ctrl_regs.h>
 
 
 static int inline check_vmcs_write(vmcs_field_t field, addr_t val)
@@ -51,6 +53,237 @@ static int inline check_vmcs_read(vmcs_field_t field, void * val)
     return 0;
 }
 
+static void inline translate_access_to_v3_seg(struct vmcs_segment_access * access, 
+        struct v3_segment * v3_seg)
+{
+    v3_seg->type = access->type;
+    v3_seg->system = access->desc_type;
+    v3_seg->dpl = access->dpl;
+    v3_seg->present = access->present;
+    v3_seg->avail = access->avail;
+    v3_seg->long_mode = access->long_mode;
+    v3_seg->db = access->db;
+    v3_seg->granularity = access->granularity;
+}
+
+static void load_vmcs_guest_state(struct guest_info * info)
+{
+    check_vmcs_read(VMCS_GUEST_RIP, &(info->rip));
+    check_vmcs_read(VMCS_GUEST_RSP, &(info->vm_regs.rsp));
+    check_vmcs_read(VMCS_GUEST_CR0, &(info->ctrl_regs.cr0));
+    check_vmcs_read(VMCS_GUEST_CR3, &(info->ctrl_regs.cr3));
+    check_vmcs_read(VMCS_GUEST_CR4, &(info->ctrl_regs.cr4));
+
+    struct vmcs_segment_access access;
+
+    memset(&access, 0, sizeof(access));
+
+    /* CS Segment */
+    check_vmcs_read(VMCS_GUEST_CS_BASE, &(info->segments.cs.base));
+    check_vmcs_read(VMCS_GUEST_CS_SELECTOR, &(info->segments.cs.selector));
+    check_vmcs_read(VMCS_GUEST_CS_LIMIT, &(info->segments.cs.limit));
+    check_vmcs_read(VMCS_GUEST_CS_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.cs));
+
+    /* SS Segment */
+    check_vmcs_read(VMCS_GUEST_SS_BASE, &(info->segments.ss.base));
+    check_vmcs_read(VMCS_GUEST_SS_SELECTOR, &(info->segments.ss.selector));
+    check_vmcs_read(VMCS_GUEST_SS_LIMIT, &(info->segments.ss.limit));
+    check_vmcs_read(VMCS_GUEST_SS_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.ss));
+
+    /* DS Segment */
+    check_vmcs_read(VMCS_GUEST_DS_BASE, &(info->segments.ds.base));
+    check_vmcs_read(VMCS_GUEST_DS_SELECTOR, &(info->segments.ds.selector));
+    check_vmcs_read(VMCS_GUEST_DS_LIMIT, &(info->segments.ds.limit));
+    check_vmcs_read(VMCS_GUEST_DS_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.ds));
+
+    /* ES Segment */
+    check_vmcs_read(VMCS_GUEST_ES_BASE, &(info->segments.es.base));
+    check_vmcs_read(VMCS_GUEST_ES_SELECTOR, &(info->segments.es.selector));
+    check_vmcs_read(VMCS_GUEST_ES_LIMIT, &(info->segments.es.limit));
+    check_vmcs_read(VMCS_GUEST_ES_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.es));
+
+    /* FS Segment */
+    check_vmcs_read(VMCS_GUEST_FS_BASE, &(info->segments.fs.base));
+    check_vmcs_read(VMCS_GUEST_FS_SELECTOR, &(info->segments.fs.selector));
+    check_vmcs_read(VMCS_GUEST_FS_LIMIT, &(info->segments.fs.limit));
+    check_vmcs_read(VMCS_GUEST_FS_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.fs));
+
+
+    /* GS Segment */
+    check_vmcs_read(VMCS_GUEST_GS_BASE, &(info->segments.gs.base));
+    check_vmcs_read(VMCS_GUEST_GS_SELECTOR, &(info->segments.gs.selector));
+    check_vmcs_read(VMCS_GUEST_GS_LIMIT, &(info->segments.gs.limit));
+    check_vmcs_read(VMCS_GUEST_GS_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.gs));
+
+    /* LDTR Segment */
+    check_vmcs_read(VMCS_GUEST_LDTR_BASE, &(info->segments.ldtr.base));
+    check_vmcs_read(VMCS_GUEST_LDTR_SELECTOR, &(info->segments.ldtr.selector));
+    check_vmcs_read(VMCS_GUEST_LDTR_LIMIT, &(info->segments.ldtr.limit));
+    check_vmcs_read(VMCS_GUEST_LDTR_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.ldtr));
+
+    /* TR Segment */
+    check_vmcs_read(VMCS_GUEST_TR_BASE, &(info->segments.tr.base));
+    check_vmcs_read(VMCS_GUEST_TR_SELECTOR, &(info->segments.tr.selector));
+    check_vmcs_read(VMCS_GUEST_TR_LIMIT, &(info->segments.tr.limit));
+    check_vmcs_read(VMCS_GUEST_TR_ACCESS, &(access.value));
+
+    translate_access_to_v3_seg(&access, &(info->segments.tr));
+
+    /* GDTR Segment */
+    check_vmcs_read(VMCS_GUEST_GDTR_BASE, &(info->segments.gdtr.base));
+    check_vmcs_read(VMCS_GUEST_GDTR_LIMIT, &(info->segments.gdtr.limit));
+    
+    /* IDTR Segment */
+    check_vmcs_read(VMCS_GUEST_IDTR_BASE, &(info->segments.idtr.base));
+    check_vmcs_read(VMCS_GUEST_IDTR_LIMIT, &(info->segments.idtr.limit));
+}
+
+
+static void setup_v8086_mode_for_boot(struct guest_info * info)
+{
+
+    ((struct vmx_data *)info->vmm_data)->state = VMXASSIST_V8086_BIOS;
+    struct rflags * flags = (struct rflags *)&(info->ctrl_regs.rflags);
+    flags->rsvd1 = 1;
+    flags->vm = 1;
+    flags->iopl = 3;
+
+    info->rip = 0xfff0;
+    //info->vm_regs.rsp = 0x0;
+   
+    /* Zero the segment registers */
+    memset(&(info->segments), 0, sizeof(struct v3_segment)*6);
+
+
+    info->segments.cs.selector = 0xf000;
+    info->segments.cs.base = 0xf000 << 4;
+    info->segments.cs.limit = 0xffff;
+    info->segments.cs.type = 3;
+    info->segments.cs.system = 1;
+    info->segments.cs.dpl = 3;
+    info->segments.cs.present = 1;
+    info->segments.cs.granularity = 0;
+
+    int i;
+    
+    /* Set values for selectors ds through ss */
+    struct v3_segment * seg_ptr = (struct v3_segment *)&(info->segments);
+    for(i = 1; i < 6 ; i++) {
+        seg_ptr[i].selector = 0x0000;
+        seg_ptr[i].base = 0x00000;
+        seg_ptr[i].limit = 0xffff;
+        seg_ptr[i].type = 3;
+        seg_ptr[i].system = 1;
+        seg_ptr[i].dpl = 3;
+        seg_ptr[i].present = 1;
+        seg_ptr[i].granularity = 0;
+    }
+
+    PrintDebug("END INFO!\n");
+#if 0
+    for(i = 6; i < 10; i++) {
+        seg_ptr[i].base = 0x0;
+        seg_ptr[i].limit = 0xffff;
+    }
+
+    info->segments.ldtr.type = 2;
+    info->segments.ldtr.system = 0;
+    info->segments.ldtr.present = 1;
+    info->segments.ldtr.granularity = 0;
+
+    info->segments.tr.type = 3;
+    info->segments.tr.system = 0;
+    info->segments.tr.present = 1;
+    info->segments.tr.granularity = 0;
+#endif
+}
+
+static int inline handle_cr_access(struct guest_info * info, ulong_t exit_qual)
+{
+    struct vmexit_cr_qual * cr_qual = (struct vmexit_cr_qual *)&exit_qual;
+
+    if(cr_qual->access_type < 2) {
+        ulong_t reg = 0;
+        switch(cr_qual->gpr) {
+            case 0:
+                reg = info->vm_regs.rax;
+                break;
+            case 1:
+                reg = info->vm_regs.rcx;
+                break;
+            case 2:
+                reg = info->vm_regs.rdx;
+                break;
+            case 3:
+                reg = info->vm_regs.rbx;
+                break;
+            case 4:
+                reg = info->vm_regs.rsp;
+                break;
+            case 5:
+                reg = info->vm_regs.rbp;
+                break;
+            case 6:
+                reg = info->vm_regs.rsi;
+                break;
+            case 7:
+                reg = info->vm_regs.rdi;
+                break;
+            case 8:
+                reg = info->vm_regs.r8;
+                break;
+            case 9:
+                reg = info->vm_regs.r9;
+                break;
+            case 10:
+                reg = info->vm_regs.r10;
+                break;
+            case 11:
+                reg = info->vm_regs.r11;
+                break;
+            case 12:
+                reg = info->vm_regs.r11;
+                break;
+            case 13:
+                reg = info->vm_regs.r13;
+                break;
+            case 14:
+                reg = info->vm_regs.r14;
+                break;
+            case 15:
+                reg = info->vm_regs.r15;
+                break;
+        }
+        PrintDebug("RAX: %p\n", (void *)info->vm_regs.rax);
+
+        if(cr_qual->cr_id == 0
+                && (~reg & CR0_PE)
+                && ((struct vmx_data*)info->vmm_data)->state == VMXASSIST_STARTUP) {
+            setup_v8086_mode_for_boot(info);
+            info->shdw_pg_state.guest_cr0 = 0x0;
+            v3_update_vmcs_guest_state(info);
+            return 0;
+        }
+    }
+    PrintError("Unhandled CR access\n");
+    return -1;
+}
+
+
 int v3_handle_vmx_exit(struct v3_gprs * gprs, struct guest_info * info)
 {
     uint32_t exit_reason;
@@ -59,17 +292,11 @@ int v3_handle_vmx_exit(struct v3_gprs * gprs, struct guest_info * info)
     check_vmcs_read(VMCS_EXIT_REASON, &exit_reason);
     check_vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
 
-    PrintDebug("VMX Exit taken, id-qual: %d-%ld\n", exit_reason, exit_qual);
+    PrintDebug("VMX Exit taken, id-qual: %u-%lu\n", exit_reason, exit_qual);
 
     /* Update guest state */
-    check_vmcs_read(VMCS_GUEST_RIP, &(info->rip));
-    check_vmcs_read(VMCS_GUEST_RSP, &(info->vm_regs.rsp));
-    check_vmcs_read(VMCS_GUEST_CR0, &(info->ctrl_regs.cr0));
-    check_vmcs_read(VMCS_GUEST_CR3, &(info->ctrl_regs.cr3));
-    check_vmcs_read(VMCS_GUEST_CR4, &(info->ctrl_regs.cr4));
-
-    // read out segments
-
+    load_vmcs_guest_state(info);
+  
     switch(exit_reason)
     {
         case VMEXIT_INFO_EXCEPTION_OR_NMI:
@@ -89,13 +316,17 @@ int v3_handle_vmx_exit(struct v3_gprs * gprs, struct guest_info * info)
                     PrintError("Page fault in unimplemented paging mode\n");
                     return -1;
                 }
+            } else {
+                PrintDebug("Unknown exception: 0x%x\n", (uint8_t)int_info);
+                v3_print_GPRs(info);
+                return -1;
             }
             break;
         }
 
         case VMEXIT_IO_INSTR: 
         {
-            struct vmcs_io_qual * io_qual = (struct vmcs_io_qual *)&exit_qual;
+            struct vmexit_io_qual * io_qual = (struct vmexit_io_qual *)&exit_qual;
 
             if(io_qual->dir == 0) {
                 if(io_qual->string) {
@@ -121,6 +352,11 @@ int v3_handle_vmx_exit(struct v3_gprs * gprs, struct guest_info * info)
             break;
         }
 
+        case VMEXIT_CR_REG_ACCESSES:
+            if(handle_cr_access(info,exit_qual) != 0)
+                return -1;
+            break;
+
         default:
             PrintError("Unhandled VMEXIT\n");
             return -1;
@@ -132,6 +368,7 @@ int v3_handle_vmx_exit(struct v3_gprs * gprs, struct guest_info * info)
     check_vmcs_write(VMCS_GUEST_RIP, info->rip);
     check_vmcs_write(VMCS_GUEST_RSP, info->vm_regs.rsp);
 
-    PrintDebug("Executing VMRESUME\n");
+    check_vmcs_write(VMCS_CR0_READ_SHDW, info->shdw_pg_state.guest_cr0);
+
     return 0;
 }
index bfe1703..2f2596d 100644 (file)
@@ -4,6 +4,7 @@
 #include <palacios/vmcs.h>
 #include <palacios/vmx_lowlevel.h>
 #include <palacios/vmm.h>
+#include <palacios/vmx_handler.h>
 
 /* Same as SVM */
 static int update_map(struct guest_info * info, uint16_t port, int hook_read, int hook_write)
@@ -33,8 +34,39 @@ int v3_init_vmx_io_map(struct guest_info * info)
 
 int v3_handle_vmx_io_in(struct guest_info * info)
 {
-    PrintDebug("IN not implemented\n");
-    return -1;
+    ulong_t exit_qual;
+
+    vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
+
+    struct vmexit_io_qual * io_qual = (struct vmexit_io_qual *)&exit_qual;
+
+    struct v3_io_hook * hook = v3_get_io_hook(info,io_qual->port);
+    int read_size = 0;
+
+    if(hook == NULL) {
+        PrintError("Hook not present for IN on port %x\n", io_qual->port);
+        return -1;
+    }
+
+    read_size = 1<<(io_qual->access_size);
+
+    PrintDebug("IN of %d bytes on port %d (0x%x)\n", read_size, io_qual->port, io_qual->port);
+
+    if(hook->read(io_qual->port, &(info->vm_regs.rax), read_size, hook->priv_data) != read_size) {
+        PrintError("Read failure for IN on port %x\n", io_qual->port);
+        return -1;
+    }
+
+    uint32_t instr_length = 0;
+
+    if(vmcs_read(VMCS_EXIT_INSTR_LEN, &instr_length) != VMX_SUCCESS) {
+        PrintError("Could not read instruction length\n");
+        return -1;
+    }
+
+    info->rip += instr_length;
+
+    return 0;
 }
 
 int v3_handle_vmx_io_ins(struct guest_info * info)
@@ -49,7 +81,7 @@ int v3_handle_vmx_io_out(struct guest_info * info)
 
     vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
 
-    struct vmcs_io_qual * io_qual = (struct vmcs_io_qual *)&exit_qual;
+    struct vmexit_io_qual * io_qual = (struct vmexit_io_qual *)&exit_qual;
 
     struct v3_io_hook * hook = v3_get_io_hook(info, io_qual->port);
 
@@ -58,18 +90,22 @@ int v3_handle_vmx_io_out(struct guest_info * info)
         return -1;
     }
 
-    int write_size = 1<<(io_qual->accessSize);
+    int write_size = 1<<(io_qual->access_size);
     
     PrintDebug("OUT of %d bytes on port %d (0x%x)\n", write_size, io_qual->port, io_qual->port);
 
+
     if(hook->write(io_qual->port, &(info->vm_regs.rax), write_size, hook->priv_data) != write_size) {
         PrintError("Write failure for out on port %x\n",io_qual->port);
         return -1;
     }
 
-    uint32_t instr_length;
+    uint32_t instr_length = 0;
 
-    vmcs_read(VMCS_EXIT_INSTR_LEN, &instr_length);
+    if(vmcs_read(VMCS_EXIT_INSTR_LEN, &instr_length) != VMX_SUCCESS) {
+        PrintError("Could not read instruction length\n");
+        return -1;
+    } 
 
     info->rip += instr_length;
 
@@ -82,7 +118,7 @@ int v3_handle_vmx_io_outs(struct guest_info * info)
 
     vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
 
-    struct vmcs_io_qual * io_qual = (struct vmcs_io_qual *)&exit_qual;
+    struct vmexit_io_qual * io_qual = (struct vmexit_io_qual *)&exit_qual;
 
     PrintDebug("OUTS on port %d, (0x%x)\n", io_qual->port, io_qual->port);
     return -1;
index f0e793f..12aeb4b 100644 (file)
@@ -21,9 +21,9 @@
        movq    %rdx, 40(%rax);         \
        movq    %rcx, 48(%rax);         \
        pushq   %rbx;                   \
-       movq    16(%rsp), %rbx;         \
+       movq    8(%rsp), %rbx;          \
        movq    %rbx, 56(%rax);         \
-       popq    %rbx;                   \
+       popq    %rbx;                       \
                                        \
        movq    %r8, 64(%rax);          \
        movq    %r9, 72(%rax);          \
        
 
 #define restore_registers(location) \
-       push    %rax;                   \
        mov     location, %rax;         \
        mov     (%rax), %rdi;           \
        mov     8(%rax), %rsi;          \
        mov     16(%rax), %rbp;         \
        mov     32(%rax), %rbx;         \
        mov     40(%rax), %rdx;         \
-       mov     48(%rax), %rcx;         \
+       mov 48(%rax), %rcx;             \
                                        \
        mov     64(%rax), %r8;          \
        mov     72(%rax), %r9;          \
        mov     104(%rax), %r13;        \
        mov     112(%rax), %r14;        \
        mov     120(%rax), %r15;        \
-       pop     %rax;
+    pushq %rbx;              \
+    movq 56(%rax), %rbx;     \
+    movq %rbx, %rax;         \
+    popq %rbx;
+