On Fri, Jul 29, 2022, Shukla, Santosh wrote: > Hello Sean, > > On 7/21/2022 3:24 AM, Sean Christopherson wrote: > > On Sat, Jul 09, 2022, Santosh Shukla wrote: ... > >> @@ -3609,6 +3612,9 @@ static void svm_enable_nmi_window(struct kvm_vcpu *vcpu) > >> { > >> struct vcpu_svm *svm = to_svm(vcpu); > >> > >> + if (is_vnmi_enabled(svm)) > >> + return; > > > > Ugh, is there really no way to trigger an exit when NMIs become unmasked? Because > > if there isn't, this is broken for KVM. > > > > Yes. there is. > > NMI_INTERCEPT will trigger VMEXIT when second NMI arrives while guest is busy handling first NMI. But NMI_INTERCEPT only applies to "real" NMIs. The scenario laid out below is where KVM wants to inject a virtual NMI without an associated hardware/real NMI, e.g. if multiple vCPUs send NMI IPIs to the target. > And in that scenario, Guest will exit with V_NMI_MASK set to 1, KVM can inject pending(Second) > NMI(V_NMI=1). Guest will resume handling the first NMI, then HW will > clear the V_NMI_MASK and later HW will take the pending V_NMI in side the guest. > > I'll handle above case in v3. > > Thanks, > Santosh > > > On bare metal, if two NMIs arrive "simultaneously", so long as NMIs aren't blocked, > > the first NMI will be delivered and the second will be pended, i.e. software will > > see both NMIs. And if that doesn't hold true, the window for a true collision is > > really, really tiny. > > > > But in KVM, because a vCPU may not be run a long duration, that window becomes > > very large. To not drop NMIs and more faithfully emulate hardware, KVM allows two > > NMIs to be _pending_. And when that happens, KVM needs to trigger an exit when > > NMIs become unmasked _after_ the first NMI is injected. > > > >> + > >> if ((vcpu->arch.hflags & (HF_NMI_MASK | HF_IRET_MASK)) == HF_NMI_MASK) > >> return; /* IRET will cause a vm exit */ > >> > >> -- > >> 2.25.1 > >>