Commit 2b27924b authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: nVMX: always use early vmcs check when EPT is disabled

The remaining failures of vmx.flat when EPT is disabled are caused by
incorrectly reflecting VMfails to the L1 hypervisor.  What happens is
that nested_vmx_restore_host_state corrupts the guest CR3, reloading it
with the host's shadow CR3 instead, because it blindly loads GUEST_CR3
from the vmcs01.

For simplicity let's just always use hardware VMCS checks when EPT is
disabled.  This way, nested_vmx_restore_host_state is not reached at
all (or at least shouldn't be reached).
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 69090810
...@@ -146,6 +146,7 @@ ...@@ -146,6 +146,7 @@
#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1 #define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
#define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2 #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2
#define VMX_ABORT_VMCS_CORRUPTED 3
#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4 #define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
#endif /* _UAPIVMX_H */ #endif /* _UAPIVMX_H */
...@@ -3796,8 +3796,18 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu) ...@@ -3796,8 +3796,18 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu)
vmx_set_cr4(vcpu, vmcs_readl(CR4_READ_SHADOW)); vmx_set_cr4(vcpu, vmcs_readl(CR4_READ_SHADOW));
nested_ept_uninit_mmu_context(vcpu); nested_ept_uninit_mmu_context(vcpu);
vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
__set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); /*
* This is only valid if EPT is in use, otherwise the vmcs01 GUEST_CR3
* points to shadow pages! Fortunately we only get here after a WARN_ON
* if EPT is disabled, so a VMabort is perfectly fine.
*/
if (enable_ept) {
vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
__set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail);
} else {
nested_vmx_abort(vcpu, VMX_ABORT_VMCS_CORRUPTED);
}
/* /*
* Use ept_save_pdptrs(vcpu) to load the MMU's cached PDPTRs * Use ept_save_pdptrs(vcpu) to load the MMU's cached PDPTRs
...@@ -5745,6 +5755,14 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)) ...@@ -5745,6 +5755,14 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *))
{ {
int i; int i;
/*
* Without EPT it is not possible to restore L1's CR3 and PDPTR on
* VMfail, because they are not available in vmcs01. Just always
* use hardware checks.
*/
if (!enable_ept)
nested_early_check = 1;
if (!cpu_has_vmx_shadow_vmcs()) if (!cpu_has_vmx_shadow_vmcs())
enable_shadow_vmcs = 0; enable_shadow_vmcs = 0;
if (enable_shadow_vmcs) { if (enable_shadow_vmcs) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment