Re: [PATCH V2 3/4] KVM: VMX: Don't consult original exit qualification for nested EPT violation injection

From: Yosry Ahmed

Date: Tue Feb 24 2026 - 14:43:57 EST


On Tue, Feb 24, 2026 at 11:37 AM Sean Christopherson <seanjc@xxxxxxxxxx> wrote:
>
> On Tue, Feb 24, 2026, Yosry Ahmed wrote:
> > > > @@ -496,7 +510,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
> > > > * [2:0] - Derive from the access bits. The exit_qualification might be
> > > > * out of date if it is serving an EPT misconfiguration.
> > > > * [5:3] - Calculated by the page walk of the guest EPT page tables
> > > > - * [7:8] - Derived from [7:8] of real exit_qualification
> > > > + * [7:8] - Set at the kvm_translate_gpa() call sites above
> > > > *
> > > > * The other bits are set to 0.
> > > > */
> > > > diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> > > > index 248635da67661..6a167b1d51595 100644
> > > > --- a/arch/x86/kvm/vmx/nested.c
> > > > +++ b/arch/x86/kvm/vmx/nested.c
> > > > @@ -444,9 +444,6 @@ static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu,
> > > > exit_qualification = 0;
> > > > } else {
> > > > exit_qualification = fault->exit_qualification;
> > > > - exit_qualification |= vmx_get_exit_qual(vcpu) &
> > > > - (EPT_VIOLATION_GVA_IS_VALID |
> > > > - EPT_VIOLATION_GVA_TRANSLATED);
> > >
> > > Hmm, this isn't quite correct. If KVM injects an EPT Violation (or a #NPF) when
> > > handling an EPT Violation (or #NPF) from L2, then KVM _should_ follow hardware.
> > >
> > > Aha! I think the easiest way to deal with that is to flag nested page faults
> > > that were the result of walking L1's TDP when handling an L2 TDP page fault, and
> > > then let vendor code extract the fault information out of hardaware.
> >
> > Is it not possible that KVM gets an EPT Violation (or a #NPF) on an L2
> > memory access while the CPU is walking L2's page tables, then KVM
> > walks L1's TDP and finds mappings for the L2 page tables but not the
> > final translation? Or will KVM always just fixup the immediate EPT
> > Violation (or #NPF) by inserting a shadow mapping of L2's page tables
> > and retry the instruction immediately?
>
> The latter, assuming by "shadow mapping of L2's page tables" out meant "installing
> a shadow mapping of the faulting L2 GPA according to L1's TDP page tables".
>
> I.e. when servicing an L2 TDP fault, KVM is only resolving the fault for the reported
> L2 GPA, _not_ the originating L2 GVA (if there is one).

I see. Does this need special handling when forwarding #NPFs to L1 as
well? Or will fault->error_code have the HW fault bits in
nested_svm_inject_npf_exit() in this case?