All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests
@ 2020-04-09 13:32 Cathy Avery
  2020-04-09 13:32 ` [PATCH kvm-unit-tests 1/2] svm: Add test cases around NMI injection Cathy Avery
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Cathy Avery @ 2020-04-09 13:32 UTC (permalink / raw)
  To: kvm, pbonzini

Patch 1 is NMI injection and intercept. Patch 2 is the same test with guest in
HLT.

Cathy Avery (2):
  svm: Add test cases around NMI injection
  svm: Add test cases around NMI injection with HLT

 x86/svm_tests.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 187 insertions(+)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH kvm-unit-tests 1/2] svm: Add test cases around NMI injection
  2020-04-09 13:32 [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests Cathy Avery
@ 2020-04-09 13:32 ` Cathy Avery
  2020-04-09 13:49   ` Paolo Bonzini
  2020-04-09 13:32 ` [PATCH kvm-unit-tests 2/2] svm: Add test cases around NMI injection with HLT Cathy Avery
  2020-04-09 13:48 ` [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests Paolo Bonzini
  2 siblings, 1 reply; 5+ messages in thread
From: Cathy Avery @ 2020-04-09 13:32 UTC (permalink / raw)
  To: kvm, pbonzini

This test checks for NMI delivery to L2 and
intercepted NMI (VMEXIT_NMI) delivery to L1.

Signed-off-by: Cathy Avery <cavery@redhat.com>
---
 x86/svm_tests.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 16b9dfd..d1dbdef 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -1340,6 +1340,87 @@ static bool interrupt_check(struct svm_test *test)
     return get_test_stage(test) == 5;
 }
 
+static volatile bool nmi_fired;
+
+#define NMI_VECTOR    2
+
+static void nmi_handler(isr_regs_t *regs)
+{
+    nmi_fired = true;
+    apic_write(APIC_EOI, 0);
+}
+
+static void nmi_prepare(struct svm_test *test)
+{
+    default_prepare(test);
+    nmi_fired = false;
+    handle_irq(NMI_VECTOR, nmi_handler);
+    set_test_stage(test, 0);
+}
+
+static void nmi_test(struct svm_test *test)
+{
+    apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
+
+    report(nmi_fired, "direct NMI while running guest");
+
+    if (!nmi_fired)
+        set_test_stage(test, -1);
+
+    vmmcall();
+
+    nmi_fired = false;
+
+    apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
+
+    if (!nmi_fired) {
+        report(nmi_fired, "intercepted pending NMI not dispatched");
+        set_test_stage(test, -1);
+    }
+
+}
+
+static bool nmi_finished(struct svm_test *test)
+{
+    switch (get_test_stage(test)) {
+    case 0:
+        if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
+            report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
+                   vmcb->control.exit_code);
+            return true;
+        }
+        vmcb->save.rip += 3;
+
+        vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
+        break;
+
+    case 1:
+        if (vmcb->control.exit_code != SVM_EXIT_NMI) {
+            report(false, "VMEXIT not due to NMI intercept. Exit reason 0x%x",
+                   vmcb->control.exit_code);
+            return true;
+        }
+
+        report(true, "NMI intercept while running guest");
+        break;
+
+    case 2:
+        break;
+
+    default:
+        return true;
+    }
+
+    inc_test_stage(test);
+
+    return get_test_stage(test) == 3;
+}
+
+static bool nmi_check(struct svm_test *test)
+{
+    return get_test_stage(test) == 3;
+}
+
 #define TEST(name) { #name, .v2 = name }
 
 /*
@@ -1446,6 +1527,9 @@ struct svm_test svm_tests[] = {
     { "interrupt", default_supported, interrupt_prepare,
       default_prepare_gif_clear, interrupt_test,
       interrupt_finished, interrupt_check },
+    { "nmi", default_supported, nmi_prepare,
+      default_prepare_gif_clear, nmi_test,
+      nmi_finished, nmi_check },
     TEST(svm_guest_state_test),
     { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 };
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH kvm-unit-tests 2/2] svm: Add test cases around NMI injection with HLT
  2020-04-09 13:32 [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests Cathy Avery
  2020-04-09 13:32 ` [PATCH kvm-unit-tests 1/2] svm: Add test cases around NMI injection Cathy Avery
@ 2020-04-09 13:32 ` Cathy Avery
  2020-04-09 13:48 ` [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests Paolo Bonzini
  2 siblings, 0 replies; 5+ messages in thread
From: Cathy Avery @ 2020-04-09 13:32 UTC (permalink / raw)
  To: kvm, pbonzini

This test checks for NMI delivery to L2 and
intercepted NMI (VMEXIT_NMI) delivery to L1
during an active HLT.

Signed-off-by: Cathy Avery <cavery@redhat.com>
---
 x86/svm_tests.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 103 insertions(+)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index d1dbdef..7d7c546 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -9,6 +9,7 @@
 #include "alloc_page.h"
 #include "isr.h"
 #include "apic.h"
+#include "delay.h"
 
 #define SVM_EXIT_MAX_DR_INTERCEPT 0x3f
 
@@ -1421,6 +1422,105 @@ static bool nmi_check(struct svm_test *test)
     return get_test_stage(test) == 3;
 }
 
+#define NMI_DELAY 100000000ULL
+
+static void nmi_message_thread(void *_test)
+{
+    struct svm_test *test = _test;
+
+    while (get_test_stage(test) != 1)
+        pause();
+
+    delay(NMI_DELAY);
+
+    apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, id_map[0]);
+
+    while (get_test_stage(test) != 2)
+        pause();
+
+    delay(NMI_DELAY);
+
+    apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, id_map[0]);
+}
+
+static void nmi_hlt_test(struct svm_test *test)
+{
+    long long start;
+
+    on_cpu_async(1, nmi_message_thread, test);
+
+    start = rdtsc();
+
+    set_test_stage(test, 1);
+
+    asm volatile ("hlt");
+
+    report((rdtsc() - start > NMI_DELAY) && nmi_fired,
+          "direct NMI + hlt");
+
+    if (!nmi_fired)
+        set_test_stage(test, -1);
+
+    nmi_fired = false;
+
+    vmmcall();
+
+    start = rdtsc();
+
+    set_test_stage(test, 2);
+
+    asm volatile ("hlt");
+
+    report((rdtsc() - start > NMI_DELAY) && nmi_fired,
+           "intercepted NMI + hlt");
+
+    if (!nmi_fired) {
+        report(nmi_fired, "intercepted pending NMI not dispatched");
+        set_test_stage(test, -1);
+    }
+
+    set_test_stage(test, 3);
+}
+
+static bool nmi_hlt_finished(struct svm_test *test)
+{
+    switch (get_test_stage(test)) {
+    case 1:
+        if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
+            report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
+                   vmcb->control.exit_code);
+            return true;
+        }
+        vmcb->save.rip += 3;
+
+        vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
+        break;
+
+    case 2:
+        if (vmcb->control.exit_code != SVM_EXIT_NMI) {
+            report(false, "VMEXIT not due to NMI intercept. Exit reason 0x%x",
+                   vmcb->control.exit_code);
+            return true;
+        }
+
+        report(true, "NMI intercept while running guest");
+        break;
+
+    case 3:
+        break;
+
+    default:
+        return true;
+    }
+
+    return get_test_stage(test) == 3;
+}
+
+static bool nmi_hlt_check(struct svm_test *test)
+{
+    return get_test_stage(test) == 3;
+}
+
 #define TEST(name) { #name, .v2 = name }
 
 /*
@@ -1530,6 +1630,9 @@ struct svm_test svm_tests[] = {
     { "nmi", default_supported, nmi_prepare,
       default_prepare_gif_clear, nmi_test,
       nmi_finished, nmi_check },
+    { "nmi_hlt", smp_supported, nmi_prepare,
+      default_prepare_gif_clear, nmi_hlt_test,
+      nmi_hlt_finished, nmi_hlt_check },
     TEST(svm_guest_state_test),
     { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 };
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests
  2020-04-09 13:32 [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests Cathy Avery
  2020-04-09 13:32 ` [PATCH kvm-unit-tests 1/2] svm: Add test cases around NMI injection Cathy Avery
  2020-04-09 13:32 ` [PATCH kvm-unit-tests 2/2] svm: Add test cases around NMI injection with HLT Cathy Avery
@ 2020-04-09 13:48 ` Paolo Bonzini
  2 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2020-04-09 13:48 UTC (permalink / raw)
  To: Cathy Avery, kvm

On 09/04/20 15:32, Cathy Avery wrote:
> Patch 1 is NMI injection and intercept. Patch 2 is the same test with guest in
> HLT.
> 
> Cathy Avery (2):
>   svm: Add test cases around NMI injection
>   svm: Add test cases around NMI injection with HLT
> 
>  x86/svm_tests.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 187 insertions(+)
> 

Looks good, apart from one nit in patch 1.  Using the LAPIC timer could
have been an alternative (which would also let the HLT test run on
uniprocessor guests), but there is certainly no issue with using an IPI
and making things a little more varied. :)

Paolo


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH kvm-unit-tests 1/2] svm: Add test cases around NMI injection
  2020-04-09 13:32 ` [PATCH kvm-unit-tests 1/2] svm: Add test cases around NMI injection Cathy Avery
@ 2020-04-09 13:49   ` Paolo Bonzini
  0 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2020-04-09 13:49 UTC (permalink / raw)
  To: Cathy Avery, kvm

On 09/04/20 15:32, Cathy Avery wrote:
> +static volatile bool nmi_fired;
> +
> +#define NMI_VECTOR    2
> +

This one is already defined, so it is not necessary to include the
#define here.

Paolo


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-04-09 13:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-09 13:32 [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests Cathy Avery
2020-04-09 13:32 ` [PATCH kvm-unit-tests 1/2] svm: Add test cases around NMI injection Cathy Avery
2020-04-09 13:49   ` Paolo Bonzini
2020-04-09 13:32 ` [PATCH kvm-unit-tests 2/2] svm: Add test cases around NMI injection with HLT Cathy Avery
2020-04-09 13:48 ` [PATCH kvm-unit-tests 0/2] svm: NMI injection and HLT tests Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.