From: Andy Gocke Date: Mon, 13 Jul 2009 17:22:18 +0000 (-0500) Subject: vmx refactoring X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=e058c75f238c6662f6ae1cd517bbca030cc130ab vmx refactoring --- diff --git a/palacios/include/palacios/vmcs.h b/palacios/include/palacios/vmcs.h index ab53e1f..9acdc20 100644 --- a/palacios/include/palacios/vmcs.h +++ b/palacios/include/palacios/vmcs.h @@ -1,4 +1,3 @@ - /* * This file is part of the Palacios Virtual Machine Monitor developed * by the V3VEE Project with funding from the United States National @@ -79,7 +78,8 @@ #define VMCS_LINK_PTR_HIGH 0x00002801 #define GUEST_IA32_DEBUGCTL 0x00002802 #define GUEST_IA32_DEBUGCTL_HIGH 0x00002803 - +#define GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808 +#define GUEST_IA32_PERF_GLOBAL_CTRL_HIGH 0x00002809 /* 32 bit control fields */ #define PIN_VM_EXEC_CTRLS 0x00004000 @@ -101,6 +101,8 @@ // + + /* 32 bit Read Only data fields */ #define VM_INSTR_ERROR 0x00004400 #define EXIT_REASON 0x00004402 @@ -231,11 +233,6 @@ -typedef void vmcs_t; - - - - /* VMCS Exit QUALIFICATIONs */ struct VMExitIOQual { uint32_t accessSize : 3; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes) @@ -308,115 +305,45 @@ struct VMExitIntInfo { /* INTEL Manual: 20-4 vol 3B */ -struct vmcs_segment { - uint16_t selector; - uint32_t limit; - addr_t baseAddr; - - struct { - union { - uint32_t value; - struct { - uint8_t type; - uint32_t desc_type : 1; - uint32_t dpl : 2; - uint32_t present : 1; - uint8_t rsvd1; - uint32_t avail : 1; - uint32_t long_mode : 1; // CS only (64 bit active), reserved otherwise - uint32_t DB : 1; - uint32_t granularity : 1; - uint32_t unusable : 1; - uint32_t rsvd2 : 15; - } __attribute__((packed)); +struct vmcs_segment_access { + union { + uint32_t value; + struct { + uint32_t type : 4; + uint32_t desc_type : 1; + uint32_t dpl : 2; + uint32_t present : 1; + uint32_t rsvd1 : 4; + uint32_t avail : 1; + uint32_t long_mode : 1; // CS only (64 bit active), reserved otherwise + uint32_t DB : 1; + uint32_t granularity : 1; + uint32_t unusable : 1; + uint32_t rsvd2 : 15; } __attribute__((packed)); - } __attribute__((packed)) access; -}; - - - -struct VMCSGuestStateArea { - /* (1) Guest State Area */ - /* (1.1) Guest Register State */ - uint32_t cr0 ; // should be 64 bits? - uint32_t cr3 ; // should be 64 bits? - uint32_t cr4 ; // should be 64 bits? - uint32_t dr7 ; // should be 64 bits? - uint32_t rsp ; // should be 64 bits? - uint32_t rip ; // should be 64 bits? - uint32_t rflags ; // should be 64 bits? - - - struct VMCSSegment cs ; - struct VMCSSegment ss ; - struct VMCSSegment ds ; - struct VMCSSegment es ; - struct VMCSSegment fs ; - struct VMCSSegment gs ; - struct VMCSSegment ldtr ; - struct VMCSSegment tr ; - - struct VMCSSegment gdtr ; - struct VMCSSegment idtr ; - - // MSRs - uint64_t dbg_ctrl ; - uint32_t sysenter_cs ; - uint64_t sysenter_esp ; // should be 64 bits? - uint64_t sysenter_eip ; // should be 64 bits? - - uint32_t smbase ; - - /* (1.2) Guest Non-register State */ - uint32_t activity ; /* (0=Active, 1=HLT, 2=Shutdown, 3=Wait-for-SIPI) - (listed in MSR: IA32_VMX_MISC) */ + } __attribute__((packed)); +}__attribute__((packed);; - uint32_t interrupt_state ; // see Table 20-3 (page 20-6) INTEL MANUAL 3B - uint64_t pending_dbg_exceptions ; // should be 64 bits? - /* Table 20-4 page 20-8 INTEL MANUAL 3B */ - - uint64_t vmcs_link ; // should be set to 0xffffffff_ffffffff -}; - - -int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea * p); -int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea * p); - - - -struct VMCSHostStateArea { - /* (2) Host State Area */ - addr_t cr0 ; - addr_t cr3 ; - addr_t cr4 ; - addr_t rsp ; - addr_t rip ; - - addr_t csSelector ; - addr_t ssSelector ; - addr_t dsSelector ; - addr_t esSelector ; - addr_t fsSelector ; - addr_t gsSelector ; - addr_t trSelector ; - - addr_t fsBaseAddr ; - addr_t gsBaseAddr ; - addr_t trBaseAddr ; - addr_t gdtrBaseAddr ; - addr_t idtrBaseAddr ; - - - /* MSRs */ - uint32_t sysenter_cs ; - addr_t sysenter_esp ; - addr_t sysenter_eip ; - -}; +struct vmcs_interrupt_state { + uint32_t sti_blocking : 1; + uint32_t mov_ss_blocking : 1; + uint32_t smi_blocking : 1; + uint32_t nmi_blocking : 1; + uint32_t rsvd1 : 28; +} __attribute__((packed)); -int CopyOutVMCSHostStateArea(struct VMCSHostStateArea *p); -int CopyInVMCSHostStateArea(struct VMCSHostStateArea *p); +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 { @@ -508,17 +435,10 @@ int CopyOutVMCSExitInfoFields(struct VMCSExitInfoFields *p); -struct VMCSData { +typedef struct vmcs_data { uint32_t revision ; uint32_t abort ; - uint32_t exitCtrlFlags; - struct VMCSGuestStateArea guestStateArea ; - struct VMCSHostStateArea hostStateArea ; - struct VMCSExecCtrlFields execCtrlFields ; - struct VMCSExitCtrlFields exitCtrlFields ; - struct VMCSEntryCtrlFields entryCtrlFields ; - struct VMCSExitInfoFields exitInfoFields ; -}; +} __attribute__((packed)) vmcs_data_t; int CopyOutVMCSData(struct VMCSData *p); diff --git a/palacios/include/palacios/vmx.h b/palacios/include/palacios/vmx.h index d637d8f..4c04647 100644 --- a/palacios/include/palacios/vmx.h +++ b/palacios/include/palacios/vmx.h @@ -31,7 +31,7 @@ // Intel VMX Specific MSRs #define VMX_FEATURE_CONTROL_MSR 0x0000003a -#define VMX_BASIC_MSR 0x00000480 +#define VMX_BASIC_MSR 0x00000480 #define VMX_PINBASED_CTLS_MSR 0x00000481 #define VMX_PROCBASED_CTLS_MSR 0x00000482 #define VMX_EXIT_CTLS_MSR 0x00000483 @@ -67,25 +67,16 @@ struct vmx_basic_msr { uint_t rsvd2 : 10; // Always 0 } __attribute__((packed)); +typedef enum { + VMXASSIST_STARTUP, + VMXASSIST_V8086_BIOS, + VMXASSIST_V8086, + NORMAL +} vmx_state_t; - - - -enum VMState { VM_VMXASSIST_STARTUP, VM_VMXASSIST_V8086_BIOS, VM_VMXASSIST_V8086, VM_NORMAL }; - - - - - - - -struct VM { - enum VMState state; - struct VMXRegs registers; - struct VMDescriptor descriptor; - struct VMCSData vmcs; - struct VMCS *vmcsregion; - struct VmxOnRegion *vmxonregion; +struct vmx_data { + vmx_state_t state; + struct vmcs_data vmcs; }; diff --git a/palacios/include/palacios/vmx_lowlevel.h b/palacios/include/palacios/vmx_lowlevel.h index c4ee91f..b0bd7a5 100644 --- a/palacios/include/palacios/vmx_lowlevel.h +++ b/palacios/include/palacios/vmx_lowlevel.h @@ -147,7 +147,7 @@ static inline int vmcs_store(vmcs_t * vmcs_ptr) { /* According to Intel, vmread will return an architecure sized type - be sure that * dst is at least 64-bits in IA-32e and 32 otherwise */ -static inline int vmcs_read(addr_t vmcs_index, void * dst) { +static inline int vmcs_read(addr_t vmcs_index, void * dst, int len) { addr_t val = 0; uint8_t ret_valid = 0; uint8_t ret_invalid = 0; diff --git a/palacios/src/palacios/vmcs.c b/palacios/src/palacios/vmcs.c index ced7201..aa25f5e 100644 --- a/palacios/src/palacios/vmcs.c +++ b/palacios/src/palacios/vmcs.c @@ -27,407 +27,133 @@ // -#define CHK_VMCS_READ(tag, val) {if (VMCS_READ(tag, val) != 0) return -1;} -#define CHK_VMCS_WRITE(tag, val) {if (VMCS_WRITE(tag, val) != 0) return -1;} - - - -int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea *p) { - CHK_VMCS_READ(GUEST_CR0, &(p->cr0)); - CHK_VMCS_READ(GUEST_CR3, &(p->cr3)); - CHK_VMCS_READ(GUEST_CR4, &(p->cr4)); - CHK_VMCS_READ(GUEST_DR7, &(p->dr7)); - CHK_VMCS_READ(GUEST_RSP, &(p->rsp)); - CHK_VMCS_READ(GUEST_RIP, &(p->rip)); - CHK_VMCS_READ(GUEST_RFLAGS, &(p->rflags)); - CHK_VMCS_READ(VMCS_GUEST_CS_SELECTOR, &(p->cs.selector)); - CHK_VMCS_READ(VMCS_GUEST_SS_SELECTOR, &(p->ss.selector)); - CHK_VMCS_READ(VMCS_GUEST_DS_SELECTOR, &(p->ds.selector)); - CHK_VMCS_READ(VMCS_GUEST_ES_SELECTOR, &(p->es.selector)); - CHK_VMCS_READ(VMCS_GUEST_FS_SELECTOR, &(p->fs.selector)); - CHK_VMCS_READ(VMCS_GUEST_GS_SELECTOR, &(p->gs.selector)); - CHK_VMCS_READ(VMCS_GUEST_LDTR_SELECTOR, &(p->ldtr.selector)); - CHK_VMCS_READ(VMCS_GUEST_TR_SELECTOR, &(p->tr.selector)); - CHK_VMCS_READ(GUEST_CS_BASE, &(p->cs.baseAddr)); - CHK_VMCS_READ(GUEST_SS_BASE, &(p->ss.baseAddr)); - CHK_VMCS_READ(GUEST_DS_BASE, &(p->ds.baseAddr)); - CHK_VMCS_READ(GUEST_ES_BASE, &(p->es.baseAddr)); - CHK_VMCS_READ(GUEST_FS_BASE, &(p->fs.baseAddr)); - CHK_VMCS_READ(GUEST_GS_BASE, &(p->gs.baseAddr)); - CHK_VMCS_READ(GUEST_LDTR_BASE, &(p->ldtr.baseAddr)); - CHK_VMCS_READ(GUEST_TR_BASE, &(p->tr.baseAddr)); - CHK_VMCS_READ(GUEST_CS_LIMIT, &(p->cs.limit)); - CHK_VMCS_READ(GUEST_SS_LIMIT, &(p->ss.limit)); - CHK_VMCS_READ(GUEST_DS_LIMIT, &(p->ds.limit)); - CHK_VMCS_READ(GUEST_ES_LIMIT, &(p->es.limit)); - CHK_VMCS_READ(GUEST_FS_LIMIT, &(p->fs.limit)); - CHK_VMCS_READ(GUEST_GS_LIMIT, &(p->gs.limit)); - CHK_VMCS_READ(GUEST_LDTR_LIMIT, &(p->ldtr.limit)); - CHK_VMCS_READ(GUEST_TR_LIMIT, &(p->tr.limit)); - CHK_VMCS_READ(GUEST_CS_ACCESS, &(p->cs.access)); - CHK_VMCS_READ(GUEST_SS_ACCESS, &(p->ss.access)); - CHK_VMCS_READ(GUEST_DS_ACCESS, &(p->ds.access)); - CHK_VMCS_READ(GUEST_ES_ACCESS, &(p->es.access)); - CHK_VMCS_READ(GUEST_FS_ACCESS, &(p->fs.access)); - CHK_VMCS_READ(GUEST_GS_ACCESS, &(p->gs.access)); - CHK_VMCS_READ(GUEST_LDTR_ACCESS, &(p->ldtr.access)); - CHK_VMCS_READ(GUEST_TR_ACCESS, &(p->tr.access)); - CHK_VMCS_READ(GUEST_GDTR_BASE, &(p->gdtr.baseAddr)); - CHK_VMCS_READ(GUEST_IDTR_BASE, &(p->idtr.baseAddr)); - CHK_VMCS_READ(GUEST_GDTR_LIMIT, &(p->gdtr.limit)); - CHK_VMCS_READ(GUEST_IDTR_LIMIT, &(p->idtr.limit)); - CHK_VMCS_READ(GUEST_IA32_DEBUGCTL, &(p->dbg_ctrl)); - CHK_VMCS_READ(GUEST_IA32_DEBUGCTL_HIGH, ((char *)&(p->dbg_ctrl)) + 4); - CHK_VMCS_READ(GUEST_IA32_SYSENTER_CS, &(p->sysenter_cs)); - CHK_VMCS_READ(GUEST_IA32_SYSENTER_ESP, &(p->sysenter_esp)); - CHK_VMCS_READ(GUEST_IA32_SYSENTER_EIP, &(p->sysenter_eip)); - CHK_VMCS_READ(GUEST_SMBASE, &(p->smbase)); - - CHK_VMCS_READ(GUEST_ACTIVITY_STATE, &(p->activity)); - CHK_VMCS_READ(GUEST_INT_STATE, &(p->interrupt_state)); - CHK_VMCS_READ(GUEST_PENDING_DEBUG_EXCS, &(p->pending_dbg_exceptions)); - CHK_VMCS_READ(VMCS_LINK_PTR, &(p->vmcs_link)); - CHK_VMCS_READ(VMCS_LINK_PTR_HIGH, ((char *)&(p->vmcs_link)) + 4); - return 0; +static inline void print_vmcs_field(uint_t vmcs_index) { + int len = v3_vmcs_get_field_len(vmcs_index); + addr_t val; + + if (vmcs_read(vmcs_index, &val, len) != VMX_SUCCESS) { + PrintError("VMCS_READ error for index %x\n", vmcs_index); + return; + }; + + if (len == 2) { + PrintDebug("%s: %x\n", v3_vmcs_get_field_name(vmcs_index), (uint16_t)val); + } else if (len == 4) { + PrintDebug("%s: %x\n", v3_vmcs_get_field_name(vmcs_index), (uint32_t)val); + } else if (len == 8) { + PrintDebug("%s: %p\n", v3_vmcs_get_field_name(vmcs_index), (void *)(addr_t)val); + } } -int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea *p) { - CHK_VMCS_WRITE(GUEST_CR0, &(p->cr0)); - CHK_VMCS_WRITE(GUEST_CR3, &(p->cr3)); - CHK_VMCS_WRITE(GUEST_CR4, &(p->cr4)); - CHK_VMCS_WRITE(GUEST_DR7, &(p->dr7)); - CHK_VMCS_WRITE(GUEST_RSP, &(p->rsp)); - CHK_VMCS_WRITE(GUEST_RIP, &(p->rip)); - CHK_VMCS_WRITE(GUEST_RFLAGS, &(p->rflags)); - CHK_VMCS_WRITE(VMCS_GUEST_CS_SELECTOR, &(p->cs.selector)); - CHK_VMCS_WRITE(VMCS_GUEST_SS_SELECTOR, &(p->ss.selector)); - CHK_VMCS_WRITE(VMCS_GUEST_DS_SELECTOR, &(p->ds.selector)); - CHK_VMCS_WRITE(VMCS_GUEST_ES_SELECTOR, &(p->es.selector)); - CHK_VMCS_WRITE(VMCS_GUEST_FS_SELECTOR, &(p->fs.selector)); - CHK_VMCS_WRITE(VMCS_GUEST_GS_SELECTOR, &(p->gs.selector)); - CHK_VMCS_WRITE(VMCS_GUEST_LDTR_SELECTOR, &(p->ldtr.selector)); - CHK_VMCS_WRITE(VMCS_GUEST_TR_SELECTOR, &(p->tr.selector)); - CHK_VMCS_WRITE(GUEST_CS_BASE, &(p->cs.baseAddr)); - CHK_VMCS_WRITE(GUEST_SS_BASE, &(p->ss.baseAddr)); - CHK_VMCS_WRITE(GUEST_DS_BASE, &(p->ds.baseAddr)); - CHK_VMCS_WRITE(GUEST_ES_BASE, &(p->es.baseAddr)); - CHK_VMCS_WRITE(GUEST_FS_BASE, &(p->fs.baseAddr)); - CHK_VMCS_WRITE(GUEST_GS_BASE, &(p->gs.baseAddr)); - CHK_VMCS_WRITE(GUEST_LDTR_BASE, &(p->ldtr.baseAddr)); - CHK_VMCS_WRITE(GUEST_TR_BASE, &(p->tr.baseAddr)); - CHK_VMCS_WRITE(GUEST_CS_LIMIT, &(p->cs.limit)); - CHK_VMCS_WRITE(GUEST_SS_LIMIT, &(p->ss.limit)); - CHK_VMCS_WRITE(GUEST_DS_LIMIT, &(p->ds.limit)); - CHK_VMCS_WRITE(GUEST_ES_LIMIT, &(p->es.limit)); - CHK_VMCS_WRITE(GUEST_FS_LIMIT, &(p->fs.limit)); - CHK_VMCS_WRITE(GUEST_GS_LIMIT, &(p->gs.limit)); - CHK_VMCS_WRITE(GUEST_LDTR_LIMIT, &(p->ldtr.limit)); - CHK_VMCS_WRITE(GUEST_TR_LIMIT, &(p->tr.limit)); - CHK_VMCS_WRITE(GUEST_CS_ACCESS, &(p->cs.access)); - CHK_VMCS_WRITE(GUEST_SS_ACCESS, &(p->ss.access)); - CHK_VMCS_WRITE(GUEST_DS_ACCESS, &(p->ds.access)); - CHK_VMCS_WRITE(GUEST_ES_ACCESS, &(p->es.access)); - CHK_VMCS_WRITE(GUEST_FS_ACCESS, &(p->fs.access)); - CHK_VMCS_WRITE(GUEST_GS_ACCESS, &(p->gs.access)); - CHK_VMCS_WRITE(GUEST_LDTR_ACCESS, &(p->ldtr.access)); - CHK_VMCS_WRITE(GUEST_TR_ACCESS, &(p->tr.access)); - CHK_VMCS_WRITE(GUEST_GDTR_BASE, &(p->gdtr.baseAddr)); - CHK_VMCS_WRITE(GUEST_IDTR_BASE, &(p->idtr.baseAddr)); - CHK_VMCS_WRITE(GUEST_GDTR_LIMIT, &(p->gdtr.limit)); - CHK_VMCS_WRITE(GUEST_IDTR_LIMIT, &(p->idtr.limit)); - CHK_VMCS_WRITE(GUEST_IA32_DEBUGCTL, &(p->dbg_ctrl)); - CHK_VMCS_WRITE(GUEST_IA32_DEBUGCTL_HIGH, ((char *)&(p->dbg_ctrl)) + 4); - CHK_VMCS_WRITE(GUEST_IA32_SYSENTER_CS, &(p->sysenter_cs)); - CHK_VMCS_WRITE(GUEST_IA32_SYSENTER_ESP, &(p->sysenter_esp)); - CHK_VMCS_WRITE(GUEST_IA32_SYSENTER_EIP, &(p->sysenter_eip)); - CHK_VMCS_WRITE(GUEST_SMBASE, &(p->smbase)); - - CHK_VMCS_WRITE(GUEST_ACTIVITY_STATE, &(p->activity)); - CHK_VMCS_WRITE(GUEST_INT_STATE, &(p->interrupt_state)); - CHK_VMCS_WRITE(GUEST_PENDING_DEBUG_EXCS, &(p->pending_dbg_exceptions)); - CHK_VMCS_WRITE(VMCS_LINK_PTR, &(p->vmcs_link)); - CHK_VMCS_WRITE(VMCS_LINK_PTR_HIGH, ((char *)&(p->vmcs_link)) + 4); - return 0; +static inline void print_vmcs_segments() { + // see vm_guest.c } -int CopyOutVMCSHostStateArea(struct VMCSHostStateArea *p) { - CHK_VMCS_READ(HOST_CR0, &(p->cr0)); - CHK_VMCS_READ(HOST_CR3, &(p->cr3)); - CHK_VMCS_READ(HOST_CR4, &(p->cr4)); - CHK_VMCS_READ(HOST_RSP, &(p->rsp)); - CHK_VMCS_READ(HOST_RIP, &(p->rip)); - CHK_VMCS_READ(VMCS_HOST_CS_SELECTOR, &(p->csSelector)); - CHK_VMCS_READ(VMCS_HOST_SS_SELECTOR, &(p->ssSelector)); - CHK_VMCS_READ(VMCS_HOST_DS_SELECTOR, &(p->dsSelector)); - CHK_VMCS_READ(VMCS_HOST_ES_SELECTOR, &(p->esSelector)); - CHK_VMCS_READ(VMCS_HOST_FS_SELECTOR, &(p->fsSelector)); - CHK_VMCS_READ(VMCS_HOST_GS_SELECTOR, &(p->gsSelector)); - CHK_VMCS_READ(VMCS_HOST_TR_SELECTOR, &(p->trSelector)); - CHK_VMCS_READ(HOST_FS_BASE, &(p->fsBaseAddr)); - CHK_VMCS_READ(HOST_GS_BASE, &(p->gsBaseAddr)); - CHK_VMCS_READ(HOST_TR_BASE, &(p->trBaseAddr)); - CHK_VMCS_READ(HOST_GDTR_BASE, &(p->gdtrBaseAddr)); - CHK_VMCS_READ(HOST_IDTR_BASE, &(p->idtrBaseAddr)); - CHK_VMCS_READ(HOST_IA32_SYSENTER_CS, &(p->sysenter_cs)); - CHK_VMCS_READ(HOST_IA32_SYSENTER_ESP, &(p->sysenter_esp)); - CHK_VMCS_READ(HOST_IA32_SYSENTER_EIP, &(p->sysenter_eip)); - return 0; -} - - - -int CopyInVMCSHostStateArea(struct VMCSHostStateArea *p) { - CHK_VMCS_WRITE(HOST_CR0, &(p->cr0)); - CHK_VMCS_WRITE(HOST_CR3, &(p->cr3)); - CHK_VMCS_WRITE(HOST_CR4, &(p->cr4)); - CHK_VMCS_WRITE(HOST_RSP, &(p->rsp)); - CHK_VMCS_WRITE(HOST_RIP, &(p->rip)); - CHK_VMCS_WRITE(VMCS_HOST_CS_SELECTOR, &(p->csSelector)); - CHK_VMCS_WRITE(VMCS_HOST_SS_SELECTOR, &(p->ssSelector)); - CHK_VMCS_WRITE(VMCS_HOST_DS_SELECTOR, &(p->dsSelector)); - CHK_VMCS_WRITE(VMCS_HOST_ES_SELECTOR, &(p->esSelector)); - CHK_VMCS_WRITE(VMCS_HOST_FS_SELECTOR, &(p->fsSelector)); - CHK_VMCS_WRITE(VMCS_HOST_GS_SELECTOR, &(p->gsSelector)); - CHK_VMCS_WRITE(VMCS_HOST_TR_SELECTOR, &(p->trSelector)); - CHK_VMCS_WRITE(HOST_FS_BASE, &(p->fsBaseAddr)); - CHK_VMCS_WRITE(HOST_GS_BASE, &(p->gsBaseAddr)); - CHK_VMCS_WRITE(HOST_TR_BASE, &(p->trBaseAddr)); - CHK_VMCS_WRITE(HOST_GDTR_BASE, &(p->gdtrBaseAddr)); - CHK_VMCS_WRITE(HOST_IDTR_BASE, &(p->idtrBaseAddr)); - CHK_VMCS_WRITE(HOST_IA32_SYSENTER_CS, &(p->sysenter_cs)); - CHK_VMCS_WRITE(HOST_IA32_SYSENTER_ESP, &(p->sysenter_esp)); - CHK_VMCS_WRITE(HOST_IA32_SYSENTER_EIP, &(p->sysenter_eip)); - return 0; -} - -int CopyOutVMCSExitCtrlFields(struct VMCSExitCtrlFields *p) -{ - CHK_VMCS_READ(VM_EXIT_CTRLS,&(p->exitCtrls)); - CHK_VMCS_READ(VM_EXIT_MSR_STORE_COUNT,&(p->msrStoreCount)); - CHK_VMCS_READ(VM_EXIT_MSR_STORE_ADDR,&(p->msrStoreAddr)); - CHK_VMCS_READ(VM_EXIT_MSR_LOAD_COUNT,&(p->msrLoadCount)); - CHK_VMCS_READ(VM_EXIT_MSR_LOAD_ADDR,&(p->msrLoadAddr)); - return 0; -} - -int CopyInVMCSExitCtrlFields(struct VMCSExitCtrlFields *p) -{ - CHK_VMCS_WRITE(VM_EXIT_CTRLS,&(p->exitCtrls)); - CHK_VMCS_WRITE(VM_EXIT_MSR_STORE_COUNT,&(p->msrStoreCount)); - CHK_VMCS_WRITE(VM_EXIT_MSR_STORE_ADDR,&(p->msrStoreAddr)); - CHK_VMCS_WRITE(VM_EXIT_MSR_LOAD_COUNT,&(p->msrLoadCount)); - CHK_VMCS_WRITE(VM_EXIT_MSR_LOAD_ADDR,&(p->msrLoadAddr)); - return 0; -} - - -int CopyOutVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p) -{ - CHK_VMCS_READ(VM_ENTRY_CTRLS,&(p->entryCtrls)); - CHK_VMCS_READ(VM_ENTRY_MSR_LOAD_COUNT,&(p->msrLoadCount)); - CHK_VMCS_READ(VM_ENTRY_MSR_LOAD_ADDR,&(p->msrLoadAddr)); - CHK_VMCS_READ(VM_ENTRY_INT_INFO_FIELD,&(p->intInfo)); - CHK_VMCS_READ(VM_ENTRY_EXCEPTION_ERROR,&(p->exceptionErrorCode)); - CHK_VMCS_READ(VM_ENTRY_INSTR_LENGTH,&(p->instrLength)); - return 0; -} -int CopyInVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p) -{ - CHK_VMCS_WRITE(VM_ENTRY_CTRLS,&(p->entryCtrls)); - CHK_VMCS_WRITE(VM_ENTRY_MSR_LOAD_COUNT,&(p->msrLoadCount)); - CHK_VMCS_WRITE(VM_ENTRY_MSR_LOAD_ADDR,&(p->msrLoadAddr)); - CHK_VMCS_WRITE(VM_ENTRY_INT_INFO_FIELD,&(p->intInfo)); - CHK_VMCS_WRITE(VM_ENTRY_EXCEPTION_ERROR,&(p->exceptionErrorCode)); - CHK_VMCS_WRITE(VM_ENTRY_INSTR_LENGTH,&(p->instrLength)); - return 0; -} +void print_debug_vmcs_load_guest() { + const int wordsize = sizeof(addr_t); + uint64_t temp; + vmcs_segment tmp_seg; -int CopyOutVMCSExitInfoFields(struct VMCSExitInfoFields *p) { - CHK_VMCS_READ(EXIT_REASON,&(p->reason)); - CHK_VMCS_READ(EXIT_QUALIFICATION,&(p->qualification)); - CHK_VMCS_READ(VM_EXIT_INT_INFO,&(p->intInfo)); - CHK_VMCS_READ(VM_EXIT_INT_ERROR,&(p->intErrorCode)); - CHK_VMCS_READ(IDT_VECTOR_INFO,&(p->idtVectorInfo)); - CHK_VMCS_READ(IDT_VECTOR_ERROR,&(p->idtVectorErrorCode)); - CHK_VMCS_READ(VM_EXIT_INSTR_LENGTH,&(p->instrLength)); - CHK_VMCS_READ(GUEST_LINEAR_ADDR,&(p->guestLinearAddr)); - CHK_VMCS_READ(VMX_INSTR_INFO,&(p->instrInfo)); - CHK_VMCS_READ(IO_RCX,&(p->ioRCX)); - CHK_VMCS_READ(IO_RSI,&(p->ioRSI)); - CHK_VMCS_READ(IO_RDI,&(p->ioRDI)); - CHK_VMCS_READ(IO_RIP,&(p->ioRIP)); - CHK_VMCS_READ(VM_INSTR_ERROR,&(p->instrErrorField)); - return 0; -} + PrintDebug("\n====== Loading Guest State ======\n"); + PRINT_VMREAD("Guest CR0: %x\n", GUEST_CR0, wordsize); + PRINT_VMREAD("Guest CR3: %x\n", GUEST_CR3, wordsize); + PRINT_VMREAD("Guest CR4: %x\n", GUEST_CR4, wordsize); + PRINT_VMREAD("Guest DR7: %x\n", GUEST_DR7, wordsize); + READ_VMCS_SEG(&tmp_seg,CS,wordsize); + print_vmcs_segment("CS", &tmp_seg); + + READ_VMCS_SEG(&tmp_seg,SS,wordsize); + print_vmcs_segment("SS", &tmp_seg); -int CopyOutVMCSExecCtrlFields(struct VMCSExecCtrlFields *p) -{ - CHK_VMCS_READ(PIN_VM_EXEC_CTRLS,&(p->pinCtrls)); - CHK_VMCS_READ(PROC_VM_EXEC_CTRLS,&(p->procCtrls)); - CHK_VMCS_READ(EXCEPTION_BITMAP,&(p->execBitmap)); - CHK_VMCS_READ(PAGE_FAULT_ERROR_MASK,&(p->pageFaultErrorMask)); - CHK_VMCS_READ(PAGE_FAULT_ERROR_MATCH,&(p->pageFaultErrorMatch)); - CHK_VMCS_READ(IO_BITMAP_A_ADDR,&(p->ioBitmapA)); - CHK_VMCS_READ(IO_BITMAP_B_ADDR,&(p->ioBitmapB)); - CHK_VMCS_READ(TSC_OFFSET,&(p->tscOffset)); - CHK_VMCS_READ(CR0_GUEST_HOST_MASK,&(p->cr0GuestHostMask)); - CHK_VMCS_READ(CR0_READ_SHADOW,&(p->cr0ReadShadow)); - CHK_VMCS_READ(CR4_GUEST_HOST_MASK,&(p->cr4GuestHostMask)); - CHK_VMCS_READ(CR4_READ_SHADOW,&(p->cr4ReadShadow)); - CHK_VMCS_READ(CR3_TARGET_COUNT, &(p->cr3TargetCount)); - CHK_VMCS_READ(CR3_TARGET_VALUE_0, &(p->cr3TargetValue0)); - CHK_VMCS_READ(CR3_TARGET_VALUE_1, &(p->cr3TargetValue1)); - CHK_VMCS_READ(CR3_TARGET_VALUE_2, &(p->cr3TargetValue2)); - CHK_VMCS_READ(CR3_TARGET_VALUE_3, &(p->cr3TargetValue3)); - CHK_VMCS_READ(VIRT_APIC_PAGE_ADDR, &(p->virtApicPageAddr)); - CHK_VMCS_READ(TPR_THRESHOLD, &(p->tprThreshold)); - CHK_VMCS_READ(MSR_BITMAPS, &(p->MSRBitmapsBaseAddr)); - CHK_VMCS_READ(VMCS_EXEC_PTR,&(p->vmcsExecPtr)); - return 0; -} + READ_VMCS_SEG(&tmp,DS,wordsize); + print_vmcs_segment("DS", &tmp_seg); + READ_VMCS_SEG(&tmp_seg,ES,wordsize); + print_vmcs_segment("ES", &tmp_seg); -int CopyInVMCSExecCtrlFields(struct VMCSExecCtrlFields *p) -{ - CHK_VMCS_WRITE(PIN_VM_EXEC_CTRLS,&(p->pinCtrls)); - CHK_VMCS_WRITE(PROC_VM_EXEC_CTRLS,&(p->procCtrls)); - CHK_VMCS_WRITE(EXCEPTION_BITMAP,&(p->execBitmap)); - CHK_VMCS_WRITE(PAGE_FAULT_ERROR_MASK,&(p->pageFaultErrorMask)); - CHK_VMCS_WRITE(PAGE_FAULT_ERROR_MATCH,&(p->pageFaultErrorMatch)); - CHK_VMCS_WRITE(IO_BITMAP_A_ADDR,&(p->ioBitmapA)); - CHK_VMCS_WRITE(IO_BITMAP_B_ADDR,&(p->ioBitmapB)); - CHK_VMCS_WRITE(TSC_OFFSET,&(p->tscOffset)); - CHK_VMCS_WRITE(CR0_GUEST_HOST_MASK,&(p->cr0GuestHostMask)); - CHK_VMCS_WRITE(CR0_READ_SHADOW,&(p->cr0ReadShadow)); - CHK_VMCS_WRITE(CR4_GUEST_HOST_MASK,&(p->cr4GuestHostMask)); - CHK_VMCS_WRITE(CR4_READ_SHADOW,&(p->cr4ReadShadow)); - CHK_VMCS_WRITE(CR3_TARGET_COUNT, &(p->cr3TargetCount)); - CHK_VMCS_WRITE(CR3_TARGET_VALUE_0, &(p->cr3TargetValue0)); - CHK_VMCS_WRITE(CR3_TARGET_VALUE_1, &(p->cr3TargetValue1)); - CHK_VMCS_WRITE(CR3_TARGET_VALUE_2, &(p->cr3TargetValue2)); - CHK_VMCS_WRITE(CR3_TARGET_VALUE_3, &(p->cr3TargetValue3)); - CHK_VMCS_WRITE(VIRT_APIC_PAGE_ADDR, &(p->virtApicPageAddr)); - CHK_VMCS_WRITE(TPR_THRESHOLD, &(p->tprThreshold)); - CHK_VMCS_WRITE(MSR_BITMAPS, &(p->MSRBitmapsBaseAddr)); - CHK_VMCS_WRITE(VMCS_EXEC_PTR,&(p->vmcsExecPtr)); - return 0; -} + READ_VMCS_SEG(&tmp_seg,FS,wordsize); + print_vmcs_segment("FS", &tmp_seg); + READ_VMCS_SEG(&tmp_seg,GS,wordsize); + print_vmcs_segment("GS", &tmp_seg); -int CopyOutVMCSData(struct VMCSData *p) { - if (CopyOutVMCSGuestStateArea(&(p->guestStateArea)) != 0) { - return -1; - } - if (CopyOutVMCSHostStateArea(&(p->hostStateArea)) != 0) { - return -1; - } - if (CopyOutVMCSExecCtrlFields(&(p->execCtrlFields)) != 0) { - return -1; - } - if (CopyOutVMCSExitCtrlFields(&(p->exitCtrlFields)) != 0) { - return -1; - } - if (CopyOutVMCSEntryCtrlFields(&(p->entryCtrlFields)) != 0) { - return -1; - } - if (CopyOutVMCSExitInfoFields(&(p->exitInfoFields)) != 0) { - return -1; - } - return 0; -} + READ_VMCS_SEG(&tmp_seg,TR,wordsize); + print_vmcs_segment("TR", &tmp_seg); + READ_VMCS_SEG(&tmp_seg,LDTR,wordsize); + print_vmcs_segment("LDTR", &tmp_seg); + + PrintDebug("\n==GDTR==\n"); + PRINT_VMREAD("GDTR Base: %x\n", GUEST_GDTR_BASE, wordsize); + PRINT_VMREAD("GDTR Limit: %x\n", GUEST_GDTR_LIMIT, 32); + PrintDebug("====\n"); -int CopyInVMCSData(struct VMCSData *p) { - if (CopyInVMCSGuestStateArea(&(p->guestStateArea)) != 0) { - return -1; - } - if (CopyInVMCSHostStateArea(&(p->hostStateArea)) != 0) { - return -1; - } - if (CopyInVMCSExecCtrlFields(&(p->execCtrlFields)) != 0) { - return -1; - } - if (CopyInVMCSExitCtrlFields(&(p->exitCtrlFields)) != 0) { - return -1; - } - if (CopyInVMCSEntryCtrlFields(&(p->entryCtrlFields)) != 0) { - return -1; - } - return 0; -} + PrintDebug("\n==LDTR==\n"); + PRINT_VMREAD("LDTR Base: %x\n", GUEST_LDTR_BASE, wordsize); + PRINT_VMREAD("LDTR Limit: %x\n", GUEST_LDTR_LIMIT, 32); + PrintDebug("=====\n"); + PRINT_VMREAD("Guest RSP: %x\n", GUEST_RSP, wordsize); + PRINT_VMREAD("Guest RIP: %x\n", GUEST_RIP, wordsize); + PRINT_VMREAD("Guest RFLAGS: %x\n", GUEST_RFLAGS, wordsize); + PRINT_VMREAD("Guest Activity state: %x\n", GUEST_ACTIVITY_STATE, 32); + PRINT_VMREAD("Guest Interruptibility state: %x\n", GUEST_INT_STATE, 32); + PRINT_VMREAD("Guest pending debug: %x\n", GUEST_PENDING_DEBUG_EXCS, wordsize); -void PrintTrace_VMX_Regs(struct VMXRegs * regs) { - PrintTrace("==>VMX Register values:\n"); - PrintTrace("EAX: %x\n", regs->eax); - PrintTrace("ECX: %x\n", regs->ecx); - PrintTrace("EDX: %x\n", regs->edx); - PrintTrace("EBX: %x\n", regs->ebx); - PrintTrace("ESP: %x\n", regs->esp); - PrintTrace("EBP: %x\n", regs->ebp); - PrintTrace("ESI: %x\n", regs->esi); - PrintTrace("EDI: %x\n", regs->edi); - PrintTrace("\n"); + PRINT_VMREAD("IA32_DEBUGCTL: %x\n", GUEST_IA32_DEBUGCTL, 64); + PRINT_VMREAD("IA32_SYSENTER_CS: %x\n", GUEST_IA32_SYSENTER_CS, 32); + PRINT_VMREAD("IA32_SYSTENTER_ESP: %x\n", GUEST_IA32_SYSENTER_ESP, wordsize); + PRINT_VMREAD("IA32_SYSTENTER_EIP: %x\n", GUEST_IA32_SYSENTER_EIP, wordsize); + PRINT_VMREAD("IA32_PERF_GLOBAL_CTRL: %x\n", GUEST_IA32_PERF_GLOBAL_CTRL, wordsize); + PRINT_VMREAD("VMCS Link Ptr: %x\n", VMCS_LINK_PTR, 64); + // TODO: Maybe add VMX preemption timer and PDTE (Intel 20-8 Vol. 3b) } - -void PrintTrace_VMCSSegment(char * segname, struct VMCSSegment * seg, int abbr) { - PrintTrace("Segment: %s\n", segname); - if (abbr == 0) { - PrintTrace("\tSelector: %x\n", (uint_t)seg->selector); - PrintTrace("\tAccess: %x\n", *(uint_t*)&(seg->access)); - } - PrintTrace("\tBase Addr: %x\n", (uint_t)seg->baseAddr); - PrintTrace("\tLimit: %x\n", (uint_t)seg->limit); - +void print_debug_load_host() { + const int wordsize = sizeof(addr_t); + uint64_t temp; + vmcs_segment tmp_seg; + + PrintDebug("\n====== Host State ========\n"); + PRINT_VMREAD("Host CR0: %x\n", HOST_CR0, wordsize); + PRINT_VMREAD("Host CR3: %x\n", HOST_CR3, wordsize); + PRINT_VMREAD("Host CR4: %x\n", HOST_CR4, wordsize); + PRINT_VMREAD("Host RSP: %x\n", HOST_RSP, wordsize); + PRINT_VMREAD("Host RIP: %x\n", HOST_RIP, wordsize); + PRINT_VMREAD("IA32_SYSENTER_CS: %x\n", HOST_IA32_SYSENTER_CS, 32); + PRINT_VMREAD("IA32_SYSENTER_ESP: %x\n", HOST_IA32_SYSENTER_ESP, wordsize); + PRINT_VMREAD("IA32_SYSENTER_EIP: %x\n", HOST_IA32_SYSENTER_EIP, wordsize); + + PRINT_VMREAD("Host CS Selector: %x\n", HOST_CS_SELECTOR, 16); + PRINT_VMREAD("Host SS Selector: %x\n", HOST_SS_SELECTOR, 16); + PRINT_VMREAD("Host DS Selector: %x\n", HOST_DS_SELECTOR, 16); + PRINT_VMREAD("Host ES Selector: %x\n", HOST_ES_SELECTOR, 16); + PRINT_VMREAD("Host FS Selector: %x\n", HOST_FS_SELECTOR, 16); + PRINT_VMREAD("Host GS Selector: %x\n", HOST_GS_SELECTOR, 16); + PRINT_VMREAD("Host TR Selector: %x\n", HOST_TR_SELECTOR, 16); + + PRINT_VMREAD("Host FS Base: %x\n", HOST_FS_BASE, wordsize); + PRINT_VMREAD("Host GS Base: %x\n", HOST_GS_BASE, wordsize); + PRINT_VMREAD("Host TR Base: %x\n", HOST_TR_BASE, wordsize); + PRINT_VMREAD("Host GDTR Base: %x\n", HOST_GDTR_BASE, wordsize); + PRINT_VMREAD("Host IDTR Base: %x\n", HOSE_IDTR_BASE, wordsize); } - -void PrintTrace_VMCSGuestStateArea(struct VMCSGuestStateArea * guestState) { - PrintTrace("==>Guest State Area\n"); - PrintTrace("==>==> Guest Register State\n"); - PrintTrace("GUEST_CR0: %x\n",(uint_t) guestState->cr0); - PrintTrace("GUEST_CR3: %x\n",(uint_t)guestState->cr3); - PrintTrace("GUEST_CR4: %x\n",(uint_t)guestState->cr4); - PrintTrace("GUEST_DR7: %x\n",(uint_t)guestState->dr7); - PrintTrace("GUEST_RSP: %x\n",(uint_t)guestState->rsp); - PrintTrace("GUEST_RIP: %x\n",(uint_t)guestState->rip); - PrintTrace("GUEST_RFLAGS: %x\n",(uint_t)guestState->rflags); - - PrintTrace_VMCSSegment("Guest CS", &(guestState->cs), 0); - PrintTrace_VMCSSegment("Guest SS", &(guestState->ss), 0); - PrintTrace_VMCSSegment("Guest DS",&(guestState->ds), 0); - PrintTrace_VMCSSegment("Guest ES", &(guestState->es), 0); - PrintTrace_VMCSSegment("Guest FS", &(guestState->fs), 0); - PrintTrace_VMCSSegment("Guest GS", &(guestState->gs), 0); - PrintTrace_VMCSSegment("Guest LDTR", &(guestState->ldtr), 0); - PrintTrace_VMCSSegment("Guest TR", &(guestState->tr), 0); - PrintTrace_VMCSSegment("Guest GDTR", &(guestState->gdtr), 1); - PrintTrace_VMCSSegment("Guest IDTR", &(guestState->idtr), 1); - - - PrintTrace("GUEST_IA32_DEBUGCTL: %x\n",(uint_t)(guestState->dbg_ctrl & 0xffffffff)); - PrintTrace("GUEST_IA32_DEBUGCTL_HIGH: %x\n",(uint_t)(guestState->dbg_ctrl >> 32) & 0xffffffff); - PrintTrace("GUEST_IA32_SYSENTER_CS: %x\n",guestState->sysenter_cs); - PrintTrace("GUEST_IA32_SYSENTER_ESP: %x\n",(uint_t)guestState->sysenter_esp); - PrintTrace("GUEST_IA32_SYSENTER_EIP: %x\n",(uint_t)guestState->sysenter_eip); - PrintTrace("GUEST_SMBASE: %x\n", (uint_t)guestState->smbase); - - PrintTrace("==>==> Guest Non-Register State\n"); - PrintTrace("GUEST_ACTIVITY_STATE: %x\n", (uint_t)guestState->activity); - PrintTrace("GUEST_INT_STATE: %x\n", (uint_t)guestState->interrupt_state); - PrintTrace("GUEST_PENDING_DEBUG_EXCS: %x\n", (uint_t)guestState->pending_dbg_exceptions); - PrintTrace("VMCS_LINK_PTR: %x\n", (uint_t)guestState->vmcs_link & 0xffffffff); - PrintTrace("VMCS_LINK_PTR_HIGH: %x\n", (uint_t)(guestState->vmcs_link >> 32) & 0xffffffff); +void print_vmcs_segment(char * name, vmcs_segment* seg) +{ + PrintDebug("\n==VMCS %s Segment==\n",name); + PrintDebug("\tSelector: %x\n", seg->selector); + PrintDebug("\tBase Address: %x\n", seg->baseAddr); + PrintDebug("\tLimit: %x\n", seg->limit); + PrintDebug("\tAccess: %x\n", seg->access); } - void PrintTrace_VMCSHostStateArea(struct VMCSHostStateArea * hostState) { PrintTrace("\n==> Host State Area\n"); PrintTrace("HOST_CR0: %x\n", (uint_t)hostState->cr0); diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 5ab70f6..8a315ce 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -23,6 +23,7 @@ #include #include #include +#include // @@ -35,6 +36,7 @@ #include #include +#include @@ -50,7 +52,6 @@ extern int Launch_VM(ullong_t vmcsPtr, uint_t eip); #define ROMBIOS_DEBUG_PORT 0x403 -static struct VM theVM; static uint_t GetLinearIP(struct VM * vm) { if (vm->state == VM_VMXASSIST_V8086_BIOS || vm->state == VM_VMXASSIST_V8086) { @@ -77,11 +78,7 @@ uint_t myregs = 0; -extern uint_t VMCS_CLEAR(); -extern uint_t VMCS_LOAD(); -extern uint_t VMCS_STORE(); extern uint_t VMCS_LAUNCH(); -extern uint_t VMCS_RESUME(); extern uint_t Init_VMCS_HostState(); extern uint_t Init_VMCS_GuestState(); @@ -123,60 +120,61 @@ void DecodeCurrentInstruction(struct VM *vm, struct Instruction *inst) } -static void V8086ModeSegmentRegisterFixup(struct VM *vm) +static void setup_v8086_mode_for_boot(struct guest_info* vm_info) { - vm->vmcs.guestStateArea.cs.baseAddr = vm->vmcs.guestStateArea.cs.selector << 4; - vm->vmcs.guestStateArea.es.baseAddr = vm->vmcs.guestStateArea.es.selector << 4; - vm->vmcs.guestStateArea.ss.baseAddr = vm->vmcs.guestStateArea.ss.selector << 4; - vm->vmcs.guestStateArea.ds.baseAddr = vm->vmcs.guestStateArea.ds.selector << 4; - vm->vmcs.guestStateArea.fs.baseAddr = vm->vmcs.guestStateArea.fs.selector << 4; - vm->vmcs.guestStateArea.gs.baseAddr = vm->vmcs.guestStateArea.gs.selector << 4; -} - -static void SetupV8086ModeForBoot(struct VM *vm) -{ - vm->state = VM_VMXASSIST_V8086_BIOS; - - // Put guest into V8086 mode on return - vm->vmcs.guestStateArea.rflags |= EFLAGS_VM | EFLAGS_IOPL_HI | EFLAGS_IOPL_LO ; - - // We will start at f000:fff0 on return - // - // We want this to look as much as possible as a processor - // reset - vm->vmcs.guestStateArea.rip = 0xfff0; // note, 16 bit rip - vm->vmcs.guestStateArea.cs.selector = 0xf000; - vm->vmcs.guestStateArea.cs.limit = 0xffff; - vm->vmcs.guestStateArea.cs.access.as_dword = 0xf3; - - vm->vmcs.guestStateArea.ss.selector = 0x0000; - vm->vmcs.guestStateArea.ss.limit = 0xffff; - vm->vmcs.guestStateArea.ss.access.as_dword = 0xf3; - - vm->vmcs.guestStateArea.ds.selector = 0x0000; - vm->vmcs.guestStateArea.ds.limit = 0xffff; - vm->vmcs.guestStateArea.ds.access.as_dword = 0xf3; - - vm->vmcs.guestStateArea.es.selector = 0x0000; - vm->vmcs.guestStateArea.es.limit = 0xffff; - vm->vmcs.guestStateArea.es.access.as_dword = 0xf3; - - vm->vmcs.guestStateArea.fs.selector = 0x0000; - vm->vmcs.guestStateArea.fs.limit = 0xffff; - vm->vmcs.guestStateArea.fs.access.as_dword = 0xf3; - - vm->vmcs.guestStateArea.gs.selector = 0x0000; - vm->vmcs.guestStateArea.gs.limit = 0xffff; - vm->vmcs.guestStateArea.gs.access.as_dword = 0xf3; - - V8086ModeSegmentRegisterFixup(vm); - - PrintTrace_VMCSData(&(vm->vmcs)); + ((struct vmx_data*)vm_info->vmm_data)->state = VMXASSIST_V8086_BIOS; + ((struct rflags)info->ctrl_regs.rflags).vm = 1; + ((struct rflags)info->ctrl_regs.rflags).iopl = 3; + + + vm_info->rip = 0xfff0; + + vm_info->segments.cs.selector = 0xf000; + vm_info->segments.cs.base = 0xf000<<4; + vm_info->segments.cs.limit = 0xffff; + vm_info->segments.cs.type = 3; + vm_info->segments.cs.system = 1; + vm_info->segments.cs.dpl = 3; + vm_info->segments.cs.present = 1; + vm_info->segments.cs.granularity = 0; + + vm_info->segments.ss.selector = 0x0000; + vm_info->segments.ss.base = 0x0000<<4; + vm_info->segments.ss.limit = 0xffff; + vm_info->segments.ss.type = 3; + vm_info->segments.ss.system = 1; + vm_info->segments.ss.dpl = 3; + vm_info->segments.ss.present = 1; + vm_info->segments.ss.granularity = 0; + + vm_info->segments.es.selector = 0x0000; + vm_info->segments.es.base = 0x0000<<4; + vm_info->segments.es.limit = 0xffff; + vm_info->segments.es.type = 3; + vm_info->segments.es.system = 1; + vm_info->segments.es.dpl = 3; + vm_info->segments.es.present = 1; + vm_info->segments.es.granularity = 0; + + vm_info->segments.fs.selector = 0x0000; + vm_info->segments.fs.base = 0x0000<<4; + vm_info->segments.fs.limit = 0xffff; + vm_info->segments.fs.type = 3; + vm_info->segments.fs.system = 1; + vm_info->segments.fs.dpl = 3; + vm_info->segments.fs.present = 1; + vm_info->segments.fs.granularity = 0; + + vm_info->segments.gs.selector = 0x0000; + vm_info->segments.gs.base = 0x0000<<4; + vm_info->segments.gs.limit = 0xffff; + vm_info->segments.gs.type = 3; + vm_info->segments.gs.system = 1; + vm_info->segments.gs.dpl = 3; + vm_info->segments.gs.present = 1; + vm_info->segments.gs.granularity = 0; } - - - static void ConfigureExits(struct VM *vm) { @@ -385,15 +383,15 @@ static addr_t sanitize_bits2(uint32_t msr_num0, uint32_t msr_num1, addr_t val) { -static vmcs_t * allocate_vmcs() { +static vmcs_data* allocate_vmcs() { reg_ex_t msr; - vmcs_t * vmcs_page = (vmcs_t *)V3_VAddr(V3_AllocPages(1)); + vmcs_data* vmcs_page = (vmcs_data*)V3_VAddr(V3_AllocPages(1)); - memset(vmcb_page, 0, 4096); + memset(vmcs_page, 0, 4096); v3_get_msr(VMX_BASIC_MSR, &(msr.e_reg.high), &(msr.e_reg.low)); - *(uint32_t *)vmcs_page = ((struct vmx_basic_msr *)msr.val)->revision; + vmcs_page->revision = ((struct vmx_basic_msr)msr).revision; return vmcs_page; } @@ -409,8 +407,14 @@ static void init_vmcs_bios(vmcs_t * vmcs, struct guest_info * vm_info) { static int init_vmx_guest(struct guest_info * info, struct v3_vm_config * config_ptr) { v3_pre_config_guest(info, config_ptr); + struct vmx_data* data; + + PrintDebug("Allocating vmx_data\n"); + data = (struct vmx_data*)V3_Malloc(sizeof(vmx_data)); PrintDebug("Allocating VMCS\n"); - info->vmm_data = (void *)allocate_vmcs(); + data->vmcs = allocate_vmcs(); + + info->vmm_data = (void*)data; PrintDebug("Initializing VMCS (addr=%p)\n", (void *)info->vmm_data); init_vmcs_bios((vmcs_t *)(info->vmm_data), info);