2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2011, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_lowlevel.h>
22 #include <palacios/vmx_hw_info.h>
23 #include <palacios/vmm_msr.h>
25 // Intel VMX Feature MSRs
28 uint32_t v3_vmx_get_ctrl_features(struct vmx_ctrl_field * fields) {
29 // features are available if they are hardwired to 1, or the mask is 0 (they can be changed)
30 uint32_t features = 0;
32 features = fields->req_val;
33 features |= ~(fields->req_mask);
39 static int get_ex_ctrl_caps(struct vmx_hw_info * hw_info, struct vmx_ctrl_field * field,
40 uint32_t old_msr, uint32_t true_msr) {
41 uint32_t old_0; /* Bit is 1 => MB1 */
42 uint32_t old_1; /* Bit is 0 => MBZ */
43 uint32_t true_0; /* Bit is 1 => MB1 */
44 uint32_t true_1; /* Bit is 0 => MBZ */
46 v3_get_msr(old_msr, &old_1, &old_0);
47 field->def_val = old_0;
49 if (hw_info->basic_info.def1_maybe_0) {
50 v3_get_msr(true_msr, &true_1, &true_0);
56 field->req_val = true_0;
57 field->req_mask = ~(true_1 ^ true_0);
63 static int get_ctrl_caps(struct vmx_ctrl_field * field, uint32_t msr) {
64 uint32_t mbz = 0; /* Bit is 0 => MBZ */
65 uint32_t mb1 = 0; /* Bit is 1 => MB1 */
67 v3_get_msr(msr, &mbz, &mb1);
71 field->req_mask = ~(mbz ^ mb1);
78 static int get_cr_fields(struct vmx_cr_field * field, uint32_t fixed_1_msr, uint32_t fixed_0_msr) {
79 struct v3_msr mbz; /* Bit is 0 => MBZ */
80 struct v3_msr mb1; /* Bit is 0 => MBZ */
82 v3_get_msr(fixed_1_msr, &(mbz.hi), &(mbz.lo));
83 v3_get_msr(fixed_0_msr, &(mb1.hi), &(mb1.lo));
85 field->def_val = mb1.value;
86 field->req_val = mb1.value;
87 field->req_mask = ~(mbz.value ^ mb1.value);
96 int v3_init_vmx_hw(struct vmx_hw_info * hw_info) {
97 // extern v3_cpu_arch_t v3_cpu_types[];
99 memset(hw_info, 0, sizeof(struct vmx_hw_info));
101 v3_get_msr(VMX_BASIC_MSR, &(hw_info->basic_info.hi), &(hw_info->basic_info.lo));
102 v3_get_msr(VMX_MISC_MSR, &(hw_info->misc_info.hi), &(hw_info->misc_info.lo));
105 PrintError(VM_NONE, VCORE_NONE, "BASIC_MSR: Lo: %x, Hi: %x\n", hw_info->basic_info.lo, hw_info->basic_info.hi);
107 get_ex_ctrl_caps(hw_info, &(hw_info->pin_ctrls), VMX_PINBASED_CTLS_MSR, VMX_TRUE_PINBASED_CTLS_MSR);
108 get_ex_ctrl_caps(hw_info, &(hw_info->proc_ctrls), VMX_PROCBASED_CTLS_MSR, VMX_TRUE_PROCBASED_CTLS_MSR);
109 get_ex_ctrl_caps(hw_info, &(hw_info->exit_ctrls), VMX_EXIT_CTLS_MSR, VMX_TRUE_EXIT_CTLS_MSR);
110 get_ex_ctrl_caps(hw_info, &(hw_info->entry_ctrls), VMX_ENTRY_CTLS_MSR, VMX_TRUE_ENTRY_CTLS_MSR);
113 /* Get secondary PROCBASED controls if secondary controls are available (optional or required) */
114 /* Intel Manual 3B. Sect. G.3.3 */
115 if ( ((hw_info->proc_ctrls.req_mask & 0x80000000) == 0) ||
116 ((hw_info->proc_ctrls.req_val & 0x80000000) == 1) ) {
118 get_ctrl_caps(&(hw_info->sec_proc_ctrls), VMX_PROCBASED_CTLS2_MSR);
120 /* Get EPT data only if available - Intel 3B, G.10 */
121 /* EPT is available if processor has secondary controls (already tested) */
122 /* and if procbased_ctls2[33]==1 or procbased_ctrls2[37]==1 */
126 v3_get_msr(VMX_PROCBASED_CTLS2_MSR,&(proc2.hi),&(proc2.lo));
128 if ( (proc2.hi & 0x2) || (proc2.hi & 0x20) ) {
129 v3_get_msr(VMX_EPT_VPID_CAP_MSR, &(hw_info->ept_info.hi), &(hw_info->ept_info.lo));
133 get_cr_fields(&(hw_info->cr0), VMX_CR0_FIXED1_MSR, VMX_CR0_FIXED0_MSR);
134 get_cr_fields(&(hw_info->cr4), VMX_CR4_FIXED1_MSR, VMX_CR4_FIXED0_MSR);