X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=palacios%2Finclude%2Fpalacios%2Fvmx_lowlevel.h;h=01bca797049e79a70dfa70e4e93f7b43ef94d58a;hp=c4ee91f1ff54a628d723dd07e51656607c2d0ac5;hb=6541ca672276d841db22cc18a003303cf517ea89;hpb=6e898f031ff725e4a337094b22ff5b67d992ba45 diff --git a/palacios/include/palacios/vmx_lowlevel.h b/palacios/include/palacios/vmx_lowlevel.h index c4ee91f..01bca79 100644 --- a/palacios/include/palacios/vmx_lowlevel.h +++ b/palacios/include/palacios/vmx_lowlevel.h @@ -22,6 +22,7 @@ #ifdef __V3VEE__ +#include #define VMX_SUCCESS 0 #define VMX_FAIL_INVALID 1 @@ -37,7 +38,7 @@ /* Opcode definitions for all the VM instructions */ -#define VMCLEAR_OPCODE ".byte 0x66,0xf,0x67;" /* reg=/6 */ +#define VMCLEAR_OPCODE ".byte 0x66,0xf,0xc7;" /* reg=/6 */ #define VMRESUME_OPCODE ".byte 0x0f,0x01,0xc3;" #define VMPTRLD_OPCODE ".byte 0x0f,0xc7;" /* reg=/6 */ #define VMPTRST_OPCODE ".byte 0x0f,0xc7;" /* reg=/7 */ @@ -56,7 +57,8 @@ -static inline int v3_enable_vmx(uint64_t host_state) { +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__ ( @@ -64,7 +66,7 @@ static inline int v3_enable_vmx(uint64_t host_state) { EAX_06_MODRM "setnaeb %0;" // fail invalid (CF=1) : "=q"(ret_invalid) - : "a"(&host_state),"0"(ret_invalid) + : "a"(&vmxon_ptr_64),"0"(ret_invalid) : "memory"); if (ret_invalid) { @@ -74,9 +76,8 @@ static inline int v3_enable_vmx(uint64_t host_state) { } } -// No vmcall necessary - is only executed by the guest - -static inline int vmcs_clear(uint64_t addr) { +static inline int vmcs_clear(addr_t vmcs_ptr) { + uint64_t vmcs_ptr_64 __attribute__ ((aligned(8))) = (uint64_t)vmcs_ptr; uint8_t ret_valid = 0; uint8_t ret_invalid = 0; @@ -86,7 +87,7 @@ static inline int vmcs_clear(uint64_t addr) { "seteb %0;" // fail valid (ZF=1) "setnaeb %1;" // fail invalid (CF=1) : "=q"(ret_valid), "=q"(ret_invalid) - : "a"(&addr), "0"(ret_valid), "1"(ret_invalid) + : "a"(&vmcs_ptr_64), "0"(ret_valid), "1"(ret_invalid) : "memory"); CHECK_VMXFAIL(ret_valid, ret_invalid); @@ -94,27 +95,8 @@ static inline int vmcs_clear(uint64_t addr) { return VMX_SUCCESS; } - -static inline int vmcs_resume() { - uint8_t ret_valid = 0; - uint8_t ret_invalid = 0; - - __asm__ __volatile__ ( - VMRESUME_OPCODE - "seteb %0;" - "setnaeb %1;" - : "=q"(ret_valid), "=q"(ret_invalid) - : "0"(ret_valid), "1"(ret_invalid) - : "memory"); - - CHECK_VMXFAIL(ret_valid, ret_invalid); - - return VMX_SUCCESS; -} - - -static inline int vmcs_load(vmcs_t * vmcs_ptr) { - uint64_t addr = (uint64_t)vmcs_ptr; +static inline int vmcs_load(addr_t vmcs_ptr) { + uint64_t vmcs_ptr_64 = (uint64_t)vmcs_ptr; uint8_t ret_valid = 0; uint8_t ret_invalid = 0; @@ -124,7 +106,7 @@ static inline int vmcs_load(vmcs_t * vmcs_ptr) { "seteb %0;" // fail valid (ZF=1) "setnaeb %1;" // fail invalid (CF=1) : "=q"(ret_valid), "=q"(ret_invalid) - : "a"(&addr), "0"(ret_valid), "1"(ret_invalid) + : "a"(&vmcs_ptr_64), "0"(ret_valid), "1"(ret_invalid) : "memory"); CHECK_VMXFAIL(ret_valid, ret_invalid); @@ -132,22 +114,20 @@ static inline int vmcs_load(vmcs_t * vmcs_ptr) { return VMX_SUCCESS; } -static inline int vmcs_store(vmcs_t * vmcs_ptr) { - uint64_t addr = (uint64_t)vmcs_ptr; +static inline int vmcs_store(addr_t vmcs_ptr) { + uint64_t vmcs_ptr_64 = (uint64_t)vmcs_ptr; __asm__ __volatile__ ( - VMPTRSRT_OPCODE + VMPTRST_OPCODE EAX_07_MODRM : - : "a"(&addr) + : "a"(&vmcs_ptr_64) : "memory"); return VMX_SUCCESS; } -/* 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(vmcs_field_t vmcs_field, void * dst) { addr_t val = 0; uint8_t ret_valid = 0; uint8_t ret_invalid = 0; @@ -155,22 +135,33 @@ static inline int vmcs_read(addr_t vmcs_index, void * dst) { __asm__ __volatile__ ( VMREAD_OPCODE EAX_ECX_MODRM - "seteb %0;" // fail valid + "seteb %1;" // fail valid "setnaeb %1;" // fail invalid - : "=q"(ret_valid), "=q"(ret_invalid), "=c"(val) // Use ECX - : "a" (vmcs_index), "0"(ret_valid), "1"(ret_invalid) + : "=c"(val), "=d"(ret_valid) //, "=r"(ret_invalid) // Use ECX + : "a" (vmcs_field), "0"(0), "1"(ret_valid) : "memory" ); CHECK_VMXFAIL(ret_valid, ret_invalid); - // TODO: Fix this, will have to do a cast because dst will be variable length - *dst = val; + switch(v3_vmcs_get_field_len(vmcs_field)) + { + case 2: + *((uint16_t*)dst) = (uint16_t)val; + break; + case 4: + *((uint32_t*)dst) = (uint32_t)val; + break; + case 8: + *((uint64_t*)dst) = (uint64_t)val; + break; + } + return VMX_SUCCESS; } -static inline int vmcs_write(addr_t vmcs_index, addr_t value) { +static inline int vmcs_write(vmcs_field_t vmcs_field, addr_t value) { uint8_t ret_valid = 0; uint8_t ret_invalid = 0; @@ -180,7 +171,7 @@ static inline int vmcs_write(addr_t vmcs_index, addr_t value) { "seteb %0;" // fail valid (ZF=1) "setnaeb %1;" // fail invalid (CF=1) : "=q" (ret_valid), "=q" (ret_invalid) - : "a" (vmcs_index), "c"(value), "0"(ret_valid), "1"(ret_invalid) + : "a" (vmcs_field), "c"(value) : "memory"); CHECK_VMXFAIL(ret_valid, ret_invalid);