From: Andy Gocke Date: Thu, 16 Jul 2009 01:58:49 +0000 (-0500) Subject: VMX patch series, compilation enabled X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=1f5b9287e61b8a4164f81e52dccf3ddd59a891f8 VMX patch series, compilation enabled --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index c6c7186..59dd8d9 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -307,9 +307,10 @@ VMM_OBJS := \ palacios/vmm_ringbuffer.o \ palacios/vmm_hypercall.o \ palacios/vmm_lock.o \ + palacios/vmx.o \ + palacios/vmcs.o \ $(OBJ_FILES) -# vmx.c vmcs_gen.c vmcs.c # Extra C flags for the VMM objects $(VMM_OBJS) :: EXTRA_CFLAGS = \ diff --git a/palacios/include/palacios/vmcs.h b/palacios/include/palacios/vmcs.h index 392ddc3..2563c78 100644 --- a/palacios/include/palacios/vmcs.h +++ b/palacios/include/palacios/vmcs.h @@ -27,6 +27,34 @@ #include + /* 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, @@ -171,38 +199,10 @@ typedef enum { 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); + } vmcs_field_t; + +int v3_vmcs_get_field_len(vmcs_field_t field); +char* v3_vmcs_get_field_name(vmcs_field_t field); @@ -306,137 +306,12 @@ struct vmcs_interrupt_state { uint32_t rsvd1 : 28; } __attribute__((packed)); -struct vmcs_pending_debug { - uint32_t B0 : 1; - uint32_t B1 : 1; - uint32_t B2 : 1; - uint32_t B3 : 1; - uint32_t rsvd1 : 8; - uint32_t break_enabled : 1; - uint32_t rsvd2 : 1; - uint32_t bs : 1; - uint32_t rsvd3 : 50; -} __attribute__((packed)); - - -struct VMCSExecCtrlFields { - uint32_t pinCtrls ; // Table 20-5, Vol 3B. (pg. 20-10) - uint32_t procCtrls ; // Table 20-6, Vol 3B. (pg. 20-11) - uint32_t execBitmap ; - uint32_t pageFaultErrorMask ; - uint32_t pageFaultErrorMatch ; - uint32_t ioBitmapA ; - uint32_t ioBitmapB ; - uint64_t tscOffset ; - uint32_t cr0GuestHostMask ; // Should be 64 bits? - uint32_t cr0ReadShadow ; // Should be 64 bits? - uint32_t cr4GuestHostMask ; // Should be 64 bits? - uint32_t cr4ReadShadow ; // Should be 64 bits? - uint32_t cr3TargetValue0 ; // should be 64 bits? - uint32_t cr3TargetValue1 ; // should be 64 bits? - uint32_t cr3TargetValue2 ; // should be 64 bits? - uint32_t cr3TargetValue3 ; // should be 64 bits? - uint32_t cr3TargetCount ; - - - - /* these fields enabled if "use TPR shadow"==1 */ - /* may not need them */ - uint64_t virtApicPageAddr ; - // uint32_t virtApicPageAddrHigh - uint32_t tprThreshold ; - /**/ - - uint64_t MSRBitmapsBaseAddr; - - uint64_t vmcsExecPtr ; -}; - -int CopyOutVMCSExecCtrlFields(struct VMCSExecCtrlFields *p); -int CopyInVMCSExecCtrlFields(struct VMCSExecCtrlFields *p); - - -struct VMCSExitCtrlFields { - uint32_t exitCtrls ; // Table 20-7, Vol. 3B (pg. 20-16) - uint32_t msrStoreCount ; - uint64_t msrStoreAddr ; - uint32_t msrLoadCount ; - uint64_t msrLoadAddr ; -}; - -int CopyOutVMCSExitCtrlFields(struct VMCSExitCtrlFields *p); -int CopyInVMCSExitCtrlFields(struct VMCSExitCtrlFields *p); - - - -struct VMCSEntryCtrlFields { - uint32_t entryCtrls ; // Table 20-9, Vol. 3B (pg. 20-18) - uint32_t msrLoadCount ; - uint64_t msrLoadAddr ; - uint32_t intInfo ; // Table 20-10, Vol. 3B (pg. 20-19) - uint32_t exceptionErrorCode ; - uint32_t instrLength ; -}; - - -int CopyOutVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p); -int CopyInVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p); - - -struct VMCSExitInfoFields { - uint32_t reason; // Table 20-11, Vol. 3B (pg. 20-20) - uint32_t qualification ; // Should be 64 bits? - uint32_t intInfo ; - uint32_t intErrorCode ; - uint32_t idtVectorInfo ; - uint32_t idtVectorErrorCode ; - uint32_t instrLength ; - uint64_t guestLinearAddr ; // Should be 64 bits? - uint32_t instrInfo ; - uint64_t ioRCX ; // Should be 64 bits? - uint64_t ioRSI ; // Should be 64 bits? - uint64_t ioRDI ; // Should be 64 bits? - uint64_t ioRIP ; // Should be 64 bits? - uint32_t instrErrorField ; - -}; - - -int CopyOutVMCSExitInfoFields(struct VMCSExitInfoFields *p); - - - -typedef struct vmcs_data { +struct vmcs_data { uint32_t revision ; uint32_t abort ; -} __attribute__((packed)) vmcs_data_t; - - -int CopyOutVMCSData(struct VMCSData *p); -int CopyInVMCSData(struct VMCSData *p); - -struct VMXRegs { - uint32_t edi; - uint32_t esi; - uint32_t ebp; - uint32_t esp; - uint32_t ebx; - uint32_t edx; - uint32_t ecx; - uint32_t eax; -}; - -void PrintTrace_VMX_Regs(struct VMXRegs *regs); -void PrintTrace_VMCSData(struct VMCSData * vmcs); -void PrintTrace_VMCSGuestStateArea(struct VMCSGuestStateArea * guestState); -void PrintTrace_VMCSHostStateArea(struct VMCSHostStateArea * hostState); -void PrintTrace_VMCSExecCtrlFields(struct VMCSExecCtrlFields * execCtrls); -void PrintTrace_VMCSExitCtrlFields(struct VMCSExitCtrlFields * exitCtrls); -void PrintTrace_VMCSEntryCtrlFields(struct VMCSEntryCtrlFields * entryCtrls); -void PrintTrace_VMCSExitInfoFields(struct VMCSExitInfoFields * exitInfo); -void PrintTrace_VMCSSegment(char * segname, struct VMCSSegment * seg, int abbr); +} __attribute__((packed)); //uint_t VMCSRead(uint_t tag, void * val); diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 065021e..42c98c5 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -221,7 +221,7 @@ // Maybe make this a define.... -typedef enum v3_cpu_arch {V3_INVALID_CPU, V3_SVM_CPU, V3_SVM_REV3_CPU, V3_VMX_CPU} v3_cpu_arch_t; +typedef enum v3_cpu_arch {V3_INVALID_CPU, V3_SVM_CPU, V3_SVM_REV3_CPU, V3_VMX_CPU, V3_VMX_EPT_CPU} v3_cpu_arch_t; v3_cpu_mode_t v3_get_host_cpu_mode(); diff --git a/palacios/include/palacios/vmx.h b/palacios/include/palacios/vmx.h index 7d02053..bdf5bb8 100644 --- a/palacios/include/palacios/vmx.h +++ b/palacios/include/palacios/vmx.h @@ -28,6 +28,7 @@ #include #include +#include // Intel VMX Specific MSRs #define VMX_FEATURE_CONTROL_MSR 0x0000003a @@ -76,7 +77,7 @@ typedef enum { struct vmx_data { vmx_state_t state; - struct vmcs_data vmcs; + struct vmcs_data* vmcs; }; @@ -94,15 +95,9 @@ struct Instruction { -int is_vmx_capable(); +int v3_is_vmx_capable(); +void v3_init_vmx(struct v3_ctrl_ops* vm_ops); -VmxOnRegion * Init_VMX(); -VmxOnRegion * CreateVmxOnRegion(); - -int VMLaunch(struct VMDescriptor *vm); - - -int Do_VMM(struct VMXRegs regs); #endif // ! __V3VEE__ diff --git a/palacios/include/palacios/vmx_lowlevel.h b/palacios/include/palacios/vmx_lowlevel.h index fe8cf44..b4a2e8d 100644 --- a/palacios/include/palacios/vmx_lowlevel.h +++ b/palacios/include/palacios/vmx_lowlevel.h @@ -138,7 +138,7 @@ static inline int vmcs_store(struct vmcs_data* vmcs_ptr) { uint64_t vmcs_ptr_64 = (uint64_t)vmcs_ptr; __asm__ __volatile__ ( - VMPTRSRT_OPCODE + VMPTRST_OPCODE EAX_07_MODRM : : "a"(&vmcs_ptr_64) diff --git a/palacios/src/palacios/vmcs.c b/palacios/src/palacios/vmcs.c index 35dc5e1..cf130fc 100644 --- a/palacios/src/palacios/vmcs.c +++ b/palacios/src/palacios/vmcs.c @@ -18,6 +18,8 @@ */ #include +#include +#include @@ -27,7 +29,7 @@ // -static inline void print_vmcs_field(uint_t vmcs_index) { +static inline void print_vmcs_field(vmcs_field_t vmcs_index) { int len = v3_vmcs_get_field_len(vmcs_index); addr_t val; @@ -53,11 +55,11 @@ static inline void print_vmcs_segments() { - +/* void print_debug_vmcs_load_guest() { const int wordsize = sizeof(addr_t); uint64_t temp; - vmcs_segment tmp_seg; + struct vmcs_segment_access tmp_seg; PrintDebug("\n====== Loading Guest State ======\n"); PRINT_VMREAD("Guest CR0: %x\n", GUEST_CR0, wordsize); @@ -152,12 +154,12 @@ void print_vmcs_segment(char * name, vmcs_segment* seg) PrintDebug("\tBase Address: %x\n", seg->baseAddr); PrintDebug("\tLimit: %x\n", seg->limit); PrintDebug("\tAccess: %x\n", seg->access); -} +}*/ /* * Returns the field length in bytes */ -int vmcs_field_length(vmcs_field_t field) +int v3_vmcs_get_field_len(vmcs_field_t field) { switch(field) { @@ -306,35 +308,7 @@ int vmcs_field_length(vmcs_field_t field) 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__ + #ifdef __V3_64BIT__ return 8; #else return 4; @@ -344,9 +318,9 @@ int vmcs_field_length(vmcs_field_t field) } } -char* vmcs_field_name(vmcs_field_t field) +char* v3_vmcs_get_field_name(vmcs_field_t field) { - case(field) + switch(field) { case VMCS_GUEST_ES_SELECTOR: return "VMCS_GUEST_ES_SELECTOR"; @@ -610,160 +584,10 @@ char* vmcs_field_name(vmcs_field_t field) 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); - PrintTrace("HOST_CR3: %x\n", (uint_t)hostState->cr3); - PrintTrace("HOST_CR4: %x\n", (uint_t)hostState->cr4); - PrintTrace("HOST_RSP: %x\n", (uint_t)hostState->rsp); - PrintTrace("HOST_RIP: %x\n", (uint_t)hostState->rip); - PrintTrace("VMCS_HOST_CS_SELECTOR: %x\n", (uint_t)hostState->csSelector); - PrintTrace("VMCS_HOST_SS_SELECTOR: %x\n", (uint_t)hostState->ssSelector); - PrintTrace("VMCS_HOST_DS_SELECTOR: %x\n", (uint_t)hostState->dsSelector); - PrintTrace("VMCS_HOST_ES_SELECTOR: %x\n", (uint_t)hostState->esSelector); - PrintTrace("VMCS_HOST_FS_SELECTOR: %x\n", (uint_t)hostState->fsSelector); - PrintTrace("VMCS_HOST_GS_SELECTOR: %x\n", (uint_t)hostState->gsSelector); - PrintTrace("VMCS_HOST_TR_SELECTOR: %x\n", (uint_t)hostState->trSelector); - PrintTrace("HOST_FS_BASE: %x\n", (uint_t)hostState->fsBaseAddr); - PrintTrace("HOST_GS_BASE: %x\n", (uint_t)hostState->gsBaseAddr); - PrintTrace("HOST_TR_BASE: %x\n", (uint_t)hostState->trBaseAddr); - PrintTrace("HOST_GDTR_BASE: %x\n", (uint_t)hostState->gdtrBaseAddr); - PrintTrace("HOST_IDTR_BASE: %x\n", (uint_t)hostState->idtrBaseAddr); - PrintTrace("HOST_IA32_SYSENTER_CS: %x\n", (uint_t)hostState->sysenter_cs); - PrintTrace("HOST_IA32_SYSENTER_ESP: %x\n", (uint_t)hostState->sysenter_esp); - PrintTrace("HOST_IA32_SYSENTER_EIP: %x\n", (uint_t)hostState->sysenter_eip); -} - -void PrintTrace_VMCSExecCtrlFields(struct VMCSExecCtrlFields * execCtrls) { - PrintTrace("\n==> VM-Execution Controls:\n"); - PrintTrace("PIN_VM_EXEC_CTRLS: %x\n", (uint_t) execCtrls->pinCtrls); - PrintTrace("PROC_VM_EXEC_CTRLS: %x\n", (uint_t) execCtrls->procCtrls); - PrintTrace("EXCEPTION_BITMAP: %x\n", (uint_t) execCtrls->execBitmap); - PrintTrace("PAGE_FAULT_ERROR_MASK: %x\n", (uint_t) execCtrls->pageFaultErrorMask); - PrintTrace("PAGE_FAULT_ERROR_MATCH: %x\n", (uint_t) execCtrls->pageFaultErrorMatch); - PrintTrace("IO_BITMAP_A_ADDR: %x\n", (uint_t) execCtrls->ioBitmapA); - // PrintTrace("IO_BITMAP_A_ADDR_HIGH: %x\n", (uint_t) execCtrls->); - PrintTrace("IO_BITMAP_B_ADDR: %x\n", (uint_t) execCtrls->ioBitmapB); - // PrintTrace("IO_BITMAP_B_ADDR_HIGH: %x\n", (uint_t) execCtrls->); - PrintTrace("TSC_OFFSET: %x\n", (uint_t) execCtrls->tscOffset & 0xffffffff); - PrintTrace("TSC_OFFSET_HIGH: %x\n", (uint_t) (execCtrls->tscOffset >> 32) & 0xffffffff); - PrintTrace("CR0_GUEST_HOST_MASK: %x\n", (uint_t) execCtrls->cr0GuestHostMask); - PrintTrace("CR0_READ_SHADOW: %x\n", (uint_t) execCtrls->cr0ReadShadow); - PrintTrace("CR4_GUEST_HOST_MASK: %x\n", (uint_t) execCtrls->cr4GuestHostMask); - PrintTrace("CR4_READ_SHADOW: %x\n", (uint_t) execCtrls->cr4ReadShadow); - PrintTrace("CR3_TARGET_COUNT: %x\n", (uint_t) execCtrls->cr3TargetCount); - PrintTrace("CR3_TARGET_VALUE_0: %x\n", (uint_t) execCtrls->cr3TargetValue0); - PrintTrace("CR3_TARGET_VALUE_1: %x\n", (uint_t) execCtrls->cr3TargetValue1); - PrintTrace("CR3_TARGET_VALUE_2: %x\n", (uint_t) execCtrls->cr3TargetValue2); - PrintTrace("CR3_TARGET_VALUE_3: %x\n", (uint_t) execCtrls->cr3TargetValue3); - PrintTrace("VIRT_APIC_PAGE_ADDR: %x\n", (uint_t) execCtrls->virtApicPageAddr & 0xffffffff); - PrintTrace("VIRT_APIC_PAGE_ADDR_HIGH: %x\n", (uint_t) (execCtrls->virtApicPageAddr >> 32) & 0xffffffff); - PrintTrace("TPR_THRESHOLD: %x\n", (uint_t) execCtrls->tprThreshold); - PrintTrace("MSR_BITMAPS: %x\n", (uint_t) execCtrls->MSRBitmapsBaseAddr & 0xffffffff); - PrintTrace("MSR_BITMAPS_HIGH: %x\n", (uint_t) (execCtrls->MSRBitmapsBaseAddr >> 32) & 0xffffffff); - PrintTrace("VMCS_EXEC_PTR: %x\n", (uint_t) execCtrls->vmcsExecPtr & 0xffffffff); - PrintTrace("VMCS_EXEC_PTR_HIGH: %x\n", (uint_t) (execCtrls->vmcsExecPtr >> 32) & 0xffffffff); -} -void PrintTrace_VMCSExitCtrlFields(struct VMCSExitCtrlFields * exitCtrls) { - PrintTrace("\n==> VM Exit Controls\n"); - PrintTrace("VM_EXIT_CTRLS: %x\n", (uint_t) exitCtrls->exitCtrls); - PrintTrace("VM_EXIT_MSR_STORE_COUNT: %x\n", (uint_t) exitCtrls->msrStoreCount); - PrintTrace("VM_EXIT_MSR_STORE_ADDR: %x\n", (uint_t) exitCtrls->msrStoreAddr & 0xffffffff); - PrintTrace("VM_EXIT_MSR_STORE_ADDR_HIGH: %x\n", (uint_t) (exitCtrls->msrStoreAddr >> 32) & 0xffffffff); - PrintTrace("VM_EXIT_MSR_LOAD_COUNT: %x\n", (uint_t) exitCtrls->msrLoadCount); - PrintTrace("VM_EXIT_MSR_LOAD_ADDR: %x\n", (uint_t) exitCtrls->msrLoadAddr & 0xffffffff); - PrintTrace("VM_EXIT_MSR_LOAD_ADDR_HIGH: %x\n", (uint_t) (exitCtrls->msrLoadAddr >> 32) & 0xffffffff); -} - -void PrintTrace_VMCSEntryCtrlFields(struct VMCSEntryCtrlFields * entryCtrls) { - PrintTrace("\n==> VM Entry Controls\n"); - PrintTrace("VM_ENTRY_CTRLS: %x\n", (uint_t) entryCtrls->entryCtrls); - PrintTrace("VM_ENTRY_MSR_LOAD_COUNT: %x\n", (uint_t) entryCtrls->msrLoadCount); - PrintTrace("VM_ENTRY_MSR_LOAD_ADDR: %x\n", (uint_t) entryCtrls->msrLoadAddr & 0xffffffff); - PrintTrace("VM_ENTRY_MSR_LOAD_ADDR_HIGH: %x\n", (uint_t) (entryCtrls->msrLoadAddr >> 32) & 0xffffffff); - PrintTrace("VM_ENTRY_INT_INFO_FIELD: %x\n", (uint_t) entryCtrls->intInfo); - PrintTrace("VM_ENTRY_EXCEPTION_ERROR: %x\n", (uint_t) entryCtrls->exceptionErrorCode); - PrintTrace("VM_ENTRY_INSTR_LENGTH: %x\n", (uint_t) entryCtrls->instrLength); -} - -void PrintTrace_VMCSExitInfoFields(struct VMCSExitInfoFields * exitInfo) { - PrintTrace("\n==> VM Exit Info\n"); - PrintTrace("EXIT_REASON: %x\n", (uint_t) exitInfo->reason); - PrintTrace("EXIT_QUALIFICATION: %x\n", (uint_t) exitInfo->qualification); - PrintTrace("VM_EXIT_INT_INFO: %x\n", (uint_t) exitInfo->intInfo); - PrintTrace("VM_EXIT_INT_ERROR: %x\n", (uint_t) exitInfo->intErrorCode); - PrintTrace("IDT_VECTOR_INFO: %x\n", (uint_t) exitInfo->idtVectorInfo); - PrintTrace("IDT_VECTOR_ERROR: %x\n", (uint_t) exitInfo->idtVectorErrorCode); - PrintTrace("VM_EXIT_INSTR_LENGTH: %x\n", (uint_t) exitInfo->instrLength); - PrintTrace("GUEST_LINEAR_ADDR: %x\n", (uint_t) exitInfo->guestLinearAddr); - PrintTrace("VMX_INSTR_INFO: %x\n", (uint_t) exitInfo->instrInfo); - PrintTrace("IO_RCX: %x\n", (uint_t) exitInfo->ioRCX); - PrintTrace("IO_RSI: %x\n", (uint_t) exitInfo->ioRSI); - PrintTrace("IO_RDI: %x\n", (uint_t) exitInfo->ioRDI); - PrintTrace("IO_RIP: %x\n", (uint_t) exitInfo->ioRIP); - PrintTrace("VM_INSTR_ERROR: %x\n", (uint_t) exitInfo->instrErrorField); -} - - -void PrintTrace_VMCSData(struct VMCSData * vmcs) { - PrintTrace("VMCSData Structure\n"); - - PrintTrace_VMCSGuestStateArea(&(vmcs->guestStateArea)); - PrintTrace_VMCSHostStateArea(&(vmcs->hostStateArea)); - PrintTrace_VMCSExecCtrlFields(&(vmcs->execCtrlFields)); - PrintTrace_VMCSExitCtrlFields(&(vmcs->exitCtrlFields)); - PrintTrace_VMCSEntryCtrlFields(&(vmcs->entryCtrlFields)); - PrintTrace_VMCSExitInfoFields(&(vmcs->exitInfoFields)); - PrintTrace("\n"); -} diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 4a71a11..a0e2fc7 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -19,7 +19,7 @@ #include #include -//#include +#include #include #include #include @@ -56,17 +56,16 @@ void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops) { if (v3_is_svm_capable()) { - PrintDebug("Machine is SVM Capable\n"); - vmm_ops->allocate_guest = &allocate_guest; - v3_init_SVM(vmm_ops); + PrintDebug("Machine is SVM Capable\n"); + vmm_ops->allocate_guest = &allocate_guest; + v3_init_SVM(vmm_ops); - /* - } else if (is_vmx_capable()) { - vmm_cpu_type = VMM_VMX_CPU; - PrintDebug("Machine is VMX Capable\n"); - //Init_VMX();*/ + + } else if (v3_is_vmx_capable()) { + PrintDebug("Machine is VMX Capable\n"); + v3_init_vmx(vmm_ops); } else { - PrintDebug("CPU has no virtualization Extensions\n"); + PrintDebug("CPU has no virtualization Extensions\n"); } } diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 6195141..5c11c45 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include // @@ -32,7 +34,7 @@ // // - +#if 0 #include #include @@ -75,8 +77,6 @@ uint_t myregs = 0; -static struct vmcs_data* vmxon_ptr; - extern uint_t VMCS_LAUNCH(); @@ -342,6 +342,8 @@ int VMLaunch(struct VMDescriptor *vm) // // +#endif + static int update_vmcs_host_state(struct guest_info * info) { addr_t tmp; @@ -478,6 +480,11 @@ static int update_vmcs_host_state(struct guest_info * info) { + +static struct vmcs_data* vmxon_ptr; + + +#if 0 // For the 32 bit reserved bit fields // MB1s are in the low 32 bits, MBZs are in the high 32 bits of the MSR static uint32_t sanitize_bits1(uint32_t msr_num, uint32_t val) { @@ -487,7 +494,7 @@ static uint32_t sanitize_bits1(uint32_t msr_num, uint32_t val) { v3_get_msr(msr_num, &mask_msr.hi, &mask_msr.lo); - PrintDebug("MSR %x = %x : %x \n", msr_num, msr.hi, msr.lo); + PrintDebug("MSR %x = %x : %x \n", msr_num, mask_msr.hi, mask_msr.lo); val &= mask_msr.lo; val &= mask_msr.hi; @@ -496,6 +503,7 @@ static uint32_t sanitize_bits1(uint32_t msr_num, uint32_t val) { } + static addr_t sanitize_bits2(uint32_t msr_num0, uint32_t msr_num1, addr_t val) { v3_msr_t msr0, msr1; addr_t msr0_val, msr1_val; @@ -509,7 +517,7 @@ static addr_t sanitize_bits2(uint32_t msr_num0, uint32_t msr_num1, addr_t val) { msr0_val = msr0.value; msr1_val = msr1.value; - PrintDebug("MSR %x = %p, %x = %p \n", msr_num0, msr0_val, msr_num1, msr1_val); + PrintDebug("MSR %x = %p, %x = %p \n", msr_num0, (void*)msr0_val, msr_num1, (void*)msr1_val); val &= msr0_val; val &= msr1_val; @@ -517,17 +525,27 @@ static addr_t sanitize_bits2(uint32_t msr_num0, uint32_t msr_num1, addr_t val) { return val; } +static int setup_base_host_state() { + + + + // vmwrite(HOST_IDTR_BASE, + + +} + +#endif -static vmcs_data* allocate_vmcs() { +static struct vmcs_data* allocate_vmcs() { reg_ex_t msr; - vmcs_data* vmcs_page = (vmcs_data*)V3_VAddr(V3_AllocPages(1)); + struct vmcs_data* 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; + vmcs_page->revision = ((struct vmx_basic_msr*)&msr)->revision; return vmcs_page; } @@ -555,7 +573,7 @@ static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config info->vmm_data = (void*)data; PrintDebug("Initializing VMCS (addr=%p)\n", info->vmm_data); - init_vmcs_bios((struct vmx_data*)(info->vmm_data), info); + init_vmcs_bios(info); v3_post_config_guest(info, config_ptr); @@ -591,21 +609,22 @@ static int start_vmx_guest(struct guest_info *info) { int v3_is_vmx_capable() { - uint_t ret; v3_msr_t feature_msr; addr_t eax = 0, ebx = 0, ecx = 0, edx = 0; - v3_cpuid(CPUID_FEATURE_IDS, &eax, &ebx, &ecx, &edx); + v3_cpuid(0x1, &eax, &ebx, &ecx, &edx); + + PrintDebug("ECX: %p\n", (void*)ecx); if (ecx & CPUID_1_ECX_VTXFLAG) { - v3_get_msr(IA32_FEATURE_CONTROL_MSR, &(feature_msr.hi), &(feature_msr.lo)); + v3_get_msr(VMX_FEATURE_CONTROL_MSR, &(feature_msr.hi), &(feature_msr.lo)); - PrintTrace("MSRREGlow: 0x%.8x\n", feature_msr.lo); + PrintTrace("MSRREGlow: 0x%.8x\n", feature_msr.lo); - if ((feature_msr.lo & FEATURE_CONTROL_VALID) != FEATURE_CONTROL_VALID) { - PrintDebug("VMX is locked -- enable in the BIOS\n"); - return 0; - } + if ((feature_msr.lo & FEATURE_CONTROL_VALID) != FEATURE_CONTROL_VALID) { + PrintDebug("VMX is locked -- enable in the BIOS\n"); + return 0; + } } else { PrintDebug("VMX not supported on this cpu\n"); @@ -629,35 +648,31 @@ struct seg_descriptor { }; -static int setup_base_host_state() { - uint8_t gdt[10]; - - - - // vmwrite(HOST_IDTR_BASE, - - -} - -void v3_init_vmx(struct v3_ctrl_ops * vm_ops) { - v3_msr_t basic_msr; +void v3_init_vmx(struct v3_ctrl_ops * vmm_ops) { + extern v3_cpu_arch_t v3_cpu_type; __asm__ __volatile__ ( - "movl %%cr4, %%ebx; " - "orl %%ebx, 0x00002000; " - "movl %%ebx, %%cr4" + "movq %%cr4, %%rbx; " + "orq $0x00002000,%%rbx; " + "movq %%rbx, %%cr4;" + : + : + : "%rbx" ); // Should check and return Error here.... __asm__ __volatile__ ( - "movl %%cr0, %%ebx; " - "orl %%ebx, 0x00000020; " - "movl %%ebx, %%cr0" + "movq %%cr0, %%rbx; " + "orq $0x00000020,%%rbx; " + "movq %%rbx, %%cr0;" + : + : + : "%rbx" ); // Setup VMXON Region