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.


added hardware info for VMX
Jack Lange [Thu, 21 Apr 2011 23:57:18 +0000 (18:57 -0500)]
palacios/include/palacios/vmx_hw_info.h
palacios/src/palacios/vmx_hw_info.c

index baade9c..e130545 100644 (file)
@@ -24,6 +24,7 @@
 #ifdef __V3VEE__
 
 
+
 #define VMX_BASIC_MSR               0x00000480
 #define VMX_PINBASED_CTLS_MSR       0x00000481
 #define VMX_PROCBASED_CTLS_MSR      0x00000482
 #define VMX_CR4_FIXED0_MSR          0x00000488
 #define VMX_CR4_FIXED1_MSR          0x00000489
 #define VMX_VMCS_ENUM_MSR           0x0000048A
-
+#define VMX_PROCBASED_CTLS2_MSR     0x0000048B
+#define VMX_EPT_VPID_CAP_MSR        0x0000048C
+#define VMX_TRUE_PINBASED_CTLS_MSR  0x0000048D
+#define VMX_TRUE_PROCBASED_CTLS_MSR 0x0000048E
+#define VMX_TRUE_EXIT_CTLS_MSR      0x0000048F
+#define VMX_TRUE_ENTRY_CTLS_MSR     0x00000490
 
 
 
 struct vmx_basic_msr {
     union {
-       uint32_t lo;
-       uint32_t hi;
        struct {
-           uint32_t revision;
+           uint32_t lo;
+           uint32_t hi;
+       } __attribute__((packed));
+
+       struct {    uint32_t revision;
            uint32_t regionSize   : 13;
-           uint8_t rsvd1         : 4; /* Always 0 */
+           uint8_t rsvd1         : 3; /* Always 0 */
            uint8_t physWidth     : 1; /* VMCS address field widths 
                                          (1=32bits, 0=natural width) */
-           uint8_t smm           : 1; // Always 1
+           uint8_t smm           : 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" */
@@ -59,18 +67,99 @@ struct vmx_basic_msr {
 }  __attribute__((packed));
 
 
+struct vmx_misc_msr {
+    union {
+       struct {
+           uint32_t lo;
+           uint32_t hi;
+       } __attribute__((packed));
+
+       struct {
+           uint8_t tsc_multiple       : 5; /* Bit position in TSC field that drives vmx timer step */
+           uint8_t exits_store_LMA    : 1;
+           uint8_t can_halt           : 1;
+           uint8_t can_shtdown        : 1;
+           uint8_t can_wait_for_sipi  : 1;
+           uint8_t rsvd1              : 7;
+           uint16_t num_cr3_targets   : 9;
+           uint8_t max_msr_cache_size : 3; /* (512 * (max_msr_cache_size + 1)) == max msr load/store list size */
+           uint8_t SMM_ctrl_avail     : 1;
+           uint8_t rsvd2              : 3; 
+           uint32_t MSEG_rev_id;
+       }  __attribute__((packed));
+    }  __attribute__((packed));
+} __attribute__((packed));
+
+
+struct vmx_ept_msr {
+    union {
+       struct {
+           uint32_t lo;
+           uint32_t hi;
+       } __attribute__((packed));
+
+       struct {
+           uint8_t exec_only_ok             : 1;
+           uint8_t rsvd1                    : 5;
+           uint8_t pg_walk_len4             : 1; /* support for a page walk of length 4 */
+           uint8_t rsvd2                    : 1;
+           uint8_t ept_uc_ok                : 1; /* EPT page tables can be uncacheable */
+           uint8_t rsvd3                    : 5;
+           uint8_t ept_wb_ok                : 1; /* EPT page tables can be writeback */
+           uint8_t rsvd4                    : 1;
+           uint8_t ept_2MB_ok               : 1; /* 2MB EPT pages supported */
+           uint8_t ept_1GB_ok               : 1; /* 1GB EPT pages supported */
+           uint8_t rsvd5                    : 2;
+           uint8_t INVEPT_avail             : 1; /* INVEPT instruction is available */
+           uint8_t rsvd6                    : 4;
+           uint8_t INVEPT_single_ctx_avail  : 1;
+           uint8_t INVEPT_all_ctx_avail     : 1;
+           uint8_t rsvd7                    : 5;
+           uint8_t INVVPID_avail            : 1;
+           uint8_t rsvd8                    : 7;
+           uint8_t INVVPID_1addr_avail      : 1;
+           uint8_t INVVPID_single_ctx_avail : 1;
+           uint8_t INVVPID_all_ctx_avail    : 1;
+           uint8_t INVVPID_single_ctx_w_glbls_avail : 1;
+           uint32_t rsvd9                   : 20;
+       }  __attribute__((packed));
+    }  __attribute__((packed));
+}__attribute__((packed));
+
+
+struct vmx_ctrl_field {
+    uint32_t def_val;
+    uint32_t req_val;  /* Required values: field_val & req_mask == req_val */ 
+    uint32_t req_mask; /* If a mask bit is set it's value is restricted (i.e. the VMM cannot change it) */
+};
+
+
+struct vmx_cr_field {
+    uint64_t def_val;
+    uint64_t req_val;  /* Required values: field_val & req_mask == req_val */ 
+    uint64_t req_mask; /* If a mask bit is set it's value is restricted (i.e. the VMM cannot change it) */
+};
+
 
 
 
 struct vmx_hw_info {
     struct vmx_basic_msr basic_info;
-    
+    struct vmx_misc_msr misc_info;
+    struct vmx_ept_msr ept_info;
 
+    struct vmx_ctrl_field pin_ctrls;
+    struct vmx_ctrl_field proc_ctrls;
+    struct vmx_ctrl_field exit_ctrls;
+    struct vmx_ctrl_field entry_ctrls;
+    struct vmx_ctrl_field proc_ctrls_2;
 
+    struct vmx_cr_field cr0;
+    struct vmx_cr_field cr4;
 };
 
 
-int v3_init_vmx_hw();
+int v3_init_vmx_hw(struct vmx_hw_info * hw_info);
 
 
 
index 90b055f..3220e52 100644 (file)
 #include <palacios/vmm.h>
 #include <palacios/vmm_lowlevel.h>
 #include <palacios/vmx_hw_info.h>
-
+#include <palacios/vmm_msr.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
 
 
+static int get_ex_ctrl_caps(struct vmx_hw_info * hw_info, struct vmx_ctrl_field * field, 
+                 uint32_t old_msr, uint32_t true_msr) {
+    uint32_t old_0;  /* Bit is 1 => MB1 */
+    uint32_t old_1;  /* Bit is 0 => MBZ */
+    uint32_t true_0; /* Bit is 1 => MB1 */
+    uint32_t true_1; /* Bit is 0 => MBZ */
+
+    v3_get_msr(old_msr, &old_1, &old_0);
+    field->def_val = old_0;
+
+    if (hw_info->basic_info.def1_maybe_0) {
+       v3_get_msr(true_msr, &true_1, &true_0);
+    } else {
+       true_0 = old_0;
+       true_1 = old_1;
+    }
+    
+    field->req_val = true_0;
+    field->req_mask = ~(true_1 ^ true_0);
+
+    return 0;
+}
+
+
+static int get_ctrl_caps(struct vmx_ctrl_field * field, uint32_t msr) {
+    uint32_t mbz = 0; /* Bit is 0 => MBZ */
+    uint32_t mb1 = 0; /* Bit is 1 => MB1 */
+    
+    v3_get_msr(msr, &mbz, &mb1);
+    
+    field->def_val = mb1;
+    field->req_val = mb1;
+    field->req_mask = ~(mbz ^ mb1);
+
+    return 0;
+}
+
+
+
+static int get_cr_fields(struct vmx_cr_field * field, uint32_t fixed_1_msr, uint32_t fixed_0_msr) {
+    struct v3_msr mbz; /* Bit is 0 => MBZ */
+    struct v3_msr mb1; /* Bit is 0 => MBZ */
+
+    v3_get_msr(fixed_1_msr, &(mbz.hi), &(mbz.lo));
+    v3_get_msr(fixed_0_msr, &(mb1.hi), &(mb1.lo));
+     
+    field->def_val = mb1.value;
+    field->req_val = mb1.value;
+    field->req_mask = ~(mbz.value ^ mb1.value);
+
+    return 0;
+}
 
 
 
@@ -48,15 +89,25 @@ int v3_init_vmx_hw(struct vmx_hw_info * hw_info) {
     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));
-    
+    v3_get_msr(VMX_MISC_MSR, &(hw_info->misc_info.hi), &(hw_info->misc_info.lo));
+    v3_get_msr(VMX_EPT_VPID_CAP_MSR, &(hw_info->ept_info.hi), &(hw_info->ept_info.lo));
 
+    PrintError("BASIC_MSR: Lo: %x, Hi: %x\n", hw_info->basic_info.lo, hw_info->basic_info.hi);
 
-    /*
-    if (has_vmx_nested_paging() == 1) {
-        v3_cpu_types[cpu_id] = V3_VMX_EPT_CPU;
-    } else {
-        v3_cpu_types[cpu_id] = V3_VMX_CPU;
+    get_ex_ctrl_caps(hw_info, &(hw_info->pin_ctrls), VMX_PINBASED_CTLS_MSR, VMX_TRUE_PINBASED_CTLS_MSR);
+    get_ex_ctrl_caps(hw_info, &(hw_info->proc_ctrls), VMX_PROCBASED_CTLS_MSR, VMX_TRUE_PROCBASED_CTLS_MSR);
+    get_ex_ctrl_caps(hw_info, &(hw_info->exit_ctrls), VMX_EXIT_CTLS_MSR, VMX_TRUE_EXIT_CTLS_MSR);
+    get_ex_ctrl_caps(hw_info, &(hw_info->entry_ctrls), VMX_ENTRY_CTLS_MSR, VMX_TRUE_ENTRY_CTLS_MSR);
+
+    /* Get secondary PROCBASED controls if secondary controls are available (optional or required) */
+    /* Intel Manual 3B. Sect. G.3.3 */
+    if ( ((hw_info->proc_ctrls.req_mask & 0x80000000) == 0) || 
+        ((hw_info->proc_ctrls.req_val & 0x80000000) == 1) ) {
+       get_ctrl_caps(&(hw_info->proc_ctrls_2), VMX_PROCBASED_CTLS2_MSR);
     }
-    */
+    
+    get_cr_fields(&(hw_info->cr0), VMX_CR0_FIXED1_MSR, VMX_CR0_FIXED0_MSR);
+    get_cr_fields(&(hw_info->cr4), VMX_CR4_FIXED1_MSR, VMX_CR4_FIXED0_MSR);
+
     return 0;
 }