From: Jack Lange Date: Thu, 21 Apr 2011 21:32:50 +0000 (-0500) Subject: vmx cleanup X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=15f1869089d6d3c4dc745ac2673e3cc0dd315962;p=palacios.git vmx cleanup --- diff --git a/palacios/include/palacios/vmcs.h b/palacios/include/palacios/vmcs.h index 9129d1b..c80a23c 100644 --- a/palacios/include/palacios/vmcs.h +++ b/palacios/include/palacios/vmcs.h @@ -39,6 +39,15 @@ +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, diff --git a/palacios/include/palacios/vmx.h b/palacios/include/palacios/vmx.h index fd5e6ce..7a0a039 100644 --- a/palacios/include/palacios/vmx.h +++ b/palacios/include/palacios/vmx.h @@ -30,31 +30,14 @@ #include #include -// 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 index 0000000..baade9c --- /dev/null +++ b/palacios/include/palacios/vmx_hw_info.h @@ -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 + * Copyright (c) 2011, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * 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 diff --git a/palacios/include/palacios/vmx_lowlevel.h b/palacios/include/palacios/vmx_lowlevel.h index 6db9f17..ce6a440 100644 --- a/palacios/include/palacios/vmx_lowlevel.h +++ b/palacios/include/palacios/vmx_lowlevel.h @@ -57,24 +57,7 @@ -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 diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index dd1b637..5b4a359 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -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 diff --git a/palacios/src/palacios/vmcs.c b/palacios/src/palacios/vmcs.c index 0b874fd..f8fe322 100644 --- a/palacios/src/palacios/vmcs.c +++ b/palacios/src/palacios/vmcs.c @@ -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; diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 1ef5bde..cb38aab 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -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) { diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 2313abe..4326788 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -34,6 +34,7 @@ #include #include +#include #ifndef CONFIG_DEBUG_VMX #undef PrintDebug @@ -41,8 +42,12 @@ #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 index 0000000..90b055f --- /dev/null +++ b/palacios/src/palacios/vmx_hw_info.c @@ -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 + * Copyright (c) 2011, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include +#include + + +// 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; +}