VNMI Spec is at [1]. Change History: v5 (6.1-rc2) 01,02,06 - Renamed s/X86_FEATURE_V_NMI/X86_FEATURE_AMD_VNMI (Jim Mattson) v4 (v6.0-rc3): https://lore.kernel.org/all/20220829100850.1474-1-santosh.shukla@xxxxxxx/ v3 (rebased on eb555cb5b794f): https://lore.kernel.org/all/20220810061226.1286-1-santosh.shukla@xxxxxxx/ v2: https://lore.kernel.org/lkml/20220709134230.2397-7-santosh.shukla@xxxxxxx/T/#m4bf8a131748688fed00ab0fefdcac209a169e202 v1: https://lore.kernel.org/all/20220602142620.3196-1-santosh.shukla@xxxxxxx/ Description: Currently, NMI is delivered to the guest using the Event Injection mechanism [2]. 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. If NMI virtualization enabled and NMI_INTERCEPT bit is unset then HW will exit with #INVALID exit reason. 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 with vGIF enable and disable. * tested nested env: - L1+L2 using vnmi - L1 using vnmi and L2 not Thanks, Santosh [1] https://www.amd.com/en/support/tech-docs/amd64-architecture-programmers-manual-volumes-1-5 (Ch-15.21.10 - NMI Virtualization) [2] https://www.amd.com/en/support/tech-docs/amd64-architecture-programmers-manual-volumes-1-5 (Ch-15.20 - Event Injection) Santosh Shukla (8): 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: nSVM: emulate VMEXIT_INVALID case for 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 | 32 ++++++++++++++ arch/x86/kvm/svm/svm.c | 44 ++++++++++++++++++- arch/x86/kvm/svm/svm.h | 68 ++++++++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 1 deletion(-) -- 2.25.1