hv: update vcpu mode when vmexit

Signed-off-by: Binbin Wu <binbin.wu@intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Acked-by: Xu, Anthony <anthony.xu@intel.com>
This commit is contained in:
Binbin Wu 2018-05-15 12:00:06 +08:00 committed by lijinxia
parent 5c7f120d96
commit fb09f9daca
2 changed files with 20 additions and 19 deletions

View File

@ -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);

View File

@ -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);