From fb09f9dacafd45af65705dee83f7c10816f04421 Mon Sep 17 00:00:00 2001 From: Binbin Wu Date: Tue, 15 May 2018 12:00:06 +0800 Subject: [PATCH] hv: update vcpu mode when vmexit Signed-off-by: Binbin Wu Reviewed-by: Kevin Tian Acked-by: Xu, Anthony --- .../arch/x86/guest/instr_emul_wrapper.c | 21 ++----------------- hypervisor/arch/x86/guest/vcpu.c | 18 ++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/hypervisor/arch/x86/guest/instr_emul_wrapper.c b/hypervisor/arch/x86/guest/instr_emul_wrapper.c index d3a52e9d0..80d85fe79 100644 --- a/hypervisor/arch/x86/guest/instr_emul_wrapper.c +++ b/hypervisor/arch/x86/guest/instr_emul_wrapper.c @@ -269,23 +269,6 @@ static int32_t get_vmcs_field(int ident) } } -static enum vm_cpu_mode get_vmx_cpu_mode(void) -{ - uint32_t csar; - - if (exec_vmread(VMX_GUEST_IA32_EFER_FULL) & EFER_LMA) { - csar = exec_vmread(VMX_GUEST_CS_ATTR); - if (csar & 0x2000) - return CPU_MODE_64BIT; /* CS.L = 1 */ - else - return CPU_MODE_COMPATIBILITY; - } else if (exec_vmread(VMX_GUEST_CR0) & CR0_PE) { - return CPU_MODE_PROTECTED; - } else { - return CPU_MODE_REAL; - } -} - static void get_guest_paging_info(struct vcpu *vcpu, struct emul_cnx *emul_cnx) { uint32_t cpl, csar; @@ -297,7 +280,7 @@ static void get_guest_paging_info(struct vcpu *vcpu, struct emul_cnx *emul_cnx) emul_cnx->paging.cr3 = vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3; emul_cnx->paging.cpl = cpl; - emul_cnx->paging.cpu_mode = get_vmx_cpu_mode(); + emul_cnx->paging.cpu_mode = get_vcpu_mode(vcpu); emul_cnx->paging.paging_mode = PAGING_MODE_FLAT;/*maybe change later*/ } @@ -358,7 +341,7 @@ uint8_t decode_instruction(struct vcpu *vcpu) get_guest_paging_info(vcpu, emul_cnx); csar = exec_vmread(VMX_GUEST_CS_ATTR); - cpu_mode = get_vmx_cpu_mode(); + cpu_mode = get_vcpu_mode(vcpu); retval = __decode_instruction(vcpu, guest_rip_gva, cpu_mode, SEG_DESC_DEF32(csar), &emul_cnx->vie); diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index a0f1ee607..e44e1e216 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -106,6 +106,23 @@ int create_vcpu(int cpu_id, struct vm *vm, struct vcpu **rtn_vcpu_handle) return 0; } +static void set_vcpu_mode(struct vcpu *vcpu, uint32_t cs_attr) +{ + struct run_context *cur_context = + &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; + + if (cur_context->ia32_efer & MSR_IA32_EFER_LMA_BIT) { + if (cs_attr & 0x2000) /* CS.L = 1 */ + vcpu->arch_vcpu.cpu_mode = CPU_MODE_64BIT; + else + vcpu->arch_vcpu.cpu_mode = CPU_MODE_COMPATIBILITY; + } else if (cur_context->cr0 & CR0_PE) { + vcpu->arch_vcpu.cpu_mode = CPU_MODE_PROTECTED; + } else { + vcpu->arch_vcpu.cpu_mode = CPU_MODE_REAL; + } +} + int start_vcpu(struct vcpu *vcpu) { uint32_t instlen; @@ -160,6 +177,7 @@ int start_vcpu(struct vcpu *vcpu) /* Save guest IA32_EFER register */ cur_context->ia32_efer = exec_vmread64(VMX_GUEST_IA32_EFER_FULL); + set_vcpu_mode(vcpu, exec_vmread(VMX_GUEST_CS_ATTR)); /* Obtain current VCPU instruction pointer and length */ cur_context->rip = exec_vmread(VMX_GUEST_RIP);