Skip to content

Commit dbab610

Browse files
Maxim Levitskybonzini
authored andcommitted
KVM: x86: nVMX: re-evaluate emulation_required on nested VM exit
If L1 had invalid state on VM entry (can happen on SMM transactions when we enter from real mode, straight to nested guest), then after we load 'host' state from VMCS12, the state has to become valid again, but since we load the segment registers with __vmx_set_segment we weren't always updating emulation_required. Update emulation_required explicitly at end of load_vmcs12_host_state. Signed-off-by: Maxim Levitsky <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent c8607e4 commit dbab610

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

arch/x86/kvm/vmx/nested.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4356,6 +4356,8 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
43564356
if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr,
43574357
vmcs12->vm_exit_msr_load_count))
43584358
nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_MSR_FAIL);
4359+
4360+
to_vmx(vcpu)->emulation_required = vmx_emulation_required(vcpu);
43594361
}
43604362

43614363
static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx)

arch/x86/kvm/vmx/vmx.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,7 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
13231323
vmx_prepare_switch_to_host(to_vmx(vcpu));
13241324
}
13251325

1326-
static bool emulation_required(struct kvm_vcpu *vcpu)
1326+
bool vmx_emulation_required(struct kvm_vcpu *vcpu)
13271327
{
13281328
return emulate_invalid_guest_state && !vmx_guest_state_valid(vcpu);
13291329
}
@@ -1367,7 +1367,7 @@ void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
13671367
vmcs_writel(GUEST_RFLAGS, rflags);
13681368

13691369
if ((old_rflags ^ vmx->rflags) & X86_EFLAGS_VM)
1370-
vmx->emulation_required = emulation_required(vcpu);
1370+
vmx->emulation_required = vmx_emulation_required(vcpu);
13711371
}
13721372

13731373
u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu)
@@ -3078,7 +3078,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
30783078
}
30793079

30803080
/* depends on vcpu->arch.cr0 to be set to a new value */
3081-
vmx->emulation_required = emulation_required(vcpu);
3081+
vmx->emulation_required = vmx_emulation_required(vcpu);
30823082
}
30833083

30843084
static int vmx_get_max_tdp_level(void)
@@ -3331,7 +3331,7 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int
33313331
{
33323332
__vmx_set_segment(vcpu, var, seg);
33333333

3334-
to_vmx(vcpu)->emulation_required = emulation_required(vcpu);
3334+
to_vmx(vcpu)->emulation_required = vmx_emulation_required(vcpu);
33353335
}
33363336

33373337
static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)

arch/x86/kvm/vmx/vmx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
355355
void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
356356
unsigned long fs_base, unsigned long gs_base);
357357
int vmx_get_cpl(struct kvm_vcpu *vcpu);
358+
bool vmx_emulation_required(struct kvm_vcpu *vcpu);
358359
unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu);
359360
void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
360361
u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu);

0 commit comments

Comments
 (0)