Currently, NMI is delivered to the guest using the Event Injection mechanism [1]. The Event Injection mechanism does not block the delivery of subsequent NMIs. So the Hypervisor needs to track the NMI delivery and its completion(by intercepting IRET) before sending a new NMI. Virtual NMI (VNMI) allows the hypervisor to inject the NMI into the guest w/o using Event Injection mechanism meaning not required to track the guest NMI and intercepting the IRET. To achieve that, VNMI feature provides virtualized NMI and NMI_MASK capability bits in VMCB intr_control - V_NMI(11) - Indicates whether a virtual NMI is pending in the guest. V_NMI_MASK(12) - Indicates whether virtual NMI is masked in the guest. V_NMI_ENABLE(26) - Enables the NMI virtualization feature for the guest. When Hypervisor wants to inject NMI, it will set V_NMI bit, Processor will clear the V_NMI bit and Set the V_NMI_MASK which means the Guest is handling NMI, After the guest handled the NMI, The processor will clear the V_NMI_MASK on the successful completion of IRET instruction Or if VMEXIT occurs while delivering the virtual NMI. To enable the VNMI capability, Hypervisor need to program V_NMI_ENABLE bit 1. The presence of this feature is indicated via the CPUID function 0x8000000A_EDX[25]. Testing - * Used qemu's `inject_nmi` for testing. * tested with and w/o AVIC case. * tested with kvm-unit-test * tested injecting NMI event from L1 to L2 guest (nested env). v2: 01, 02 - added maxim reviwed-by. 03 - Added get_vnmi_vmcb API to return vmcb for l1 and l2. 04 - Moved vnmi check after is_guest_mode() in func svm_nmi_blocked(). 05 - Added WARN_ON check for vnmi pending. 06 - Save the V_NMI_PENDING/MASK state in vmcb12 on vmexit. 07 - No change. Thanks, Santosh [1] https://www.amd.com/system/files/TechDocs/40332.pdf - APM Vol2, ch-15.20 - "Event Injection". Santosh Shukla (7): x86/cpu: Add CPUID feature bit for VNMI KVM: SVM: Add VNMI bit definition KVM: SVM: Add VNMI support in get/set_nmi_mask KVM: SVM: Report NMI not allowed when Guest busy handling VNMI KVM: SVM: Add VNMI support in inject_nmi KVM: nSVM: implement nested VNMI KVM: SVM: Enable VNMI feature arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/svm.h | 7 ++++++ arch/x86/kvm/svm/nested.c | 16 +++++++++++- arch/x86/kvm/svm/svm.c | 40 ++++++++++++++++++++++++++++-- arch/x86/kvm/svm/svm.h | 38 ++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 3 deletions(-) -- 2.25.1