Re: [PATCH 7/7] KVM: VMX: Handle NMI VM-Exits in noinstr region

Sean Christopherson
2023-08-24T14:27:06Z

On Thu, Aug 24, 2023, Sean Christopherson wrote:
> On Thu, Aug 24, 2023, Like Xu wrote:
> > @@ -7389,6 +7382,13 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
> >
> > trace_kvm_exit(vcpu, KVM_ISA_VMX);
> >
> > + if ((u16)vmx->exit_reason.basic == EXIT_REASON_EXCEPTION_NMI &&
> > + is_nmi(vmx_get_intr_info(vcpu))) {
> > + kvm_before_interrupt(vcpu, KVM_HANDLING_NMI);
> > + vmx_do_nmi_irqoff();
> > + kvm_after_interrupt(vcpu);
> > + }
>
> No, the whole point of doing NMI handling in vmx_vcpu_enter_exit() is so that NMIs
> are serviced before instrumentation is enabled.
>
> I think the below is sufficient (untested at this point). Not quite minimal, e.g.
> I'm pretty sure there's (currently) no need to snapshot IDT_VECTORING_INFO_FIELD
> so early, but I can't think of any reason to wait.
>
> --
> From: Sean Christopherson <seanjc@google.com>
> Date: Thu, 24 Aug 2023 06:49:36 -0700
> Subject: [PATCH] KVM: VMX: Refresh available regs and IDT vectoring info
> before NMI handling
>
> Reset the mask of available "registers" and refresh the IDT vectoring
> info snapshot in vmx_vcpu_enter_exit(), before KVM potentially handles a
> an NMI VM-Exit. One of the "registers" that KVM VMX lazily loads is the
> vmcs.VM_EXIT_INTR_INFO field, which is holds the vector+type on "exception
> or NMI" VM-Exits, i.e. is needed to identify NMIs. Clearing the available
> registers bitmask after handling NMIs results in KVM querying info from
> the last VM-Exit that read vmcs.VM_EXIT_INTR_INFO, and leads to both
> missed NMIs and spurious NMIs from the guest's perspective.

Oof, it's not just from the guest's perspective, NMIs that are destined for host
consumption will suffer the same fate.