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.


vmx cleanup
Jack Lange [Thu, 21 Apr 2011 21:32:50 +0000 (16:32 -0500)]
palacios/include/palacios/vmcs.h
palacios/include/palacios/vmx.h
palacios/include/palacios/vmx_hw_info.h [new file with mode: 0644]
palacios/include/palacios/vmx_lowlevel.h
palacios/src/palacios/Makefile
palacios/src/palacios/vmcs.c
palacios/src/palacios/vmm.c
palacios/src/palacios/vmx.c
palacios/src/palacios/vmx_hw_info.c [new file with mode: 0644]

index 9129d1b..c80a23c 100644 (file)
 
 
 
+struct vmcs_field_encoding {
+    uint8_t access_type    : 1; /*  0 = full, 1 = high, (for accessing 64 bit fields on 32bit CPU) */
+    uint16_t index         : 9;
+    uint8_t type           : 2; /* 0=ctrl, 1=read-only, 2 = guest state, 3 = host state */
+    uint8_t rsvd1          : 1; /* MBZ */
+    uint8_t width          : 2; /* 0 = 16bit, 1 = 64bit, 2 = 32bit, 3 = natural width */
+    uint32_t rsvd2         : 17;
+} __attribute__((packed));
+
 
 typedef enum {
     VMCS_GUEST_ES_SELECTOR       = 0x00000800,
index fd5e6ce..7a0a039 100644 (file)
 #include <palacios/vmm.h>
 #include <palacios/vm_guest.h>
 
-// Intel VMX Specific MSRs
-#define VMX_FEATURE_CONTROL_MSR     0x0000003a
-#define VMX_BASIC_MSR               0x00000480
-#define VMX_PINBASED_CTLS_MSR       0x00000481
-#define VMX_PROCBASED_CTLS_MSR      0x00000482
-#define VMX_EXIT_CTLS_MSR           0x00000483
-#define VMX_ENTRY_CTLS_MSR          0x00000484
-#define VMX_MISC_MSR                0x00000485
-#define VMX_CR0_FIXED0_MSR          0x00000486
-#define VMX_CR0_FIXED1_MSR          0x00000487
-#define VMX_CR4_FIXED0_MSR          0x00000488
-#define VMX_CR4_FIXED1_MSR          0x00000489
-#define VMX_VMCS_ENUM_MSR           0x0000048A
 
 #define VMX_SUCCESS        0
 #define VMX_FAIL_INVALID   1
 #define VMX_FAIL_VALID     2
 #define VMM_ERROR          3
 
-#define FEATURE_CONTROL_LOCK  0x00000001
-#define FEATURE_CONTROL_VMXON 0x00000004
-#define FEATURE_CONTROL_VALID ( FEATURE_CONTROL_LOCK | FEATURE_CONTROL_VMXON )
 
 
-#define CPUID_1_ECX_VTXFLAG 0x00000020
 
 
 struct vmx_pin_ctrls {
@@ -168,15 +151,6 @@ struct vmx_entry_ctrls {
     } __attribute__((packed));
 } __attribute__((packed));
 
-struct vmx_basic_msr {
-    uint32_t revision;
-    uint_t regionSize   : 13;
-    uint_t rsvd1        : 4; // Always 0
-    uint_t physWidth    : 1;
-    uint_t smm          : 1; // Always 1
-    uint_t memType      : 4;
-    uint_t rsvd2        : 10; // Always 0
-}  __attribute__((packed));
 
 typedef enum { 
     VMXASSIST_DISABLED,
diff --git a/palacios/include/palacios/vmx_hw_info.h b/palacios/include/palacios/vmx_hw_info.h
new file mode 100644 (file)
index 0000000..baade9c
--- /dev/null
@@ -0,0 +1,80 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __VMX_HW_INFO_H__
+#define __VMX_HW_INFO_H__
+
+#ifdef __V3VEE__
+
+
+#define VMX_BASIC_MSR               0x00000480
+#define VMX_PINBASED_CTLS_MSR       0x00000481
+#define VMX_PROCBASED_CTLS_MSR      0x00000482
+#define VMX_EXIT_CTLS_MSR           0x00000483
+#define VMX_ENTRY_CTLS_MSR          0x00000484
+#define VMX_MISC_MSR                0x00000485
+#define VMX_CR0_FIXED0_MSR          0x00000486
+#define VMX_CR0_FIXED1_MSR          0x00000487
+#define VMX_CR4_FIXED0_MSR          0x00000488
+#define VMX_CR4_FIXED1_MSR          0x00000489
+#define VMX_VMCS_ENUM_MSR           0x0000048A
+
+
+
+
+struct vmx_basic_msr {
+    union {
+       uint32_t lo;
+       uint32_t hi;
+       struct {
+           uint32_t revision;
+           uint32_t regionSize   : 13;
+           uint8_t rsvd1         : 4; /* Always 0 */
+           uint8_t physWidth     : 1; /* VMCS address field widths 
+                                         (1=32bits, 0=natural width) */
+           uint8_t smm           : 1; // Always 1
+           uint8_t memType       : 4; /* 0 = UC, 6 = WriteBack */
+           uint8_t io_str_info   : 1;
+           uint8_t def1_maybe_0  : 1; /* 1="Any VMX ctrls that default to 1 may be cleared to 0" */
+           uint32_t rsvd2        : 8; /* Always 0 */
+       }  __attribute__((packed));
+    }  __attribute__((packed));
+}  __attribute__((packed));
+
+
+
+
+
+struct vmx_hw_info {
+    struct vmx_basic_msr basic_info;
+    
+
+
+};
+
+
+int v3_init_vmx_hw();
+
+
+
+
+#endif
+
+#endif
index 6db9f17..ce6a440 100644 (file)
 
 
 
-static inline int v3_enable_vmx(addr_t vmxon_ptr) {
-    uint64_t vmxon_ptr_64 __attribute__((aligned(8))) = (uint64_t)vmxon_ptr;
-    uint8_t ret_invalid = 0;
 
-    __asm__ __volatile__ (
-                VMXON_OPCODE
-                EAX_06_MODRM
-                "setnaeb %0;" // fail invalid (CF=1)
-                : "=q"(ret_invalid)
-                : "a"(&vmxon_ptr_64),"0"(ret_invalid)
-                : "memory");
-
-    if (ret_invalid) {
-        return VMX_FAIL_INVALID;
-    } else {
-        return VMX_SUCCESS;
-    }
-}
 
 static inline int vmcs_clear(addr_t vmcs_ptr) {
     uint64_t vmcs_ptr_64 __attribute__ ((aligned(8))) = (uint64_t)vmcs_ptr;
@@ -181,6 +164,26 @@ static inline int vmcs_write(vmcs_field_t vmcs_field, addr_t value) {
     return VMX_SUCCESS;
 }
 
+
+static inline int vmx_on(addr_t vmxon_ptr) {
+    uint64_t vmxon_ptr_64 __attribute__((aligned(8))) = (uint64_t)vmxon_ptr;
+    uint8_t ret_invalid = 0;
+
+    __asm__ __volatile__ (
+                VMXON_OPCODE
+                EAX_06_MODRM
+                "setnaeb %0;" // fail invalid (CF=1)
+                : "=q"(ret_invalid)
+                : "a"(&vmxon_ptr_64),"0"(ret_invalid)
+                : "memory");
+
+    if (ret_invalid) {
+        return VMX_FAIL_INVALID;
+    } else {
+        return VMX_SUCCESS;
+    }
+}
+
 static inline int vmx_off() {
     uint8_t ret_valid = 0;
     uint8_t ret_invalid = 0;
@@ -198,6 +201,57 @@ static inline int vmx_off() {
     return VMX_SUCCESS;
 }
 
+
+static inline int enable_vmx() {
+#ifdef __V3_64BIT__
+    __asm__ __volatile__ (
+                         "movq %%cr4, %%rbx;"
+                         "orq  $0x00002000, %%rbx;"
+                         "movq %%rbx, %%cr4;"
+                         : 
+                         :
+                         : "%rbx"
+                         );
+
+
+    __asm__ __volatile__ (
+                         "movq %%cr0, %%rbx; "
+                         "orq  $0x00000020,%%rbx; "
+                         "movq %%rbx, %%cr0;"
+                         :
+                         :
+                         : "%rbx"
+                         );
+#elif __V3_32BIT__
+    __asm__ __volatile__ (
+                         "movl %%cr4, %%ecx;"
+                         "orl  $0x00002000, %%ecx;"
+                         "movl %%ecx, %%cr4;"
+                         : 
+                         :
+                         : "%ecx"
+                         );
+
+
+
+    __asm__ __volatile__ (
+                         "movl %%cr0, %%ecx; "
+                         "orl  $0x00000020,%%ecx; "
+                         "movl %%ecx, %%cr0;"
+                         :
+                         :
+                         : "%ecx"
+                         );
+    
+#endif
+
+    return 0;
+}
+
+
+
+
+
 #endif
 
 #endif
index dd1b637..5b4a359 100644 (file)
@@ -57,6 +57,7 @@ obj-$(CONFIG_VMX) +=          vmx.o \
                        vmx_io.o \
                        vmx_lowlevel.o \
                        vmx_msr.o \
+                       vmx_hw_info.o \
                        vmcs.o \
                        vmx_ctrl_regs.o \
                        vmx_assist.o
index 0b874fd..f8fe322 100644 (file)
@@ -624,6 +624,7 @@ static void print_exec_ctrls() {
 #ifdef __V3_32BIT__
     print_vmcs_field(VMCS_IO_BITMAP_A_ADDR_HIGH);
 #endif
+
     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR);
 #ifdef __V3_32BIT__
     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR_HIGH);
@@ -762,162 +763,29 @@ void v3_print_vmcs() {
 
 /*
  * Returns the field length in bytes
+ *   It doesn't get much uglier than this... Thanks Intel
  */
 int v3_vmcs_get_field_len(vmcs_field_t field) {
-    switch(field)  {
-       /* 16 bit Control Fields */
-        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:
-        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;
-
-       /* 32 bit Control Fields */
-        case VMCS_PIN_CTRLS:
-        case VMCS_PROC_CTRLS:
-       case VMCS_SEC_PROC_CTRLS:
-        case VMCS_EXCP_BITMAP:
-        case VMCS_PG_FAULT_ERR_MASK:
-        case VMCS_PG_FAULT_ERR_MATCH:
-        case VMCS_CR3_TGT_CNT:
-        case VMCS_EXIT_CTRLS:
-        case VMCS_EXIT_MSR_STORE_CNT:
-        case VMCS_EXIT_MSR_LOAD_CNT:
-        case VMCS_ENTRY_CTRLS:
-        case VMCS_ENTRY_MSR_LOAD_CNT:
-        case VMCS_ENTRY_INT_INFO:
-        case VMCS_ENTRY_EXCP_ERR:
-        case VMCS_ENTRY_INSTR_LEN:
-        case VMCS_TPR_THRESHOLD:
-        case VMCS_INSTR_ERR:
-        case VMCS_EXIT_REASON:
-        case VMCS_EXIT_INT_INFO:
-        case VMCS_EXIT_INT_ERR:
-        case VMCS_IDT_VECTOR_INFO:
-        case VMCS_IDT_VECTOR_ERR:
-        case VMCS_EXIT_INSTR_LEN:
-        case VMCS_EXIT_INSTR_INFO:
-        case VMCS_GUEST_ES_LIMIT:
-        case VMCS_GUEST_CS_LIMIT:
-        case VMCS_GUEST_SS_LIMIT:
-        case VMCS_GUEST_DS_LIMIT:
-        case VMCS_GUEST_FS_LIMIT:
-        case VMCS_GUEST_GS_LIMIT:
-        case VMCS_GUEST_LDTR_LIMIT:
-        case VMCS_GUEST_TR_LIMIT:
-        case VMCS_GUEST_GDTR_LIMIT:
-        case VMCS_GUEST_IDTR_LIMIT:
-        case VMCS_GUEST_ES_ACCESS:
-        case VMCS_GUEST_CS_ACCESS:
-        case VMCS_GUEST_SS_ACCESS:
-        case VMCS_GUEST_DS_ACCESS:
-        case VMCS_GUEST_FS_ACCESS:
-        case VMCS_GUEST_GS_ACCESS:
-        case VMCS_GUEST_LDTR_ACCESS:
-        case VMCS_GUEST_TR_ACCESS:
-        case VMCS_GUEST_INT_STATE:
-        case VMCS_GUEST_ACTIVITY_STATE:
-        case VMCS_GUEST_SMBASE:
-        case VMCS_GUEST_SYSENTER_CS:
-        case VMCS_HOST_SYSENTER_CS:
-            return 4;
+    struct vmcs_field_encoding * enc = (struct vmcs_field_encoding *)&field;
 
-
-       /* high bits of variable width fields
-        * We can probably just delete most of these....
-        */
-        case VMCS_IO_BITMAP_A_ADDR_HIGH:
-        case VMCS_IO_BITMAP_B_ADDR_HIGH:
-        case VMCS_MSR_BITMAP_HIGH:
-        case VMCS_EXIT_MSR_STORE_ADDR_HIGH:
-        case VMCS_EXIT_MSR_LOAD_ADDR_HIGH:
-        case VMCS_ENTRY_MSR_LOAD_ADDR_HIGH:
-        case VMCS_EXEC_PTR_HIGH:
-        case VMCS_TSC_OFFSET_HIGH:
-        case VMCS_VAPIC_ADDR_HIGH:
-       case VMCS_APIC_ACCESS_ADDR_HIGH:
-        case VMCS_LINK_PTR_HIGH:
-        case VMCS_GUEST_DBG_CTL_HIGH:
-        case VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH:
-       case VMCS_HOST_PERF_GLOBAL_CTRL_HIGH:
-       case VMCS_GUEST_EFER_HIGH:
+    switch (enc->width)  {
+       case 0:
+            return 2;
+       case 1: {
+           if (enc->access_type == 1) {
+               return 4;
+           } else {
+#ifdef __V3_64BIT__
+               return 8;
+#else
+               return 4;
+#endif
+           }
+       }
+       case 2:
             return 4;
-
-            /* Natural Width Control Fields */
-        case VMCS_IO_BITMAP_A_ADDR:
-        case VMCS_IO_BITMAP_B_ADDR:
-        case VMCS_MSR_BITMAP:
-        case VMCS_EXIT_MSR_STORE_ADDR:
-        case VMCS_EXIT_MSR_LOAD_ADDR:
-        case VMCS_ENTRY_MSR_LOAD_ADDR:
-        case VMCS_EXEC_PTR:
-        case VMCS_TSC_OFFSET:
-        case VMCS_VAPIC_ADDR:
-       case VMCS_APIC_ACCESS_ADDR:
-        case VMCS_LINK_PTR:
-        case VMCS_GUEST_DBG_CTL:
-        case VMCS_GUEST_PERF_GLOBAL_CTRL:
-       case VMCS_HOST_PERF_GLOBAL_CTRL:
-        case VMCS_CR0_MASK:
-        case VMCS_CR4_MASK:
-        case VMCS_CR0_READ_SHDW:
-        case VMCS_CR4_READ_SHDW:
-        case VMCS_CR3_TGT_VAL_0:
-        case VMCS_CR3_TGT_VAL_1:
-        case VMCS_CR3_TGT_VAL_2:
-        case VMCS_CR3_TGT_VAL_3:
-        case VMCS_EXIT_QUAL:
-        case VMCS_IO_RCX:
-        case VMCS_IO_RSI:
-        case VMCS_IO_RDI:
-        case VMCS_IO_RIP:
-        case VMCS_GUEST_LINEAR_ADDR:
-        case VMCS_GUEST_CR0:
-        case VMCS_GUEST_CR3:
-        case VMCS_GUEST_CR4:
-        case VMCS_GUEST_ES_BASE:
-        case VMCS_GUEST_CS_BASE:
-        case VMCS_GUEST_SS_BASE:
-        case VMCS_GUEST_DS_BASE:
-        case VMCS_GUEST_FS_BASE:
-        case VMCS_GUEST_GS_BASE:
-        case VMCS_GUEST_LDTR_BASE:
-        case VMCS_GUEST_TR_BASE:
-        case VMCS_GUEST_GDTR_BASE:
-        case VMCS_GUEST_IDTR_BASE:
-        case VMCS_GUEST_DR7:
-        case VMCS_GUEST_RSP:
-        case VMCS_GUEST_RIP:
-        case VMCS_GUEST_RFLAGS:
-        case VMCS_GUEST_PENDING_DBG_EXCP:
-        case VMCS_GUEST_SYSENTER_ESP:
-        case VMCS_GUEST_SYSENTER_EIP:
-        case VMCS_HOST_CR0:
-        case VMCS_HOST_CR3:
-        case VMCS_HOST_CR4:
-        case VMCS_HOST_FS_BASE:
-        case VMCS_HOST_GS_BASE:
-        case VMCS_HOST_TR_BASE:
-        case VMCS_HOST_GDTR_BASE:
-        case VMCS_HOST_IDTR_BASE:
-        case VMCS_HOST_SYSENTER_ESP:
-        case VMCS_HOST_SYSENTER_EIP:
-        case VMCS_HOST_RSP:
-        case VMCS_HOST_RIP:
-       case VMCS_GUEST_EFER:
+       case 3:
             return sizeof(addr_t);
-
         default:
            PrintError("Invalid VMCS field: 0x%x\n", field);
             return -1;
index 1ef5bde..cb38aab 100644 (file)
@@ -183,14 +183,13 @@ v3_cpu_arch_t v3_get_cpu_type(int cpu_id) {
 struct v3_vm_info * v3_create_vm(void * cfg, void * priv_data, char * name) {
     struct v3_vm_info * vm = v3_config_guest(cfg, priv_data);
 
-    V3_Print("CORE 0 RIP=%p\n", (void *)(addr_t)(vm->cores[0].rip));
-
-
     if (vm == NULL) {
        PrintError("Could not configure guest\n");
        return NULL;
     }
 
+    V3_Print("CORE 0 RIP=%p\n", (void *)(addr_t)(vm->cores[0].rip));
+
     if (name == NULL) {
        name = "[V3_VM]";
     } else if (strlen(name) >= 128) {
index 2313abe..4326788 100644 (file)
@@ -34,6 +34,7 @@
 #include <palacios/vmx_io.h>
 #include <palacios/vmx_msr.h>
 
+#include <palacios/vmx_hw_info.h>
 
 #ifndef CONFIG_DEBUG_VMX
 #undef PrintDebug
 #endif
 
 
-static addr_t host_vmcs_ptrs[CONFIG_MAX_CPUS] = { [0 ... CONFIG_MAX_CPUS - 1] = 0};
+/* These fields contain the hardware feature sets supported by the local CPU */
+static struct vmx_hw_info hw_info;
+
+
 static addr_t active_vmcs_ptrs[CONFIG_MAX_CPUS] = { [0 ... CONFIG_MAX_CPUS - 1] = 0};
+static addr_t host_vmcs_ptrs[CONFIG_MAX_CPUS] = { [0 ... CONFIG_MAX_CPUS - 1] = 0};
 
 extern int v3_vmx_launch(struct v3_gprs * vm_regs, struct guest_info * info, struct v3_ctrl_regs * ctrl_regs);
 extern int v3_vmx_resume(struct v3_gprs * vm_regs, struct guest_info * info, struct v3_ctrl_regs * ctrl_regs);
@@ -76,7 +81,6 @@ static int inline check_vmcs_read(vmcs_field_t field, void * val) {
 
 
 static addr_t allocate_vmcs() {
-    reg_ex_t msr;
     struct vmcs_data * vmcs_page = NULL;
 
     PrintDebug("Allocating page\n");
@@ -84,10 +88,8 @@ static addr_t allocate_vmcs() {
     vmcs_page = (struct vmcs_data *)V3_VAddr(V3_AllocPages(1));
     memset(vmcs_page, 0, 4096);
 
-    v3_get_msr(VMX_BASIC_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
-    
-    vmcs_page->revision = ((struct vmx_basic_msr*)&msr)->revision;
-    PrintDebug("VMX Revision: 0x%x\n",vmcs_page->revision);
+    vmcs_page->revision = hw_info.basic_info.revision;
+    PrintDebug("VMX Revision: 0x%x\n", vmcs_page->revision);
 
     return (addr_t)V3_PAddr((void *)vmcs_page);
 }
@@ -815,6 +817,12 @@ int v3_start_vmx_guest(struct guest_info * info) {
 }
 
 
+
+
+#define VMX_FEATURE_CONTROL_MSR     0x0000003a
+#define CPUID_VMX_FEATURES 0x00000005  /* LOCK and VMXON */
+#define CPUID_1_ECX_VTXFLAG 0x00000020
+
 int v3_is_vmx_capable() {
     v3_msr_t feature_msr;
     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
@@ -828,7 +836,7 @@ int v3_is_vmx_capable() {
        
         PrintDebug("MSRREGlow: 0x%.8x\n", feature_msr.lo);
 
-        if ((feature_msr.lo & FEATURE_CONTROL_VALID) != FEATURE_CONTROL_VALID) {
+        if ((feature_msr.lo & CPUID_VMX_FEATURES) != CPUID_VMX_FEATURES) {
             PrintDebug("VMX is locked -- enable in the BIOS\n");
             return 0;
         }
@@ -841,88 +849,23 @@ int v3_is_vmx_capable() {
     return 1;
 }
 
-static int has_vmx_nested_paging() {
-    /* We assume that both EPT and unrestricted guest mode (Intel's Virtual Real Mode) 
-     * are mutually assured. i.e. We have either both or neither.
-     */
 
-    
 
-    return 0;
-}
 
 
 
 void v3_init_vmx_cpu(int cpu_id) {
     extern v3_cpu_arch_t v3_cpu_types[];
-    struct v3_msr tmp_msr;
-    uint64_t ret = 0;
-
-    v3_get_msr(VMX_CR4_FIXED0_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
 
-#ifdef __V3_64BIT__
-    __asm__ __volatile__ (
-                         "movq %%cr4, %%rbx;"
-                         "orq  $0x00002000, %%rbx;"
-                         "movq %%rbx, %0;"
-                         : "=m"(ret) 
-                         :
-                         : "%rbx"
-                         );
-
-    if ((~ret & tmp_msr.value) == 0) {
-        __asm__ __volatile__ (
-                             "movq %0, %%cr4;"
-                             :
-                             : "q"(ret)
-                             );
-    } else {
-        PrintError("Invalid CR4 Settings!\n");
-        return;
-    }
-
-    __asm__ __volatile__ (
-                         "movq %%cr0, %%rbx; "
-                         "orq  $0x00000020,%%rbx; "
-                         "movq %%rbx, %%cr0;"
-                         :
-                         :
-                         : "%rbx"
-                         );
-#elif __V3_32BIT__
-    __asm__ __volatile__ (
-                         "movl %%cr4, %%ecx;"
-                         "orl  $0x00002000, %%ecx;"
-                         "movl %%ecx, %0;"
-                         : "=m"(ret) 
-                         :
-                         : "%ecx"
-                         );
-
-    if ((~ret & tmp_msr.value) == 0) {
-        __asm__ __volatile__ (
-                             "movl %0, %%cr4;"
-                             :
-                             : "q"(ret)
-                             );
-    } else {
-        PrintError("Invalid CR4 Settings!\n");
-        return;
+    if (cpu_id == 0) {
+       if (v3_init_vmx_hw(&hw_info) == -1) {
+           PrintError("Could not initialize VMX hardware features on cpu %d\n", cpu_id);
+           return;
+       }
     }
 
-    __asm__ __volatile__ (
-                         "movl %%cr0, %%ecx; "
-                         "orl  $0x00000020,%%ecx; "
-                         "movl %%ecx, %%cr0;"
-                         :
-                         :
-                         : "%ecx"
-                         );
-
-#endif
 
-    //
-    // Should check and return Error here.... 
+    enable_vmx();
 
 
     // Setup VMXON Region
@@ -930,7 +873,7 @@ void v3_init_vmx_cpu(int cpu_id) {
 
     PrintDebug("VMXON pointer: 0x%p\n", (void *)host_vmcs_ptrs[cpu_id]);
 
-    if (v3_enable_vmx(host_vmcs_ptrs[cpu_id]) == VMX_SUCCESS) {
+    if (vmx_on(host_vmcs_ptrs[cpu_id]) == VMX_SUCCESS) {
         PrintDebug("VMX Enabled\n");
     } else {
         PrintError("VMX initialization failure\n");
@@ -938,11 +881,8 @@ void v3_init_vmx_cpu(int cpu_id) {
     }
     
 
-    if (has_vmx_nested_paging() == 1) {
-        v3_cpu_types[cpu_id] = V3_VMX_EPT_CPU;
-    } else {
-        v3_cpu_types[cpu_id] = V3_VMX_CPU;
-    }
+    v3_cpu_types[cpu_id] = V3_VMX_CPU;
+
 
 }
 
diff --git a/palacios/src/palacios/vmx_hw_info.c b/palacios/src/palacios/vmx_hw_info.c
new file mode 100644 (file)
index 0000000..90b055f
--- /dev/null
@@ -0,0 +1,62 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vmm_lowlevel.h>
+#include <palacios/vmx_hw_info.h>
+
+
+// Intel VMX Feature MSRs
+
+#define VMX_BASIC_MSR               0x00000480
+#define VMX_PINBASED_CTLS_MSR       0x00000481
+#define VMX_PROCBASED_CTLS_MSR      0x00000482
+#define VMX_EXIT_CTLS_MSR           0x00000483
+#define VMX_ENTRY_CTLS_MSR          0x00000484
+#define VMX_MISC_MSR                0x00000485
+#define VMX_CR0_FIXED0_MSR          0x00000486
+#define VMX_CR0_FIXED1_MSR          0x00000487
+#define VMX_CR4_FIXED0_MSR          0x00000488
+#define VMX_CR4_FIXED1_MSR          0x00000489
+#define VMX_VMCS_ENUM_MSR           0x0000048A
+
+
+
+
+
+
+
+int v3_init_vmx_hw(struct vmx_hw_info * hw_info) {
+    //  extern v3_cpu_arch_t v3_cpu_types[];
+
+    memset(hw_info, 0, sizeof(struct vmx_hw_info));
+
+    v3_get_msr(VMX_BASIC_MSR, &(hw_info->basic_info.hi), &(hw_info->basic_info.lo));
+    
+
+
+    /*
+    if (has_vmx_nested_paging() == 1) {
+        v3_cpu_types[cpu_id] = V3_VMX_EPT_CPU;
+    } else {
+        v3_cpu_types[cpu_id] = V3_VMX_CPU;
+    }
+    */
+    return 0;
+}