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.


Additional VMX support. Bootstrapping code added.
Andy Gogke [Wed, 15 Jul 2009 21:32:15 +0000 (16:32 -0500)]
palacios/include/palacios/vmcs.h
palacios/include/palacios/vmx.h
palacios/include/palacios/vmx_lowlevel.h
palacios/src/palacios/vmcs.c
palacios/src/palacios/vmx.c
palacios/src/palacios/vmx_lowlevel.asm

index 9acdc20..392ddc3 100644 (file)
 
 #include <palacios/vmm_types.h>
 
-
-/* 16 bit guest state */
-#define VMCS_GUEST_ES_SELECTOR       0x00000800
-#define VMCS_GUEST_CS_SELECTOR       0x00000802
-#define VMCS_GUEST_SS_SELECTOR       0x00000804
-#define VMCS_GUEST_DS_SELECTOR       0x00000806
-#define VMCS_GUEST_FS_SELECTOR       0x00000808
-#define VMCS_GUEST_GS_SELECTOR       0x0000080A
-#define VMCS_GUEST_LDTR_SELECTOR     0x0000080C
-#define VMCS_GUEST_TR_SELECTOR       0x0000080E
-
-/* 16 bit host state */
-#define VMCS_HOST_ES_SELECTOR        0x00000C00
-#define VMCS_HOST_CS_SELECTOR        0x00000C02
-#define VMCS_HOST_SS_SELECTOR        0x00000C04
-#define VMCS_HOST_DS_SELECTOR        0x00000C06
-#define VMCS_HOST_FS_SELECTOR        0x00000C08
-#define VMCS_HOST_GS_SELECTOR        0x00000C0A
-#define VMCS_HOST_TR_SELECTOR        0x00000C0C
-
-/* 64 bit control fields */
-#define IO_BITMAP_A_ADDR             0x00002000
-#define IO_BITMAP_A_ADDR_HIGH        0x00002001
-#define IO_BITMAP_B_ADDR             0x00002002
-#define IO_BITMAP_B_ADDR_HIGH        0x00002003
-// Only with "Use MSR Bitmaps" enabled
-#define MSR_BITMAPS                  0x00002004
-#define MSR_BITMAPS_HIGH             0x00002005
-//
-#define VM_EXIT_MSR_STORE_ADDR       0x00002006
-#define VM_EXIT_MSR_STORE_ADDR_HIGH  0x00002007
-#define VM_EXIT_MSR_LOAD_ADDR        0x00002008
-#define VM_EXIT_MSR_LOAD_ADDR_HIGH   0x00002009
-#define VM_ENTRY_MSR_LOAD_ADDR       0x0000200A
-#define VM_ENTRY_MSR_LOAD_ADDR_HIGH  0x0000200B
-#define VMCS_EXEC_PTR                0x0000200C
-#define VMCS_EXEC_PTR_HIGH           0x0000200D
-#define TSC_OFFSET                   0x00002010
-#define TSC_OFFSET_HIGH              0x00002011
-// Only with "Use TPR Shadow" enabled
-#define VIRT_APIC_PAGE_ADDR          0x00002012  
-#define VIRT_APIC_PAGE_ADDR_HIGH     0x00002013
-//
-
-
-/* 64 bit guest state fields */
-#define VMCS_LINK_PTR                0x00002800
-#define VMCS_LINK_PTR_HIGH           0x00002801
-#define GUEST_IA32_DEBUGCTL          0x00002802
-#define GUEST_IA32_DEBUGCTL_HIGH     0x00002803
-#define GUEST_IA32_PERF_GLOBAL_CTRL  0x00002808
-#define GUEST_IA32_PERF_GLOBAL_CTRL_HIGH 0x00002809
-
-/* 32 bit control fields */
-#define PIN_VM_EXEC_CTRLS            0x00004000
-#define PROC_VM_EXEC_CTRLS           0x00004002
-#define EXCEPTION_BITMAP             0x00004004
-#define PAGE_FAULT_ERROR_MASK        0x00004006
-#define PAGE_FAULT_ERROR_MATCH       0x00004008
-#define CR3_TARGET_COUNT             0x0000400A
-#define VM_EXIT_CTRLS                0x0000400C
-#define VM_EXIT_MSR_STORE_COUNT      0x0000400E
-#define VM_EXIT_MSR_LOAD_COUNT       0x00004010
-#define VM_ENTRY_CTRLS               0x00004012
-#define VM_ENTRY_MSR_LOAD_COUNT      0x00004014
-#define VM_ENTRY_INT_INFO_FIELD      0x00004016
-#define VM_ENTRY_EXCEPTION_ERROR     0x00004018
-#define VM_ENTRY_INSTR_LENGTH        0x0000401A
-// Only with "Use TPR Shadow" Enabled
-#define TPR_THRESHOLD                0x0000401C
-//
-
-
-
-
-/* 32 bit Read Only data fields */
-#define VM_INSTR_ERROR               0x00004400
-#define EXIT_REASON                  0x00004402
-#define VM_EXIT_INT_INFO             0x00004404
-#define VM_EXIT_INT_ERROR            0x00004406
-#define IDT_VECTOR_INFO              0x00004408
-#define IDT_VECTOR_ERROR             0x0000440A
-#define VM_EXIT_INSTR_LENGTH         0x0000440C
-#define VMX_INSTR_INFO               0x0000440E
-
-/* 32 bit Guest state fields */
-#define GUEST_ES_LIMIT               0x00004800
-#define GUEST_CS_LIMIT               0x00004802
-#define GUEST_SS_LIMIT               0x00004804
-#define GUEST_DS_LIMIT               0x00004806
-#define GUEST_FS_LIMIT               0x00004808
-#define GUEST_GS_LIMIT               0x0000480A
-#define GUEST_LDTR_LIMIT             0x0000480C
-#define GUEST_TR_LIMIT               0x0000480E
-#define GUEST_GDTR_LIMIT             0x00004810
-#define GUEST_IDTR_LIMIT             0x00004812
-#define GUEST_ES_ACCESS              0x00004814
-#define GUEST_CS_ACCESS              0x00004816
-#define GUEST_SS_ACCESS              0x00004818
-#define GUEST_DS_ACCESS              0x0000481A
-#define GUEST_FS_ACCESS              0x0000481C
-#define GUEST_GS_ACCESS              0x0000481E
-#define GUEST_LDTR_ACCESS            0x00004820
-#define GUEST_TR_ACCESS              0x00004822
-#define GUEST_INT_STATE              0x00004824
-#define GUEST_ACTIVITY_STATE         0x00004826
-#define GUEST_SMBASE                 0x00004828
-#define GUEST_IA32_SYSENTER_CS       0x0000482A
-
-
-/* 32 bit host state field */
-#define HOST_IA32_SYSENTER_CS        0x00004C00
-
-/* Natural Width Control Fields */
-#define CR0_GUEST_HOST_MASK          0x00006000
-#define CR4_GUEST_HOST_MASK          0x00006002
-#define CR0_READ_SHADOW              0x00006004
-#define CR4_READ_SHADOW              0x00006006
-#define CR3_TARGET_VALUE_0           0x00006008
-#define CR3_TARGET_VALUE_1           0x0000600A
-#define CR3_TARGET_VALUE_2           0x0000600C
-#define CR3_TARGET_VALUE_3           0x0000600E
-
-
-/* Natural Width Read Only Fields */
-#define EXIT_QUALIFICATION           0x00006400
-#define IO_RCX                       0x00006402
-#define IO_RSI                       0x00006404
-#define IO_RDI                       0x00006406
-#define IO_RIP                       0x00006408
-#define GUEST_LINEAR_ADDR            0x0000640A
-
-/* Natural Width Guest State Fields */
-#define GUEST_CR0                    0x00006800
-#define GUEST_CR3                    0x00006802
-#define GUEST_CR4                    0x00006804
-#define GUEST_ES_BASE                0x00006806
-#define GUEST_CS_BASE                0x00006808
-#define GUEST_SS_BASE                0x0000680A
-#define GUEST_DS_BASE                0x0000680C
-#define GUEST_FS_BASE                0x0000680E
-#define GUEST_GS_BASE                0x00006810
-#define GUEST_LDTR_BASE              0x00006812
-#define GUEST_TR_BASE                0x00006814
-#define GUEST_GDTR_BASE              0x00006816
-#define GUEST_IDTR_BASE              0x00006818
-#define GUEST_DR7                    0x0000681A
-#define GUEST_RSP                    0x0000681C
-#define GUEST_RIP                    0x0000681E
-#define GUEST_RFLAGS                 0x00006820
-#define GUEST_PENDING_DEBUG_EXCS     0x00006822
-#define GUEST_IA32_SYSENTER_ESP      0x00006824
-#define GUEST_IA32_SYSENTER_EIP      0x00006826
-
-
-/* Natural Width Host State Fields */
-#define HOST_CR0                     0x00006C00
-#define HOST_CR3                     0x00006C02
-#define HOST_CR4                     0x00006C04
-#define HOST_FS_BASE                 0x00006C06
-#define HOST_GS_BASE                 0x00006C08
-#define HOST_TR_BASE                 0x00006C0A
-#define HOST_GDTR_BASE               0x00006C0C
-#define HOST_IDTR_BASE               0x00006C0E
-#define HOST_IA32_SYSENTER_ESP       0x00006C10
-#define HOST_IA32_SYSENTER_EIP       0x00006C12
-#define HOST_RSP                     0x00006C14
-#define HOST_RIP                     0x00006C16
-
-/* Pin Based VM Execution Controls */
-/* INTEL MANUAL: 20-10 vol 3B */
-#define EXTERNAL_INTERRUPT_EXITING   0x00000001
-#define NMI_EXITING                  0x00000008
-#define VIRTUAL_NMIS                 0x00000020
-
-
-/* Processor Based VM Execution Controls */
-/* INTEL MANUAL: 20-11 vol. 3B */ 
-#define INTERRUPT_WINDOWS_EXIT       0x00000004
-#define USE_TSC_OFFSETTING           0x00000008
-#define HLT_EXITING                  0x00000080
-#define INVLPG_EXITING               0x00000200
-#define MWAIT_EXITING                0x00000400
-#define RDPMC_EXITING                0x00000800
-#define RDTSC_EXITING                0x00001000
-#define CR8_LOAD_EXITING             0x00080000
-#define CR8_STORE_EXITING            0x00100000
-#define USE_TPR_SHADOW               0x00200000
-#define NMI_WINDOW_EXITING           0x00400000
-#define MOVDR_EXITING                0x00800000
-#define UNCONDITION_IO_EXITING       0x01000000
-#define USE_IO_BITMAPS               0x02000000
-#define USE_MSR_BITMAPS              0x10000000
-#define MONITOR_EXITING              0x20000000
-#define PAUSE_EXITING                0x40000000
-
-/* VM-Exit Controls */
-/* INTEL MANUAL: 20-16 vol. 3B */
-#define HOST_ADDR_SPACE_SIZE         0x00000200
-#define ACK_IRQ_ON_EXIT              0x00008000
-
-
+typedef enum {
+    VMCS_GUEST_ES_SELECTOR       = 0x00000800,
+    VMCS_GUEST_CS_SELECTOR       = 0x00000802,
+    VMCS_GUEST_SS_SELECTOR       = 0x00000804,
+    VMCS_GUEST_DS_SELECTOR       = 0x00000806,
+    VMCS_GUEST_FS_SELECTOR       = 0x00000808,
+    VMCS_GUEST_GS_SELECTOR       = 0x0000080A,
+    VMCS_GUEST_LDTR_SELECTOR     = 0x0000080C,
+    VMCS_GUEST_TR_SELECTOR       = 0x0000080E,
+    /* 16 bit host state */
+    VMCS_HOST_ES_SELECTOR        = 0x00000C00,
+    VMCS_HOST_CS_SELECTOR        = 0x00000C02,
+    VMCS_HOST_SS_SELECTOR        = 0x00000C04,
+    VMCS_HOST_DS_SELECTOR        = 0x00000C06,
+    VMCS_HOST_FS_SELECTOR        = 0x00000C08,
+    VMCS_HOST_GS_SELECTOR        = 0x00000C0A,
+    VMCS_HOST_TR_SELECTOR        = 0x00000C0C,
+    /* 64 bit control fields */
+    IO_BITMAP_A_ADDR             = 0x00002000,
+    IO_BITMAP_A_ADDR_HIGH        = 0x00002001,
+    IO_BITMAP_B_ADDR             = 0x00002002,
+    IO_BITMAP_B_ADDR_HIGH        = 0x00002003,
+    MSR_BITMAPS                  = 0x00002004,
+    MSR_BITMAPS_HIGH             = 0x00002005,
+    VM_EXIT_MSR_STORE_ADDR       = 0x00002006,
+    VM_EXIT_MSR_STORE_ADDR_HIGH  = 0x00002007,
+    VM_EXIT_MSR_LOAD_ADDR        = 0x00002008,
+    VM_EXIT_MSR_LOAD_ADDR_HIGH   = 0x00002009,
+    VM_ENTRY_MSR_LOAD_ADDR       = 0x0000200A,
+    VM_ENTRY_MSR_LOAD_ADDR_HIGH  = 0x0000200B,
+    VMCS_EXEC_PTR                = 0x0000200C,
+    VMCS_EXEC_PTR_HIGH           = 0x0000200D,
+    TSC_OFFSET                   = 0x00002010,
+    TSC_OFFSET_HIGH              = 0x00002011,
+    VIRT_APIC_PAGE_ADDR          = 0x00002012,
+    VIRT_APIC_PAGE_ADDR_HIGH     = 0x00002013,
+    /* 64 bit guest state fields */
+    VMCS_LINK_PTR                = 0x00002800,
+    VMCS_LINK_PTR_HIGH           = 0x00002801,
+    GUEST_IA32_DEBUGCTL          = 0x00002802,
+    GUEST_IA32_DEBUGCTL_HIGH     = 0x00002803,
+    GUEST_IA32_PERF_GLOBAL_CTRL  = 0x00002808,
+    GUEST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002809,
+    /* 32 bit control fields */
+    PIN_VM_EXEC_CTRLS            = 0x00004000,
+    PROC_VM_EXEC_CTRLS           = 0x00004002,
+    EXCEPTION_BITMAP             = 0x00004004,
+    PAGE_FAULT_ERROR_MASK        = 0x00004006,
+    PAGE_FAULT_ERROR_MATCH       = 0x00004008,
+    CR3_TARGET_COUNT             = 0x0000400A,
+    VM_EXIT_CTRLS                = 0x0000400C,
+    VM_EXIT_MSR_STORE_COUNT      = 0x0000400E,
+    VM_EXIT_MSR_LOAD_COUNT       = 0x00004010,
+    VM_ENTRY_CTRLS               = 0x00004012,
+    VM_ENTRY_MSR_LOAD_COUNT      = 0x00004014,
+    VM_ENTRY_INT_INFO_FIELD      = 0x00004016,
+    VM_ENTRY_EXCEPTION_ERROR     = 0x00004018,
+    VM_ENTRY_INSTR_LENGTH        = 0x0000401A,
+    TPR_THRESHOLD                = 0x0000401C,
+    /* 32 bit Read Only data fields */
+    VM_INSTR_ERROR               = 0x00004400,
+    EXIT_REASON                  = 0x00004402,
+    VM_EXIT_INT_INFO             = 0x00004404,
+    VM_EXIT_INT_ERROR            = 0x00004406,
+    IDT_VECTOR_INFO              = 0x00004408,
+    IDT_VECTOR_ERROR             = 0x0000440A,
+    VM_EXIT_INSTR_LENGTH         = 0x0000440C,
+    VMX_INSTR_INFO               = 0x0000440E,
+    /* 32 bit Guest state fields */
+    GUEST_ES_LIMIT               = 0x00004800,
+    GUEST_CS_LIMIT               = 0x00004802,
+    GUEST_SS_LIMIT               = 0x00004804,
+    GUEST_DS_LIMIT               = 0x00004806,
+    GUEST_FS_LIMIT               = 0x00004808,
+    GUEST_GS_LIMIT               = 0x0000480A,
+    GUEST_LDTR_LIMIT             = 0x0000480C,
+    GUEST_TR_LIMIT               = 0x0000480E,
+    GUEST_GDTR_LIMIT             = 0x00004810,
+    GUEST_IDTR_LIMIT             = 0x00004812,
+    GUEST_ES_ACCESS              = 0x00004814,
+    GUEST_CS_ACCESS              = 0x00004816,
+    GUEST_SS_ACCESS              = 0x00004818,
+    GUEST_DS_ACCESS              = 0x0000481A,
+    GUEST_FS_ACCESS              = 0x0000481C,
+    GUEST_GS_ACCESS              = 0x0000481E,
+    GUEST_LDTR_ACCESS            = 0x00004820,
+    GUEST_TR_ACCESS              = 0x00004822,
+    GUEST_INT_STATE              = 0x00004824,
+    GUEST_ACTIVITY_STATE         = 0x00004826,
+    GUEST_SMBASE                 = 0x00004828,
+    GUEST_IA32_SYSENTER_CS       = 0x0000482A,
+    /* 32 bit host state field */
+    HOST_IA32_SYSENTER_CS        = 0x00004C00,
+    /* Natural Width Control Fields */
+    CR0_GUEST_HOST_MASK          = 0x00006000,
+    CR4_GUEST_HOST_MASK          = 0x00006002,
+    CR0_READ_SHADOW              = 0x00006004,
+    CR4_READ_SHADOW              = 0x00006006,
+    CR3_TARGET_VALUE_0           = 0x00006008,
+    CR3_TARGET_VALUE_1           = 0x0000600A,
+    CR3_TARGET_VALUE_2           = 0x0000600C,
+    CR3_TARGET_VALUE_3           = 0x0000600E,
+    /* Natural Width Read Only Fields */
+    EXIT_QUALIFICATION           = 0x00006400,
+    IO_RCX                       = 0x00006402,
+    IO_RSI                       = 0x00006404,
+    IO_RDI                       = 0x00006406,
+    IO_RIP                       = 0x00006408,
+    GUEST_LINEAR_ADDR            = 0x0000640A,
+    /* Natural Width Guest State Fields */
+    GUEST_CR0                    = 0x00006800,
+    GUEST_CR3                    = 0x00006802,
+    GUEST_CR4                    = 0x00006804,
+    GUEST_ES_BASE                = 0x00006806,
+    GUEST_CS_BASE                = 0x00006808,
+    GUEST_SS_BASE                = 0x0000680A,
+    GUEST_DS_BASE                = 0x0000680C,
+    GUEST_FS_BASE                = 0x0000680E,
+    GUEST_GS_BASE                = 0x00006810,
+    GUEST_LDTR_BASE              = 0x00006812,
+    GUEST_TR_BASE                = 0x00006814,
+    GUEST_GDTR_BASE              = 0x00006816,
+    GUEST_IDTR_BASE              = 0x00006818,
+    GUEST_DR7                    = 0x0000681A,
+    GUEST_RSP                    = 0x0000681C,
+    GUEST_RIP                    = 0x0000681E,
+    GUEST_RFLAGS                 = 0x00006820,
+    GUEST_PENDING_DEBUG_EXCS     = 0x00006822,
+    GUEST_IA32_SYSENTER_ESP      = 0x00006824,
+    GUEST_IA32_SYSENTER_EIP      = 0x00006826,
+    /* Natural Width Host State Fields */
+    HOST_CR0                     = 0x00006C00,
+    HOST_CR3                     = 0x00006C02,
+    HOST_CR4                     = 0x00006C04,
+    HOST_FS_BASE                 = 0x00006C06,
+    HOST_GS_BASE                 = 0x00006C08,
+    HOST_TR_BASE                 = 0x00006C0A,
+    HOST_GDTR_BASE               = 0x00006C0C,
+    HOST_IDTR_BASE               = 0x00006C0E,
+    HOST_IA32_SYSENTER_ESP       = 0x00006C10,
+    HOST_IA32_SYSENTER_EIP       = 0x00006C12,
+    HOST_RSP                     = 0x00006C14,
+    HOST_RIP                     = 0x00006C16,
+    /* Pin Based VM Execution Controls */
+    /* INTEL MANUAL: 20-10 vol 3B */
+    EXTERNAL_INTERRUPT_EXITING   = 0x00000001,
+    NMI_EXITING                  = 0x00000008,
+    VIRTUAL_NMIS                 = 0x00000020,
+    /* Processor Based VM Execution Controls */
+    /* INTEL MANUAL: 20-11 vol. 3B */
+    INTERRUPT_WINDOWS_EXIT       = 0x00000004,
+    USE_TSC_OFFSETTING           = 0x00000008,
+    HLT_EXITING                  = 0x00000080,
+    INVLPG_EXITING               = 0x00000200,
+    MWAIT_EXITING                = 0x00000400,
+    RDPMC_EXITING                = 0x00000800,
+    RDTSC_EXITING                = 0x00001000,
+    CR8_LOAD_EXITING             = 0x00080000,
+    CR8_STORE_EXITING            = 0x00100000,
+    USE_TPR_SHADOW               = 0x00200000,
+    NMI_WINDOW_EXITING           = 0x00400000,
+    MOVDR_EXITING                = 0x00800000,
+    UNCONDITION_IO_EXITING       = 0x01000000,
+    USE_IO_BITMAPS               = 0x02000000,
+    USE_MSR_BITMAPS              = 0x10000000,
+    MONITOR_EXITING              = 0x20000000,
+    PAUSE_EXITING                = 0x40000000,
+    /* VM-Exit Controls */
+    /* INTEL MANUAL: 20-16 vol. 3B */
+    HOST_ADDR_SPACE_SIZE         = 0x00000200,
+    ACK_IRQ_ON_EXIT              = 0x00008000
+} vmcs_field_t;
+
+int vmcs_field_length(vmcs_field_t field);
+char* vmcs_field_name(vmcs_field_t field);
 
 
 
@@ -322,7 +295,7 @@ struct vmcs_segment_access {
            uint32_t    rsvd2       : 15;
        } __attribute__((packed));
     } __attribute__((packed));
-}__attribute__((packed);;
+}__attribute__((packed));
 
 
 struct vmcs_interrupt_state {
index 4c04647..7d02053 100644 (file)
@@ -108,3 +108,4 @@ int Do_VMM(struct VMXRegs regs);
 #endif // ! __V3VEE__
 
 #endif 
+
index b0bd7a5..fe8cf44 100644 (file)
@@ -56,7 +56,8 @@
 
 
 
-static inline int v3_enable_vmx(uint64_t host_state) {
+static inline int v3_enable_vmx(struct vmcs_data* vmxon_ptr) {
+    uint64_t vmxon_ptr_64 = (uint64_t)vmxon_ptr;
     uint8_t ret_invalid = 0;
 
     __asm__ __volatile__ (
@@ -64,7 +65,7 @@ static inline int v3_enable_vmx(uint64_t host_state) {
                 EAX_06_MODRM
                 "setnaeb %0;" // fail invalid (CF=1)
                 : "=q"(ret_invalid)
-                : "a"(&host_state),"0"(ret_invalid)
+                : "a"(&vmxon_ptr_64),"0"(ret_invalid)
                 : "memory");
 
     if (ret_invalid) {
@@ -76,7 +77,8 @@ static inline int v3_enable_vmx(uint64_t host_state) {
 
 // No vmcall necessary - is only executed by the guest
 
-static inline int vmcs_clear(uint64_t addr) {
+static inline int vmcs_clear(struct vmcs_data* vmcs_ptr) {
+    uint64_t vmcs_ptr_64 = (uint64_t)vmcs_ptr;
     uint8_t ret_valid = 0;
     uint8_t ret_invalid = 0;
 
@@ -86,7 +88,7 @@ static inline int vmcs_clear(uint64_t addr) {
             "seteb %0;" // fail valid (ZF=1)
             "setnaeb %1;" // fail invalid (CF=1)
             : "=q"(ret_valid), "=q"(ret_invalid)
-            : "a"(&addr), "0"(ret_valid), "1"(ret_invalid)
+            : "a"(&vmcs_ptr_64), "0"(ret_valid), "1"(ret_invalid)
             : "memory");
 
     CHECK_VMXFAIL(ret_valid, ret_invalid);
@@ -113,8 +115,8 @@ static inline int vmcs_resume() {
 }
 
 
-static inline int vmcs_load(vmcs_t * vmcs_ptr) {
-    uint64_t addr = (uint64_t)vmcs_ptr;
+static inline int vmcs_load(struct vmcs_data* vmcs_ptr) {
+    uint64_t vmcs_ptr_64 = (uint64_t)vmcs_ptr;
     uint8_t ret_valid = 0;
     uint8_t ret_invalid = 0;
     
@@ -124,7 +126,7 @@ static inline int vmcs_load(vmcs_t * vmcs_ptr) {
                 "seteb %0;" // fail valid (ZF=1)
                 "setnaeb %1;"  // fail invalid (CF=1)
                 : "=q"(ret_valid), "=q"(ret_invalid)
-                : "a"(&addr), "0"(ret_valid), "1"(ret_invalid)
+                : "a"(&vmcs_ptr_64), "0"(ret_valid), "1"(ret_invalid)
                 : "memory");
     
     CHECK_VMXFAIL(ret_valid, ret_invalid);
@@ -132,23 +134,21 @@ static inline int vmcs_load(vmcs_t * vmcs_ptr) {
     return VMX_SUCCESS;
 }
 
-static inline int vmcs_store(vmcs_t * vmcs_ptr) {
-    uint64_t addr = (uint64_t)vmcs_ptr;
+static inline int vmcs_store(struct vmcs_data* vmcs_ptr) {
+    uint64_t vmcs_ptr_64 = (uint64_t)vmcs_ptr;
 
     __asm__ __volatile__ (
                VMPTRSRT_OPCODE
                EAX_07_MODRM
                :
-               : "a"(&addr)
+               : "a"(&vmcs_ptr_64)
                : "memory");
 
     return VMX_SUCCESS;
 }
 
-/* According to Intel, vmread will return an architecure sized type - be sure that
- * dst is at least 64-bits in IA-32e and 32 otherwise */
 static inline int vmcs_read(addr_t vmcs_index, void * dst, int len) {
-    addr_t val = 0;
+    uint64_t val = 0;
     uint8_t ret_valid = 0;
     uint8_t ret_invalid = 0;
 
@@ -165,7 +165,19 @@ static inline int vmcs_read(addr_t vmcs_index, void * dst, int len) {
     CHECK_VMXFAIL(ret_valid, ret_invalid);
 
     // TODO: Fix this, will have to do a cast because dst will be variable length
-    *dst = val;
+    switch(len)
+    {
+        case 2:
+            *((uint16_t*)dst) = (uint16_t)val;
+            break;
+        case 4:
+            *((uint32_t*)dst) = (uint32_t)val;
+            break;
+        case 8:
+            *((uint64_t*)dst) = (uint64_t)val;
+            break;
+    }
+
 
     return VMX_SUCCESS;
 }
index aa25f5e..35dc5e1 100644 (file)
@@ -154,6 +154,512 @@ void print_vmcs_segment(char * name, vmcs_segment* seg)
     PrintDebug("\tAccess: %x\n", seg->access);
 }
 
+/*
+ * Returns the field length in bytes
+ */
+int vmcs_field_length(vmcs_field_t field)
+{
+    switch(field)
+    {
+        case VMCS_GUEST_ES_SELECTOR:
+        case VMCS_GUEST_CS_SELECTOR:
+        case VMCS_GUEST_SS_SELECTOR:
+        case VMCS_GUEST_DS_SELECTOR:
+        case VMCS_GUEST_FS_SELECTOR:
+        case VMCS_GUEST_GS_SELECTOR:
+        case VMCS_GUEST_LDTR_SELECTOR:
+        case VMCS_GUEST_TR_SELECTOR:
+            /* 16 bit host state */
+        case VMCS_HOST_ES_SELECTOR:
+        case VMCS_HOST_CS_SELECTOR:
+        case VMCS_HOST_SS_SELECTOR:
+        case VMCS_HOST_DS_SELECTOR:
+        case VMCS_HOST_FS_SELECTOR:
+        case VMCS_HOST_GS_SELECTOR:
+        case VMCS_HOST_TR_SELECTOR:
+            return 2;
+            /* 64 bit control fields */
+        case IO_BITMAP_A_ADDR:
+        case IO_BITMAP_A_ADDR_HIGH:
+        case IO_BITMAP_B_ADDR:
+        case IO_BITMAP_B_ADDR_HIGH:
+        case MSR_BITMAPS:
+        case MSR_BITMAPS_HIGH:
+        case VM_EXIT_MSR_STORE_ADDR:
+        case VM_EXIT_MSR_STORE_ADDR_HIGH:
+        case VM_EXIT_MSR_LOAD_ADDR:
+        case VM_EXIT_MSR_LOAD_ADDR_HIGH:
+        case VM_ENTRY_MSR_LOAD_ADDR:
+        case VM_ENTRY_MSR_LOAD_ADDR_HIGH:
+        case VMCS_EXEC_PTR:
+        case VMCS_EXEC_PTR_HIGH:
+        case TSC_OFFSET:
+        case TSC_OFFSET_HIGH:
+        case VIRT_APIC_PAGE_ADDR:
+        case VIRT_APIC_PAGE_ADDR_HIGH:
+            /* 64 bit guest state fields */
+        case VMCS_LINK_PTR:
+        case VMCS_LINK_PTR_HIGH:
+        case GUEST_IA32_DEBUGCTL:
+        case GUEST_IA32_DEBUGCTL_HIGH:
+        case GUEST_IA32_PERF_GLOBAL_CTRL:
+        case GUEST_IA32_PERF_GLOBAL_CTRL_HIGH:
+            return 8;
+            /* 32 bit control fields */
+        case PIN_VM_EXEC_CTRLS:
+        case PROC_VM_EXEC_CTRLS:
+        case EXCEPTION_BITMAP:
+        case PAGE_FAULT_ERROR_MASK:
+        case PAGE_FAULT_ERROR_MATCH:
+        case CR3_TARGET_COUNT:
+        case VM_EXIT_CTRLS:
+        case VM_EXIT_MSR_STORE_COUNT:
+        case VM_EXIT_MSR_LOAD_COUNT:
+        case VM_ENTRY_CTRLS:
+        case VM_ENTRY_MSR_LOAD_COUNT:
+        case VM_ENTRY_INT_INFO_FIELD:
+        case VM_ENTRY_EXCEPTION_ERROR:
+        case VM_ENTRY_INSTR_LENGTH:
+        case TPR_THRESHOLD:
+            /* 32 bit Read Only data fields */
+        case VM_INSTR_ERROR:
+        case EXIT_REASON:
+        case VM_EXIT_INT_INFO:
+        case VM_EXIT_INT_ERROR:
+        case IDT_VECTOR_INFO:
+        case IDT_VECTOR_ERROR:
+        case VM_EXIT_INSTR_LENGTH:
+        case VMX_INSTR_INFO:
+            /* 32 bit Guest state fields */
+        case GUEST_ES_LIMIT:
+        case GUEST_CS_LIMIT:
+        case GUEST_SS_LIMIT:
+        case GUEST_DS_LIMIT:
+        case GUEST_FS_LIMIT:
+        case GUEST_GS_LIMIT:
+        case GUEST_LDTR_LIMIT:
+        case GUEST_TR_LIMIT:
+        case GUEST_GDTR_LIMIT:
+        case GUEST_IDTR_LIMIT:
+        case GUEST_ES_ACCESS:
+        case GUEST_CS_ACCESS:
+        case GUEST_SS_ACCESS:
+        case GUEST_DS_ACCESS:
+        case GUEST_FS_ACCESS:
+        case GUEST_GS_ACCESS:
+        case GUEST_LDTR_ACCESS:
+        case GUEST_TR_ACCESS:
+        case GUEST_INT_STATE:
+        case GUEST_ACTIVITY_STATE:
+        case GUEST_SMBASE:
+        case GUEST_IA32_SYSENTER_CS:
+            /* 32 bit host state field */
+        case HOST_IA32_SYSENTER_CS:
+            return 4;
+            /* Natural Width Control Fields */
+        case CR0_GUEST_HOST_MASK:
+        case CR4_GUEST_HOST_MASK:
+        case CR0_READ_SHADOW:
+        case CR4_READ_SHADOW:
+        case CR3_TARGET_VALUE_0:
+        case CR3_TARGET_VALUE_1:
+        case CR3_TARGET_VALUE_2:
+        case CR3_TARGET_VALUE_3:
+            /* Natural Width Read Only Fields */
+        case EXIT_QUALIFICATION:
+        case IO_RCX:
+        case IO_RSI:
+        case IO_RDI:
+        case IO_RIP:
+        case GUEST_LINEAR_ADDR:
+            /* Natural Width Guest State Fields */
+        case GUEST_CR0:
+        case GUEST_CR3:
+        case GUEST_CR4:
+        case GUEST_ES_BASE:
+        case GUEST_CS_BASE:
+        case GUEST_SS_BASE:
+        case GUEST_DS_BASE:
+        case GUEST_FS_BASE:
+        case GUEST_GS_BASE:
+        case GUEST_LDTR_BASE:
+        case GUEST_TR_BASE:
+        case GUEST_GDTR_BASE:
+        case GUEST_IDTR_BASE:
+        case GUEST_DR7:
+        case GUEST_RSP:
+        case GUEST_RIP:
+        case GUEST_RFLAGS:
+        case GUEST_PENDING_DEBUG_EXCS:
+        case GUEST_IA32_SYSENTER_ESP:
+        case GUEST_IA32_SYSENTER_EIP:
+            /* Natural Width Host State Fields */
+        case HOST_CR0:
+        case HOST_CR3:
+        case HOST_CR4:
+        case HOST_FS_BASE:
+        case HOST_GS_BASE:
+        case HOST_TR_BASE:
+        case HOST_GDTR_BASE:
+        case HOST_IDTR_BASE:
+        case HOST_IA32_SYSENTER_ESP:
+        case HOST_IA32_SYSENTER_EIP:
+        case HOST_RSP:
+        case HOST_RIP:
+            /* Pin Based VM Execution Controls */
+            /* INTEL MANUAL: 20-10 vol 3B */
+        case EXTERNAL_INTERRUPT_EXITING:
+        case NMI_EXITING:
+        case VIRTUAL_NMIS:
+            /* Processor Based VM Execution Controls */
+            /* INTEL MANUAL: 20-11 vol. 3B */
+        case INTERRUPT_WINDOWS_EXIT:
+        case USE_TSC_OFFSETTING:
+        case HLT_EXITING:
+        case INVLPG_EXITING:
+        case MWAIT_EXITING:
+        case RDPMC_EXITING:
+        case RDTSC_EXITING:
+        case CR8_LOAD_EXITING:
+        case CR8_STORE_EXITING:
+        case USE_TPR_SHADOW:
+        case NMI_WINDOW_EXITING:
+        case MOVDR_EXITING:
+        case UNCONDITION_IO_EXITING:
+        case USE_IO_BITMAPS:
+        case USE_MSR_BITMAPS:
+        case MONITOR_EXITING:
+        case PAUSE_EXITING:
+            /* VM-Exit Controls */
+            /* INTEL MANUAL: 20-16 vol. 3B */
+        case HOST_ADDR_SPACE_SIZE:
+        case ACK_IRQ_ON_EXIT:
+#ifdef __V3_64BIT__
+            return 8;
+#else
+            return 4;
+#endif
+        default:
+            return -1;
+    }
+}
+
+char* vmcs_field_name(vmcs_field_t field)
+{   
+    case(field)
+    {
+        case VMCS_GUEST_ES_SELECTOR:
+            return "VMCS_GUEST_ES_SELECTOR";
+        case VMCS_GUEST_CS_SELECTOR:
+            return "VMCS_GUEST_CS_SELECTOR";
+        case VMCS_GUEST_SS_SELECTOR:
+            return "VMCS_GUEST_SS_SELECTOR";
+        case VMCS_GUEST_DS_SELECTOR:
+            return "VMCS_GUEST_DS_SELECTOR";
+        case VMCS_GUEST_FS_SELECTOR:
+            return "VMCS_GUEST_FS_SELECTOR";
+        case VMCS_GUEST_GS_SELECTOR:
+            return "VMCS_GUEST_GS_SELECTOR";
+        case VMCS_GUEST_LDTR_SELECTOR:
+            return "VMCS_GUEST_LDTR_SELECTOR";
+        case VMCS_GUEST_TR_SELECTOR:
+            return "VMCS_GUEST_TR_SELECTOR";
+        case VMCS_HOST_ES_SELECTOR:
+            return "VMCS_HOST_ES_SELECTOR";
+        case VMCS_HOST_CS_SELECTOR:
+            return "VMCS_HOST_CS_SELECTOR";
+        case VMCS_HOST_SS_SELECTOR:
+            return "VMCS_HOST_SS_SELECTOR";
+        case VMCS_HOST_DS_SELECTOR:
+            return "VMCS_HOST_DS_SELECTOR";
+        case VMCS_HOST_FS_SELECTOR:
+            return "VMCS_HOST_FS_SELECTOR";
+        case VMCS_HOST_GS_SELECTOR:
+            return "VMCS_HOST_GS_SELECTOR";
+        case VMCS_HOST_TR_SELECTOR:
+            return "VMCS_HOST_TR_SELECTOR";
+        case IO_BITMAP_A_ADDR:
+            return "IO_BITMAP_A_ADDR";
+        case IO_BITMAP_A_ADDR_HIGH:
+            return "IO_BITMAP_A_ADDR_HIGH";
+        case IO_BITMAP_B_ADDR:
+            return "IO_BITMAP_B_ADDR";
+        case IO_BITMAP_B_ADDR_HIGH:
+            return "IO_BITMAP_B_ADDR_HIGH";
+        case MSR_BITMAPS:
+            return "MSR_BITMAPS";
+        case MSR_BITMAPS_HIGH:
+            return "MSR_BITMAPS_HIGH";
+        case VM_EXIT_MSR_STORE_ADDR:
+            return "VM_EXIT_MSR_STORE_ADDR";
+        case VM_EXIT_MSR_STORE_ADDR_HIGH:
+            return "VM_EXIT_MSR_STORE_ADDR_HIGH";
+        case VM_EXIT_MSR_LOAD_ADDR:
+            return "VM_EXIT_MSR_LOAD_ADDR";
+        case VM_EXIT_MSR_LOAD_ADDR_HIGH:
+            return "VM_EXIT_MSR_LOAD_ADDR_HIGH";
+        case VM_ENTRY_MSR_LOAD_ADDR:
+            return "VM_ENTRY_MSR_LOAD_ADDR";
+        case VM_ENTRY_MSR_LOAD_ADDR_HIGH:
+            return "VM_ENTRY_MSR_LOAD_ADDR_HIGH";
+        case VMCS_EXEC_PTR:
+            return "VMCS_EXEC_PTR";
+        case VMCS_EXEC_PTR_HIGH:
+            return "VMCS_EXEC_PTR_HIGH";
+        case TSC_OFFSET:
+            return "TSC_OFFSET";
+        case TSC_OFFSET_HIGH:
+            return "TSC_OFFSET_HIGH";
+        case VIRT_APIC_PAGE_ADDR:
+            return "VIRT_APIC_PAGE_ADDR";
+        case VIRT_APIC_PAGE_ADDR_HIGH:
+            return "VIRT_APIC_PAGE_ADDR_HIGH";
+        case VMCS_LINK_PTR:
+            return "VMCS_LINK_PTR";
+        case VMCS_LINK_PTR_HIGH:
+            return "VMCS_LINK_PTR_HIGH";
+        case GUEST_IA32_DEBUGCTL:
+            return "GUEST_IA32_DEBUGCTL";
+        case GUEST_IA32_DEBUGCTL_HIGH:
+            return "GUEST_IA32_DEBUGCTL_HIGH";
+        case GUEST_IA32_PERF_GLOBAL_CTRL:
+            return "GUEST_IA32_PERF_GLOBAL_CTRL";
+        case GUEST_IA32_PERF_GLOBAL_CTRL_HIGH:
+            return "GUEST_IA32_PERF_GLOBAL_CTRL_HIGH";
+        case PIN_VM_EXEC_CTRLS:
+            return "PIN_VM_EXEC_CTRLS";
+        case PROC_VM_EXEC_CTRLS:
+            return "PROC_VM_EXEC_CTRLS";
+        case EXCEPTION_BITMAP:
+            return "EXCEPTION_BITMAP";
+        case PAGE_FAULT_ERROR_MASK:
+            return "PAGE_FAULT_ERROR_MASK";
+        case PAGE_FAULT_ERROR_MATCH:
+            return "PAGE_FAULT_ERROR_MATCH";
+        case CR3_TARGET_COUNT:
+            return "CR3_TARGET_COUNT";
+        case VM_EXIT_CTRLS:
+            return "VM_EXIT_CTRLS";
+        case VM_EXIT_MSR_STORE_COUNT:
+            return "VM_EXIT_MSR_STORE_COUNT";
+        case VM_EXIT_MSR_LOAD_COUNT:
+            return "VM_EXIT_MSR_LOAD_COUNT";
+        case VM_ENTRY_CTRLS:
+            return "VM_ENTRY_CTRLS";
+        case VM_ENTRY_MSR_LOAD_COUNT:
+            return "VM_ENTRY_MSR_LOAD_COUNT";
+        case VM_ENTRY_INT_INFO_FIELD:
+            return "VM_ENTRY_INT_INFO_FIELD";
+        case VM_ENTRY_EXCEPTION_ERROR:
+            return "VM_ENTRY_EXCEPTION_ERROR";
+        case VM_ENTRY_INSTR_LENGTH:
+            return "VM_ENTRY_INSTR_LENGTH";
+        case TPR_THRESHOLD:
+            return "TPR_THRESHOLD";
+        case VM_INSTR_ERROR:
+            return "VM_INSTR_ERROR";
+        case EXIT_REASON:
+            return "EXIT_REASON";
+        case VM_EXIT_INT_INFO:
+            return "VM_EXIT_INT_INFO";
+        case VM_EXIT_INT_ERROR:
+            return "VM_EXIT_INT_ERROR";
+        case IDT_VECTOR_INFO:
+            return "IDT_VECTOR_INFO";
+        case IDT_VECTOR_ERROR:
+            return "IDT_VECTOR_ERROR";
+        case VM_EXIT_INSTR_LENGTH:
+            return "VM_EXIT_INSTR_LENGTH";
+        case VMX_INSTR_INFO:
+            return "VMX_INSTR_INFO";
+        case GUEST_ES_LIMIT:
+            return "GUEST_ES_LIMIT";
+        case GUEST_CS_LIMIT:
+            return "GUEST_CS_LIMIT";
+        case GUEST_SS_LIMIT:
+            return "GUEST_SS_LIMIT";
+        case GUEST_DS_LIMIT:
+            return "GUEST_DS_LIMIT";
+        case GUEST_FS_LIMIT:
+            return "GUEST_FS_LIMIT";
+        case GUEST_GS_LIMIT:
+            return "GUEST_GS_LIMIT";
+        case GUEST_LDTR_LIMIT:
+            return "GUEST_LDTR_LIMIT";
+        case GUEST_TR_LIMIT:
+            return "GUEST_TR_LIMIT";
+        case GUEST_GDTR_LIMIT:
+            return "GUEST_GDTR_LIMIT";
+        case GUEST_IDTR_LIMIT:
+            return "GUEST_IDTR_LIMIT";
+        case GUEST_ES_ACCESS:
+            return "GUEST_ES_ACCESS";
+        case GUEST_CS_ACCESS:
+            return "GUEST_CS_ACCESS";
+        case GUEST_SS_ACCESS:
+            return "GUEST_SS_ACCESS";
+        case GUEST_DS_ACCESS:
+            return "GUEST_DS_ACCESS";
+        case GUEST_FS_ACCESS:
+            return "GUEST_FS_ACCESS";
+        case GUEST_GS_ACCESS:
+            return "GUEST_GS_ACCESS";
+        case GUEST_LDTR_ACCESS:
+            return "GUEST_LDTR_ACCESS";
+        case GUEST_TR_ACCESS:
+            return "GUEST_TR_ACCESS";
+        case GUEST_INT_STATE:
+            return "GUEST_INT_STATE";
+        case GUEST_ACTIVITY_STATE:
+            return "GUEST_ACTIVITY_STATE";
+        case GUEST_SMBASE:
+            return "GUEST_SMBASE";
+        case GUEST_IA32_SYSENTER_CS:
+            return "GUEST_IA32_SYSENTER_CS";
+        case HOST_IA32_SYSENTER_CS:
+            return "HOST_IA32_SYSENTER_CS";
+        case CR0_GUEST_HOST_MASK:
+            return "CR0_GUEST_HOST_MASK";
+        case CR4_GUEST_HOST_MASK:
+            return "CR4_GUEST_HOST_MASK";
+        case CR0_READ_SHADOW:
+            return "CR0_READ_SHADOW";
+        case CR4_READ_SHADOW:
+            return "CR4_READ_SHADOW";
+        case CR3_TARGET_VALUE_0:
+            return "CR3_TARGET_VALUE_0";
+        case CR3_TARGET_VALUE_1:
+            return "CR3_TARGET_VALUE_1";
+        case CR3_TARGET_VALUE_2:
+            return "CR3_TARGET_VALUE_2";
+        case CR3_TARGET_VALUE_3:
+            return "CR3_TARGET_VALUE_3";
+        case EXIT_QUALIFICATION:
+            return "EXIT_QUALIFICATION";
+        case IO_RCX:
+            return "IO_RCX";
+        case IO_RSI:
+            return "IO_RSI";
+        case IO_RDI:
+            return "IO_RDI";
+        case IO_RIP:
+            return "IO_RIP";
+        case GUEST_LINEAR_ADDR:
+            return "GUEST_LINEAR_ADDR";
+        case GUEST_CR0:
+            return "GUEST_CR0";
+        case GUEST_CR3:
+            return "GUEST_CR3";
+        case GUEST_CR4:
+            return "GUEST_CR4";
+        case GUEST_ES_BASE:
+            return "GUEST_ES_BASE";
+        case GUEST_CS_BASE:
+            return "GUEST_CS_BASE";
+        case GUEST_SS_BASE:
+            return "GUEST_SS_BASE";
+        case GUEST_DS_BASE:
+            return "GUEST_DS_BASE";
+        case GUEST_FS_BASE:
+            return "GUEST_FS_BASE";
+        case GUEST_GS_BASE:
+            return "GUEST_GS_BASE";
+        case GUEST_LDTR_BASE:
+            return "GUEST_LDTR_BASE";
+        case GUEST_TR_BASE:
+            return "GUEST_TR_BASE";
+        case GUEST_GDTR_BASE:
+            return "GUEST_GDTR_BASE";
+        case GUEST_IDTR_BASE:
+            return "GUEST_IDTR_BASE";
+        case GUEST_DR7:
+            return "GUEST_DR7";
+        case GUEST_RSP:
+            return "GUEST_RSP";
+        case GUEST_RIP:
+            return "GUEST_RIP";
+        case GUEST_RFLAGS:
+            return "GUEST_RFLAGS";
+        case GUEST_PENDING_DEBUG_EXCS:
+            return "GUEST_PENDING_DEBUG_EXCS";
+        case GUEST_IA32_SYSENTER_ESP:
+            return "GUEST_IA32_SYSENTER_ESP";
+        case GUEST_IA32_SYSENTER_EIP:
+            return "GUEST_IA32_SYSENTER_EIP";
+        case HOST_CR0:
+            return "HOST_CR0";
+        case HOST_CR3:
+            return "HOST_CR3";
+        case HOST_CR4:
+            return "HOST_CR4";
+        case HOST_FS_BASE:
+            return "HOST_FS_BASE";
+        case HOST_GS_BASE:
+            return "HOST_GS_BASE";
+        case HOST_TR_BASE:
+            return "HOST_TR_BASE";
+        case HOST_GDTR_BASE:
+            return "HOST_GDTR_BASE";
+        case HOST_IDTR_BASE:
+            return "HOST_IDTR_BASE";
+        case HOST_IA32_SYSENTER_ESP:
+            return "HOST_IA32_SYSENTER_ESP";
+        case HOST_IA32_SYSENTER_EIP:
+            return "HOST_IA32_SYSENTER_EIP";
+        case HOST_RSP:
+            return "HOST_RSP";
+        case HOST_RIP:
+            return "HOST_RIP";
+        case EXTERNAL_INTERRUPT_EXITING:
+            return "EXTERNAL_INTERRUPT_EXITING";
+        case NMI_EXITING:
+            return "NMI_EXITING";
+        case VIRTUAL_NMIS:
+            return "VIRTUAL_NMIS";
+        case INTERRUPT_WINDOWS_EXIT:
+            return "INTERRUPT_WINDOWS_EXIT";
+        case USE_TSC_OFFSETTING:
+            return "USE_TSC_OFFSETTING";
+        case HLT_EXITING:
+            return "HLT_EXITING";
+        case INVLPG_EXITING:
+            return "INVLPG_EXITING";
+        case MWAIT_EXITING:
+            return "MWAIT_EXITING";
+        case RDPMC_EXITING:
+            return "RDPMC_EXITING";
+        case RDTSC_EXITING:
+            return "RDTSC_EXITING";
+        case CR8_LOAD_EXITING:
+            return "CR8_LOAD_EXITING";
+        case CR8_STORE_EXITING:
+            return "CR8_STORE_EXITING";
+        case USE_TPR_SHADOW:
+            return "USE_TPR_SHADOW";
+        case NMI_WINDOW_EXITING:
+            return "NMI_WINDOW_EXITING";
+        case MOVDR_EXITING:
+            return "MOVDR_EXITING";
+        case UNCONDITION_IO_EXITING:
+            return "UNCONDITION_IO_EXITING";
+        case USE_IO_BITMAPS:
+            return "USE_IO_BITMAPS";
+        case USE_MSR_BITMAPS:
+            return "USE_MSR_BITMAPS";
+        case MONITOR_EXITING:
+            return "MONITOR_EXITING";
+        case PAUSE_EXITING:
+            return "PAUSE_EXITING";
+        case HOST_ADDR_SPACE_SIZE:
+            return "HOST_ADDR_SPACE_SIZE";
+        case ACK_IRQ_ON_EXIT:
+            return "ACK_IRQ_ON_EXIT";
+        default:
+            return NULL;
+    }
+}
+
+
 void PrintTrace_VMCSHostStateArea(struct VMCSHostStateArea * hostState) {
   PrintTrace("\n==> Host State Area\n");
   PrintTrace("HOST_CR0: %x\n", (uint_t)hostState->cr0);
index 8a315ce..d152e0b 100644 (file)
@@ -75,6 +75,7 @@ uint_t myregs = 0;
 
 
 
+static struct vmcs_data* vmxon_ptr;
 
 
 
@@ -398,7 +399,9 @@ static vmcs_data* allocate_vmcs() {
 
 
 
-static void init_vmcs_bios(vmcs_t * vmcs, struct guest_info * vm_info) {
+static void init_vmcs_bios(struct guest_info * vm_info) 
+{
+
 
 }
 
@@ -410,14 +413,14 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config
     struct vmx_data* data;
 
     PrintDebug("Allocating vmx_data\n");
-    data = (struct vmx_data*)V3_Malloc(sizeof(vmx_data));
+    data = (struct vmx_data*)V3_Malloc(sizeof(struct vmx_data));
     PrintDebug("Allocating VMCS\n");
     data->vmcs = allocate_vmcs();
 
     info->vmm_data = (void*)data;
 
-    PrintDebug("Initializing VMCS (addr=%p)\n", (void *)info->vmm_data);
-    init_vmcs_bios((vmcs_t *)(info->vmm_data), info);
+    PrintDebug("Initializing VMCS (addr=%p)\n", info->vmm_data);
+    init_vmcs_bios((struct vmx_data*)(info->vmm_data), info);
 
     v3_post_config_guest(info, config_ptr);
 
@@ -427,7 +430,23 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config
 
 
 
-static int start_svm_guest(struct guest_info *info) {
+static int start_vmx_guest(struct guest_info *info) {
+    struct vmx_data* vmx_data = (struct vmx_data*)info->vmm_data;
+    int vmx_ret;
+
+    // Have to do a whole lot of flag setting here
+    vmx_ret = vmcs_clear(vmx_data->vmcs);
+    if(vmx_ret != VMX_SUCCESS) {
+        PrintDebug("VMCS Clear failed\n");
+        return -1;
+    }
+    vmx_ret = vmcs_load(vmx_data->vmcs);
+    if(vmx_ret != VMX_SUCCESS) {
+        PrintDebug("Executing VMPTRLD\n");
+        return -1;
+    }
+
+    // Setup guest state
     return -1;
 }
 
@@ -454,8 +473,8 @@ int v3_is_vmx_capable() {
        }
 
     } else {
-       PrintDebug("VMX not supported on this cpu\n");
-       return 0;
+        PrintDebug("VMX not supported on this cpu\n");
+        return 0;
     }
 
     return 1;
@@ -490,15 +509,7 @@ static int setup_base_host_state() {
 void v3_init_vmx(struct v3_ctrl_ops * vm_ops) {
     v3_msr_t basic_msr;
 
-    // Setup the host state save area
-    void * host_state = V3_AllocPages(1);
-
-    v3_get_msr(VMX_BASIC_MSR, &(basic_msr.hi), &(basic_msr.lo));
     
-    *(uint32_t *)host_state = ((struct vmx_basic_msr *)basic_msr.value)->revision;
-    
-    PrintDebug("VMX revision: 0x%p\n", host_state);
-
     __asm__ __volatile__ (
                          "movl %%cr4, %%ebx; "
                          "orl  %%ebx, 0x00002000; "
@@ -514,19 +525,22 @@ void v3_init_vmx(struct v3_ctrl_ops * vm_ops) {
                          "movl %%ebx, %%cr0"
                          );
 
+    // Setup VMXON Region
+    vmxon_ptr = allocate_vmcs();
+    PrintDebug("VMX revision: 0x%p\n", (void*)vmxon_ptr);
 
-    if (v3_enable_vmx(host_state) == 0) {
-       PrintDebug("VMX Enabled\n");
+    if (v3_enable_vmx(vmxon_ptr) == 0) {
+        PrintDebug("VMX Enabled\n");
     } else {
-       PrintError("VMX initialization failure\n");
-       return;
+        PrintError("VMX initialization failure\n");
+        return;
     }
        
 
     if (has_vmx_nested_paging() == 1) {
-       v3_cpu_type = V3_VMX_EPT_CPU;
+        v3_cpu_type = V3_VMX_EPT_CPU;
     } else {
-       v3_cpu_type = V3_VMX_CPU;
+        v3_cpu_type = V3_VMX_CPU;
     }
 
     // Setup the VMX specific vmm operations
index eefe3e3..94f7432 100644 (file)
@@ -54,150 +54,6 @@ EXPORT SAFE_VM_LAUNCH
 EXPORT Init_VMCS_HostState
 EXPORT Init_VMCS_GuestState
        
-;
-; Enable_VMX - Turn on VMX
-;
-align 8
-Enable_VMX:
-       push    ebp
-       mov     ebp, esp
-       push    ebx
-       mov     ebx, cr4
-       or      ebx, dword 0x00002000
-       mov     cr4, ebx
-       mov     ebx, cr0
-       or      ebx, dword 0x80000021
-       mov     cr0, ebx
-       vmxon   [ebp+8]
-       pop     ebx
-       pop     ebp
-       mov     eax, VMX_SUCCESS
-       jnc     .return
-       mov     eax, VMX_FAIL_INVALID
-.return
-       ret
-
-       
-;
-; VMREAD  - read a value from a VMCS
-;
-align 8
-VMCS_READ:
-       push    ebp
-       mov     ebp, esp
-       push    ecx
-       push    ebx
-
-       mov     ecx, [ebp + 8]
-       mov     ebx,[ebp + 12]
-;      lea     ebx, ebp
-       vmread  [ebx], ecx
-
-       pop     ebx
-       pop     ecx
-       pop     ebp
-       jz      .error_code
-       jc      .error
-
-       mov     eax, VMX_SUCCESS
-       jmp     .return
-.error
-       mov     eax, VMX_FAIL_INVALID
-       jmp     .return
-.error_code
-       mov     eax, VMX_FAIL_VALID
-.return
-       ret
-
-;
-; VMWRITE - write a value to a VMCS
-align 8
-VMCS_WRITE:
-       push    ebp
-       mov     ebp, esp
-       push    ebx
-
-       mov     eax, [ebp + 8]
-       mov     ebx, [ebp + 12]
-       vmwrite eax, [ebx]
-
-       pop     ebx
-       pop     ebp
-       jz      .error_code
-       jc      .error
-
-       mov     eax, VMX_SUCCESS
-       jmp     .return
-.error
-       mov     eax, VMX_FAIL_INVALID
-       jmp     .return
-.error_code
-       mov     eax, VMX_FAIL_VALID
-.return
-       ret
-
-;
-; VMCLEAR - Initializes a VMCS
-;
-align 8
-VMCS_CLEAR:
-       vmclear [esp+4]
-       jz      .error_code
-       jc      .error
-
-       mov     eax, VMX_SUCCESS
-       jmp     .return
-.error
-       mov     eax, VMX_FAIL_INVALID
-       jmp     .return
-.error_code
-       mov     eax, VMX_FAIL_VALID
-.return
-       ret
-
-
-
-;
-; VMCS_LOAD - load a VMCS 
-;
-align 8
-VMCS_LOAD:
-       vmptrld [esp+4]
-       jz      .error_code
-       jc      .error
-
-       mov     eax, VMX_SUCCESS
-       jmp     .return
-.error
-       mov     eax, VMX_FAIL_INVALID
-       jmp     .return
-.error_code
-       mov     eax, VMX_FAIL_VALID
-.return
-       ret
-
-
-
-;
-; VMCS_STORE - Store a VMCS
-;
-align 8
-VMCS_STORE:
-       mov     eax, [esp+4]
-       vmptrst [eax]
-       jz      .error_code
-       jc      .error
-
-       mov     eax, VMX_SUCCESS
-       jmp     .return
-.error
-       mov     eax, VMX_FAIL_INVALID
-       jmp     .return
-.error_code
-       mov     eax, VMX_FAIL_VALID
-.return
-       ret
-
 
 ;
 ; VMCS_LAUNCH
@@ -755,7 +611,18 @@ InitHostSelectors:
        jz      .error_code
        jc      .error
 
-       mov     ebx, VMCS_HOST_SS_SELECTOR
+       mov     ebx, VMCS_HOST_SS_SELECTOR;
+    PrintDebug("VMX revision: 0x%p\n", (void*)vmxon_ptr);
+
+    if (v3_enable_vmx(vmxon_ptr) == 0) {
+        PrintDebug("VMX Enabled\n");
+    } else {
+        PrintError("VMX initialization failure\n");
+        return;
+    }
+       
+
+
        mov     eax, ss
        vmwrite ebx, eax
        jz      .error_code