]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: nVMX: Clear EXIT_QUALIFICATION when injecting an EPT Misconfig
authorSean Christopherson <seanjc@google.com>
Fri, 9 Feb 2024 22:16:58 +0000 (14:16 -0800)
committerSean Christopherson <seanjc@google.com>
Tue, 9 Apr 2024 17:24:36 +0000 (10:24 -0700)
Explicitly clear the EXIT_QUALIFCATION field when injecting an EPT
misconfig into L1, as required by the VMX architecture.  Per the SDM:

  This field is saved for VM exits due to the following causes:
  debug exceptions; page-fault exceptions; start-up IPIs (SIPIs);
  system-management interrupts (SMIs) that arrive immediately after the
  execution of I/O instructions; task switches; INVEPT; INVLPG; INVPCID;
  INVVPID; LGDT; LIDT; LLDT; LTR; SGDT; SIDT; SLDT; STR; VMCLEAR; VMPTRLD;
  VMPTRST; VMREAD; VMWRITE; VMXON; WBINVD; WBNOINVD; XRSTORS; XSAVES;
  control-register accesses; MOV DR; I/O instructions; MWAIT; accesses to
  the APIC-access page; EPT violations; EOI virtualization; APIC-write
  emulation; page-modification log full; SPP-related events; and
  instruction timeout. For all other VM exits, this field is cleared.

Generating EXIT_QUALIFICATION from vcpu->arch.exit_qualification is wrong
for all (two) paths that lead to nested_ept_inject_page_fault().  For EPT
violations (the common case), vcpu->arch.exit_qualification will have been
set by handle_ept_violation() to vmcs02.EXIT_QUALIFICATION, i.e. contains
the information of a EPT violation and thus is likely non-zero.

For an EPT misconfig, which can reach FNAME(walk_addr_generic) and thus
inject a nEPT misconfig if KVM created an MMIO SPTE that became stale,
vcpu->arch.exit_qualification will hold the information from the last EPT
violation VM-Exit, as vcpu->arch.exit_qualification is _only_ written by
handle_ept_violation().

Fixes: 4704d0befb07 ("KVM: nVMX: Exiting from L2 to L1")
Link: https://lore.kernel.org/r/20240209221700.393189-2-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/vmx/nested.c

index d05ddf7514915c479bffbd6e40514b2b91db93ed..695558ff40e1b7e96f01babe565f968164bfc135 100644 (file)
@@ -417,10 +417,12 @@ static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu,
                vmx->nested.pml_full = false;
                exit_qualification &= INTR_INFO_UNBLOCK_NMI;
        } else {
-               if (fault->error_code & PFERR_RSVD_MASK)
+               if (fault->error_code & PFERR_RSVD_MASK) {
                        vm_exit_reason = EXIT_REASON_EPT_MISCONFIG;
-               else
+                       exit_qualification = 0;
+               } else {
                        vm_exit_reason = EXIT_REASON_EPT_VIOLATION;
+               }
 
                /*
                 * Although the caller (kvm_inject_emulated_page_fault) would