From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, Sean Christopherson <seanjc@google.com>,
Santosh Shukla <santosh.shukla@amd.com>
Subject: [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest
Date: Wed, 5 Apr 2023 13:51:37 -0700 [thread overview]
Message-ID: <20230405205138.525310-2-seanjc@google.com> (raw)
In-Reply-To: <20230405205138.525310-1-seanjc@google.com>
Add a helper macro to dedup nSVM test code that handles fatal errors
by reporting the failure, setting the test stage to a magic number, and
invoking VMMCALL to bail to the host and terminate.
Note, the V_TPR fails if report() is invoked. Punt on the issue for
now as most users already report only failures, but leave a TODO for
future developers.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
x86/svm_tests.c | 127 ++++++++++++++++--------------------------------
1 file changed, 42 insertions(+), 85 deletions(-)
diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 27ce47b4..e87db3fa 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -947,6 +947,21 @@ static bool lat_svm_insn_check(struct svm_test *test)
return true;
}
+/*
+ * Report failures from SVM guest code, and on failure, set the stage to -1 and
+ * do VMMCALL to terminate the test (host side must treat -1 as "finished").
+ * TODO: fix the tests that don't play nice with a straight report, e.g. the
+ * V_TPR test fails if report() is invoked.
+ */
+#define report_svm_guest(cond, test, fmt, args...) \
+do { \
+ if (!(cond)) { \
+ report_fail("why didn't my format '" fmt "' format?", ##args);\
+ set_test_stage(test, -1); \
+ vmmcall(); \
+ } \
+} while (0)
+
bool pending_event_ipi_fired;
bool pending_event_guest_run;
@@ -1049,22 +1064,16 @@ static void pending_event_cli_prepare_gif_clear(struct svm_test *test)
static void pending_event_cli_test(struct svm_test *test)
{
- if (pending_event_ipi_fired == true) {
- set_test_stage(test, -1);
- report_fail("Interrupt preceeded guest");
- vmmcall();
- }
+ report_svm_guest(!pending_event_ipi_fired, test,
+ "IRQ should NOT be delivered while IRQs disabled");
/* VINTR_MASKING is zero. This should cause the IPI to fire. */
irq_enable();
asm volatile ("nop");
irq_disable();
- if (pending_event_ipi_fired != true) {
- set_test_stage(test, -1);
- report_fail("Interrupt not triggered by guest");
- }
-
+ report_svm_guest(pending_event_ipi_fired, test,
+ "IRQ should be delivered after enabling IRQs");
vmmcall();
/*
@@ -1079,11 +1088,9 @@ static void pending_event_cli_test(struct svm_test *test)
static bool pending_event_cli_finished(struct svm_test *test)
{
- if ( vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
- report_fail("VM_EXIT return to host is not EXIT_VMMCALL exit reason 0x%x",
- vmcb->control.exit_code);
- return true;
- }
+ report_svm_guest(vmcb->control.exit_code == SVM_EXIT_VMMCALL, test,
+ "Wanted VMMCALL VM-Exit, got ext reason 0x%x",
+ vmcb->control.exit_code);
switch (get_test_stage(test)) {
case 0:
@@ -1158,12 +1165,8 @@ static void interrupt_test(struct svm_test *test)
for (loops = 0; loops < 10000000 && !timer_fired; loops++)
asm volatile ("nop");
- report(timer_fired, "direct interrupt while running guest");
-
- if (!timer_fired) {
- set_test_stage(test, -1);
- vmmcall();
- }
+ report_svm_guest(timer_fired, test,
+ "direct interrupt while running guest");
apic_write(APIC_TMICT, 0);
irq_disable();
@@ -1174,12 +1177,8 @@ static void interrupt_test(struct svm_test *test)
for (loops = 0; loops < 10000000 && !timer_fired; loops++)
asm volatile ("nop");
- report(timer_fired, "intercepted interrupt while running guest");
-
- if (!timer_fired) {
- set_test_stage(test, -1);
- vmmcall();
- }
+ report_svm_guest(timer_fired, test,
+ "intercepted interrupt while running guest");
irq_enable();
apic_write(APIC_TMICT, 0);
@@ -1190,13 +1189,8 @@ static void interrupt_test(struct svm_test *test)
apic_write(APIC_TMICT, 1000000);
safe_halt();
- report(rdtsc() - start > 10000 && timer_fired,
- "direct interrupt + hlt");
-
- if (!timer_fired) {
- set_test_stage(test, -1);
- vmmcall();
- }
+ report_svm_guest(timer_fired, test, "direct interrupt + hlt");
+ report(rdtsc() - start > 10000, "IRQ arrived after expected delay");
apic_write(APIC_TMICT, 0);
irq_disable();
@@ -1207,13 +1201,8 @@ static void interrupt_test(struct svm_test *test)
apic_write(APIC_TMICT, 1000000);
asm volatile ("hlt");
- report(rdtsc() - start > 10000 && timer_fired,
- "intercepted interrupt + hlt");
-
- if (!timer_fired) {
- set_test_stage(test, -1);
- vmmcall();
- }
+ report_svm_guest(timer_fired, test, "intercepted interrupt + hlt");
+ report(rdtsc() - start > 10000, "IRQ arrived after expected delay");
apic_write(APIC_TMICT, 0);
irq_disable();
@@ -1287,10 +1276,7 @@ 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);
+ report_svm_guest(nmi_fired, test, "direct NMI while running guest");
vmmcall();
@@ -1298,11 +1284,7 @@ static void nmi_test(struct svm_test *test)
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);
- }
-
+ report_svm_guest(nmi_fired, test, "intercepted pending NMI delivered to guest");
}
static bool nmi_finished(struct svm_test *test)
@@ -1379,11 +1361,8 @@ static void nmi_hlt_test(struct svm_test *test)
asm volatile ("hlt");
- report((rdtsc() - start > NMI_DELAY) && nmi_fired,
- "direct NMI + hlt");
-
- if (!nmi_fired)
- set_test_stage(test, -1);
+ report_svm_guest(nmi_fired, test, "direct NMI + hlt");
+ report(rdtsc() - start > NMI_DELAY, "direct NMI after expected delay");
nmi_fired = false;
@@ -1395,14 +1374,8 @@ static void nmi_hlt_test(struct svm_test *test)
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);
- vmmcall();
- }
+ report_svm_guest(nmi_fired, test, "intercepted NMI + hlt");
+ report(rdtsc() - start > NMI_DELAY, "intercepted NMI after expected delay");
set_test_stage(test, 3);
}
@@ -1534,37 +1507,23 @@ static void virq_inject_prepare(struct svm_test *test)
static void virq_inject_test(struct svm_test *test)
{
- if (virq_fired) {
- report_fail("virtual interrupt fired before L2 sti");
- set_test_stage(test, -1);
- vmmcall();
- }
+ report_svm_guest(!virq_fired, test, "virtual IRQ blocked after L2 cli");
irq_enable();
asm volatile ("nop");
irq_disable();
- if (!virq_fired) {
- report_fail("virtual interrupt not fired after L2 sti");
- set_test_stage(test, -1);
- }
+ report_svm_guest(virq_fired, test, "virtual IRQ fired after L2 sti");
vmmcall();
- if (virq_fired) {
- report_fail("virtual interrupt fired before L2 sti after VINTR intercept");
- set_test_stage(test, -1);
- vmmcall();
- }
+ report_svm_guest(!virq_fired, test, "intercepted VINTR blocked after L2 cli");
irq_enable();
asm volatile ("nop");
irq_disable();
- if (!virq_fired) {
- report_fail("virtual interrupt not fired after return from VINTR intercept");
- set_test_stage(test, -1);
- }
+ report_svm_guest(virq_fired, test, "intercepted VINTR fired after L2 sti");
vmmcall();
@@ -1572,10 +1531,8 @@ static void virq_inject_test(struct svm_test *test)
asm volatile ("nop");
irq_disable();
- if (virq_fired) {
- report_fail("virtual interrupt fired when V_IRQ_PRIO less than V_TPR");
- set_test_stage(test, -1);
- }
+ report_svm_guest(!virq_fired, test,
+ "virtual IRQ blocked V_IRQ_PRIO less than V_TPR");
vmmcall();
vmmcall();
--
2.40.0.348.gf938b09366-goog
next prev parent reply other threads:[~2023-04-05 20:51 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-05 20:51 [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase Sean Christopherson
2023-04-05 20:51 ` Sean Christopherson [this message]
2023-04-06 8:31 ` [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest Mathias Krause
2023-04-06 16:31 ` Sean Christopherson
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 2/2] x86: nSVM: Add support for VNMI test Sean Christopherson
2023-04-06 10:42 ` Santosh Shukla
2023-06-07 23:26 ` [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230405205138.525310-2-seanjc@google.com \
--to=seanjc@google.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=santosh.shukla@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.