* [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase
@ 2023-04-05 20:51 Sean Christopherson
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest Sean Christopherson
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Sean Christopherson @ 2023-04-05 20:51 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Santosh Shukla
Santosh's vNMI test, plus a prep patch to dedup a pile of copy+paste code
in the SVM test for handling fatal errors in the guest.
Santosh, can you check that I didn't break anything in the vNMI test? I
don't have access to the necessary hardware.
Thanks!
Santosh Shukla (1):
x86: nSVM: Add support for VNMI test
Sean Christopherson (1):
nSVM: Add helper to report fatal errors in guest
lib/x86/processor.h | 1 +
x86/svm.c | 5 ++
x86/svm.h | 8 ++
x86/svm_tests.c | 205 ++++++++++++++++++++++++++------------------
4 files changed, 134 insertions(+), 85 deletions(-)
base-commit: 723a5703848d91f7aea8bc01d12fe8b1a6fc2391
--
2.40.0.348.gf938b09366-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest
2023-04-05 20:51 [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase Sean Christopherson
@ 2023-04-05 20:51 ` Sean Christopherson
2023-04-06 8:31 ` Mathias Krause
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 2/2] x86: nSVM: Add support for VNMI test Sean Christopherson
2023-06-07 23:26 ` [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase Sean Christopherson
2 siblings, 1 reply; 7+ messages in thread
From: Sean Christopherson @ 2023-04-05 20:51 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Santosh Shukla
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [kvm-unit-tests PATCH v4 2/2] x86: nSVM: Add support for VNMI test
2023-04-05 20:51 [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase Sean Christopherson
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest Sean Christopherson
@ 2023-04-05 20:51 ` 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
2 siblings, 1 reply; 7+ messages in thread
From: Sean Christopherson @ 2023-04-05 20:51 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Santosh Shukla
From: Santosh Shukla <santosh.shukla@amd.com>
Add a VNMI test case to test Virtual NMI in a nested environment,
The test covers the Virtual NMI (VNMI) delivery.
Signed-off-by: Santosh Shukla <santosh.shukla@amd.com>
[sean: reuse pieces of NMI test framework, fix formatting issues]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
lib/x86/processor.h | 1 +
x86/svm.c | 5 +++
x86/svm.h | 8 +++++
x86/svm_tests.c | 78 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 92 insertions(+)
diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 3d58ef72..3802c1e2 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -267,6 +267,7 @@ static inline bool is_intel(void)
#define X86_FEATURE_PAUSEFILTER (CPUID(0x8000000A, 0, EDX, 10))
#define X86_FEATURE_PFTHRESHOLD (CPUID(0x8000000A, 0, EDX, 12))
#define X86_FEATURE_VGIF (CPUID(0x8000000A, 0, EDX, 16))
+#define X86_FEATURE_V_NMI (CPUID(0x8000000A, 0, EDX, 25))
#define X86_FEATURE_AMD_PMU_V2 (CPUID(0x80000022, 0, EAX, 0))
static inline bool this_cpu_has(u64 feature)
diff --git a/x86/svm.c b/x86/svm.c
index ba435b4a..022a0fde 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -99,6 +99,11 @@ bool npt_supported(void)
return this_cpu_has(X86_FEATURE_NPT);
}
+bool vnmi_supported(void)
+{
+ return this_cpu_has(X86_FEATURE_V_NMI);
+}
+
int get_test_stage(struct svm_test *test)
{
barrier();
diff --git a/x86/svm.h b/x86/svm.h
index 766ff7e3..4631c2ff 100644
--- a/x86/svm.h
+++ b/x86/svm.h
@@ -131,6 +131,13 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
#define V_INTR_MASKING_SHIFT 24
#define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
+#define V_NMI_PENDING_SHIFT 11
+#define V_NMI_PENDING_MASK (1 << V_NMI_PENDING_SHIFT)
+#define V_NMI_BLOCKING_SHIFT 12
+#define V_NMI_BLOCKING_MASK (1 << V_NMI_BLOCKING_SHIFT)
+#define V_NMI_ENABLE_SHIFT 26
+#define V_NMI_ENABLE_MASK (1 << V_NMI_ENABLE_SHIFT)
+
#define SVM_INTERRUPT_SHADOW_MASK 1
#define SVM_IOIO_STR_SHIFT 2
@@ -419,6 +426,7 @@ void default_prepare(struct svm_test *test);
void default_prepare_gif_clear(struct svm_test *test);
bool default_finished(struct svm_test *test);
bool npt_supported(void);
+bool vnmi_supported(void);
int get_test_stage(struct svm_test *test);
void set_test_stage(struct svm_test *test, int s);
void inc_test_stage(struct svm_test *test);
diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index e87db3fa..3d2ca0f6 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -1419,6 +1419,81 @@ static bool nmi_hlt_check(struct svm_test *test)
return get_test_stage(test) == 3;
}
+static void vnmi_prepare(struct svm_test *test)
+{
+ nmi_prepare(test);
+
+ /*
+ * Disable NMI interception to start. Enabling vNMI without
+ * intercepting "real" NMIs should result in an ERR VM-Exit.
+ */
+ vmcb->control.intercept &= ~(1ULL << INTERCEPT_NMI);
+ vmcb->control.int_ctl = V_NMI_ENABLE_MASK;
+ vmcb->control.int_vector = NMI_VECTOR;
+}
+
+static void vnmi_test(struct svm_test *test)
+{
+ report_svm_guest(!nmi_fired, test, "No vNMI before injection");
+ vmmcall();
+
+ report_svm_guest(nmi_fired, test, "vNMI delivered after injection");
+ vmmcall();
+}
+
+static bool vnmi_finished(struct svm_test *test)
+{
+ switch (get_test_stage(test)) {
+ case 0:
+ if (vmcb->control.exit_code != SVM_EXIT_ERR) {
+ report_fail("Wanted ERR VM-Exit, got 0x%x",
+ vmcb->control.exit_code);
+ return true;
+ }
+ report(!nmi_fired, "vNMI enabled but NMI_INTERCEPT unset!");
+ vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
+ vmcb->save.rip += 3;
+ break;
+
+ case 1:
+ if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
+ report_fail("Wanted VMMCALL VM-Exit, got 0x%x",
+ vmcb->control.exit_code);
+ return true;
+ }
+ report(!nmi_fired, "vNMI with vector 2 not injected");
+ vmcb->control.int_ctl |= V_NMI_PENDING_MASK;
+ vmcb->save.rip += 3;
+ break;
+
+ case 2:
+ if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
+ report_fail("Wanted VMMCALL VM-Exit, got 0x%x",
+ vmcb->control.exit_code);
+ return true;
+ }
+ if (vmcb->control.int_ctl & V_NMI_BLOCKING_MASK) {
+ report_fail("V_NMI_BLOCKING_MASK not cleared on VMEXIT");
+ return true;
+ }
+ report_pass("VNMI serviced");
+ vmcb->save.rip += 3;
+ break;
+
+ default:
+ return true;
+ }
+
+ inc_test_stage(test);
+
+ return get_test_stage(test) == 3;
+}
+
+static bool vnmi_check(struct svm_test *test)
+{
+ return get_test_stage(test) == 3;
+}
+
static volatile int count_exc = 0;
static void my_isr(struct ex_regs *r)
@@ -3298,6 +3373,9 @@ struct svm_test svm_tests[] = {
{ "nmi_hlt", smp_supported, nmi_prepare,
default_prepare_gif_clear, nmi_hlt_test,
nmi_hlt_finished, nmi_hlt_check },
+ { "vnmi", vnmi_supported, vnmi_prepare,
+ default_prepare_gif_clear, vnmi_test,
+ vnmi_finished, vnmi_check },
{ "virq_inject", default_supported, virq_inject_prepare,
default_prepare_gif_clear, virq_inject_test,
virq_inject_finished, virq_inject_check },
--
2.40.0.348.gf938b09366-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest Sean Christopherson
@ 2023-04-06 8:31 ` Mathias Krause
2023-04-06 16:31 ` Sean Christopherson
0 siblings, 1 reply; 7+ messages in thread
From: Mathias Krause @ 2023-04-06 8:31 UTC (permalink / raw)
To: Sean Christopherson; +Cc: kvm, Santosh Shukla, Paolo Bonzini
On 05.04.23 22:51, Sean Christopherson wrote:
> 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);\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Debug artifact? Should probably be this instead (making use of C99):
#define report_svm_guest(cond, test, fmt,...) \
do { \
if (!(cond)) { \
report_fail((fmt), ##__VA_ARGS__); \
set_test_stage((test), -1); \
vmmcall(); \
} \
} while (0)
> + 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();
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [kvm-unit-tests PATCH v4 2/2] x86: nSVM: Add support for VNMI test
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
0 siblings, 0 replies; 7+ messages in thread
From: Santosh Shukla @ 2023-04-06 10:42 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, Santosh Shukla
Hi Sean,
On 4/6/2023 2:21 AM, Sean Christopherson wrote:
> From: Santosh Shukla <santosh.shukla@amd.com>
>
> Add a VNMI test case to test Virtual NMI in a nested environment,
> The test covers the Virtual NMI (VNMI) delivery.
>
> Signed-off-by: Santosh Shukla <santosh.shukla@amd.com>
> [sean: reuse pieces of NMI test framework, fix formatting issues]
> Signed-off-by: Sean Christopherson <seanjc@google.com>
Tested on Genoa system, Test passed, Thank-you!.,
Renaming comment inline -
> ---
> lib/x86/processor.h | 1 +
> x86/svm.c | 5 +++
> x86/svm.h | 8 +++++
> x86/svm_tests.c | 78 +++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 92 insertions(+)
>
> diff --git a/lib/x86/processor.h b/lib/x86/processor.h
> index 3d58ef72..3802c1e2 100644
> --- a/lib/x86/processor.h
> +++ b/lib/x86/processor.h
> @@ -267,6 +267,7 @@ static inline bool is_intel(void)
> #define X86_FEATURE_PAUSEFILTER (CPUID(0x8000000A, 0, EDX, 10))
> #define X86_FEATURE_PFTHRESHOLD (CPUID(0x8000000A, 0, EDX, 12))
> #define X86_FEATURE_VGIF (CPUID(0x8000000A, 0, EDX, 16))
> +#define X86_FEATURE_V_NMI (CPUID(0x8000000A, 0, EDX, 25))
s/X86_FEATURE_V_NMI/X86_FEATURE_VNMI
> #define X86_FEATURE_AMD_PMU_V2 (CPUID(0x80000022, 0, EAX, 0))
>
> static inline bool this_cpu_has(u64 feature)
> diff --git a/x86/svm.c b/x86/svm.c
> index ba435b4a..022a0fde 100644
> --- a/x86/svm.c
> +++ b/x86/svm.c
> @@ -99,6 +99,11 @@ bool npt_supported(void)
> return this_cpu_has(X86_FEATURE_NPT);
> }
>
> +bool vnmi_supported(void)
> +{
> + return this_cpu_has(X86_FEATURE_V_NMI);
ditto..
Thanks,
Santosh
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest
2023-04-06 8:31 ` Mathias Krause
@ 2023-04-06 16:31 ` Sean Christopherson
0 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2023-04-06 16:31 UTC (permalink / raw)
To: Mathias Krause; +Cc: kvm, Santosh Shukla, Paolo Bonzini
On Thu, Apr 06, 2023, Mathias Krause wrote:
> On 05.04.23 22:51, Sean Christopherson wrote:
> > 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);\
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Debug artifact? Should probably be this instead (making use of C99):
Yes. I'm just glad I posted the PG version and not the rated R version.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase
2023-04-05 20:51 [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase Sean Christopherson
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest Sean Christopherson
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 2/2] x86: nSVM: Add support for VNMI test Sean Christopherson
@ 2023-06-07 23:26 ` Sean Christopherson
2 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2023-06-07 23:26 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, Santosh Shukla
On Wed, 05 Apr 2023 13:51:36 -0700, Sean Christopherson wrote:
> Santosh's vNMI test, plus a prep patch to dedup a pile of copy+paste code
> in the SVM test for handling fatal errors in the guest.
>
> Santosh, can you check that I didn't break anything in the vNMI test? I
> don't have access to the necessary hardware.
>
> Thanks!
>
> [...]
Applied to kvm-x86 next, with fixups for the goofs pointed out by Mathias and
Santosh.
[1/2] nSVM: Add helper to report fatal errors in guest
https://github.com/kvm-x86/kvm-unit-tests/commit/76c60c49ebfd
[2/2] x86: nSVM: Add support for VNMI test
https://github.com/kvm-x86/kvm-unit-tests/commit/928fec073045
--
https://github.com/kvm-x86/kvm-unit-tests/tree/next
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-06-07 23:29 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-05 20:51 [kvm-unit-tests PATCH v4 0/2] nSVM: vNMI testcase Sean Christopherson
2023-04-05 20:51 ` [kvm-unit-tests PATCH v4 1/2] nSVM: Add helper to report fatal errors in guest Sean Christopherson
2023-04-06 8:31 ` 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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).