diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 96c220e5cd56..97d41754769e 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -5007,9 +5007,12 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u64 error_code, * re-execute the instruction that caused the page fault. Do not allow * retrying MMIO emulation, as it's not only pointless but could also * cause us to enter an infinite loop because the processor will keep - * faulting on the non-existent MMIO address. + * faulting on the non-existent MMIO address. Retrying an instruction + * from a nested guest is also pointless and dangerous as we are only + * explicitly shadowing L1's page tables, i.e. unprotecting something + * for L1 isn't going to magically fix whatever issue cause L2 to fail. */ - if (!mmio_info_in_cache(vcpu, cr2, direct)) + if (!mmio_info_in_cache(vcpu, cr2, direct) && !is_guest_mode(vcpu)) emulation_type = EMULTYPE_ALLOW_RETRY; emulate: /* diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index deaa6f4234fd..97fcac34e007 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5813,6 +5813,9 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t cr2, if (!(emulation_type & EMULTYPE_ALLOW_RETRY)) return false; + if (WARN_ON_ONCE(is_guest_mode(vcpu))) + return false; + if (!vcpu->arch.mmu.direct_map) { /* * Write permission should be allowed since only @@ -5901,6 +5904,9 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt, if (!(emulation_type & EMULTYPE_ALLOW_RETRY)) return false; + if (WARN_ON_ONCE(is_guest_mode(vcpu))) + return false; + if (x86_page_table_writing_insn(ctxt)) return false;