[kvm-unit-tests PATCH] x86: APIC: Add test for pending NMIs while NMIs are blocked

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Though explicit documentation is difficult to unearth, x86 guarantees
that exactly one NMI will be pended when NMIs are blocked.  The SDM
essentially calls this out in its section on handling NMIs in SMM:

  NMI interrupts are blocked upon entry to the SMI handler. If an NMI
  request occurs during the SMI handler, it is latched and serviced
  after the processor exits SMM. Only one NMI request will be latched
  during the SMI handler.

Add a test to send multiple NMIs from within an NMI handler to verify
that KVM correctly pends exactly *one* NMI when NMIs are blocked.

Cc: Nadav Amit <nadav.amit@xxxxxxxxx>
Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx>
---
 x86/apic.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/x86/apic.c b/x86/apic.c
index 51744cf..9b78288 100644
--- a/x86/apic.c
+++ b/x86/apic.c
@@ -403,6 +403,34 @@ static void test_multiple_nmi(void)
     report("multiple nmi", ok);
 }
 
+static void pending_nmi_handler(isr_regs_t *regs)
+{
+    int i;
+
+    if (++nmi_received == 1) {
+        for (i = 0; i < 10; ++i)
+            apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI, 0);
+    }
+}
+
+static void test_pending_nmi(void)
+{
+    int i;
+
+    handle_irq(2, pending_nmi_handler);
+    for (i = 0; i < 100000; ++i) {
+	    nmi_received = 0;
+
+        apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI, 0);
+        while (nmi_received < 2)
+            pause();
+
+        if (nmi_received != 2)
+            break;
+    }
+    report("pending nmi", nmi_received == 2);
+}
+
 static volatile int lvtt_counter = 0;
 
 static void lvtt_handler(isr_regs_t *regs)
@@ -615,6 +643,7 @@ int main(void)
 
     test_sti_nmi();
     test_multiple_nmi();
+    test_pending_nmi();
 
     test_apic_timer_one_shot();
     test_apic_change_mode();
-- 
2.21.0




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux