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: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
690908104e
Коммит
2b27924bb1
|
@ -146,6 +146,7 @@
|
|||
|
||||
#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
|
||||
#define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2
|
||||
#define VMX_ABORT_VMCS_CORRUPTED 3
|
||||
#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
|
||||
|
||||
#endif /* _UAPIVMX_H */
|
||||
|
|
|
@ -3796,8 +3796,18 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu)
|
|||
vmx_set_cr4(vcpu, vmcs_readl(CR4_READ_SHADOW));
|
||||
|
||||
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
|
||||
|
@ -5745,6 +5755,14 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *))
|
|||
{
|
||||
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())
|
||||
enable_shadow_vmcs = 0;
|
||||
if (enable_shadow_vmcs) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче