kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests
@ 2022-10-05 23:52 Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 1/9] nVMX: Add "nop" after setting EFLAGS.TF to guarantee single-step #DB Sean Christopherson
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

This is a continuation of Manali's series[*] to add nSVM exception routing
tests.  The functionality is largely the same, but instead of copy+pasting
nVMX tests (and vice versa), move the helpers that generate exceptions to
processor.h so that at least the gory details can be shared.

An added bonus is that by consolidating code, nVMX can do some of the same
cleanups that Manali's patches do for nSVM, e.g. move more testcases to
the generic framework and drop fully redundant tests.

https://lore.kernel.org/all/20220810050738.7442-1-manali.shukla@amd.com

Manali Shukla (4):
  x86: nSVM: Add an exception test framework and tests
  x86: nSVM: Move #BP test to exception test framework
  x86: nSVM: Move #OF test to exception test framework
  x86: nSVM: Move part of #NM test to exception test framework

Sean Christopherson (5):
  nVMX: Add "nop" after setting EFLAGS.TF to guarantee single-step #DB
  x86: Move helpers to generate misc exceptions to processor.h
  nVMX: Move #OF test to generic exceptions test
  nVMX: Drop one-off INT3=>#BP test
  nVMX: Move #NM test to generic exception test framework

 lib/x86/processor.h |  97 ++++++++++++++++++++
 x86/svm_tests.c     | 195 ++++++++++++++++++----------------------
 x86/vmx_tests.c     | 214 ++++++--------------------------------------
 3 files changed, 210 insertions(+), 296 deletions(-)


base-commit: d8a4f9e5e8d69d4ef257b40d6cd666bd2f63494e
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 1/9] nVMX: Add "nop" after setting EFLAGS.TF to guarantee single-step #DB
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 2/9] x86: Move helpers to generate misc exceptions to processor.h Sean Christopherson
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

Add a "nop" after enabling single-stepping in vmx_l2_db_test() to ensure
a #DB is generated in the scope of the function even if the helper is
inlined.  Enabling single-step #DBs have a one-instruction delay, e.g. if
the function were inlined and the caller generated a "terminal" VM-Exit
immediately after invoking the helper, then no #DB would be generated.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/vmx_tests.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index aa2ecbb..3e3d699 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -10745,6 +10745,7 @@ static void vmx_l2_bp_test(void)
 static void vmx_l2_db_test(void)
 {
 	write_rflags(read_rflags() | X86_EFLAGS_TF);
+	asm volatile("nop");
 }
 
 static uint64_t usermode_callback(void)
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 2/9] x86: Move helpers to generate misc exceptions to processor.h
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 1/9] nVMX: Add "nop" after setting EFLAGS.TF to guarantee single-step #DB Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 3/9] nVMX: Move #OF test to generic exceptions test Sean Christopherson
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

Move nested VMX's helpers to generate miscellaenous exceptions, e.g. #DE,
to processor.h so that they can be used for nearly-identical nested SVM
tests.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/processor.h | 43 +++++++++++++++++++++++++++++++++++
 x86/vmx_tests.c     | 55 +++++----------------------------------------
 2 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 0324220..c3d112f 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -791,6 +791,49 @@ static inline void flush_tlb(void)
 	write_cr4(cr4);
 }
 
+static inline void generate_non_canonical_gp(void)
+{
+	*(volatile u64 *)NONCANONICAL = 0;
+}
+
+static inline void generate_ud(void)
+{
+	asm volatile ("ud2");
+}
+
+static inline void generate_de(void)
+{
+	asm volatile (
+		"xor %%eax, %%eax\n\t"
+		"xor %%ebx, %%ebx\n\t"
+		"xor %%edx, %%edx\n\t"
+		"idiv %%ebx\n\t"
+		::: "eax", "ebx", "edx");
+}
+
+static inline void generate_bp(void)
+{
+	asm volatile ("int3");
+}
+
+static inline void generate_single_step_db(void)
+{
+	write_rflags(read_rflags() | X86_EFLAGS_TF);
+	asm volatile("nop");
+}
+
+static inline uint64_t generate_usermode_ac(void)
+{
+	/*
+	 * Trigger an #AC by writing 8 bytes to a 4-byte aligned address.
+	 * Disclaimer: It is assumed that the stack pointer is aligned
+	 * on a 16-byte boundary as x86_64 stacks should be.
+	 */
+	asm volatile("movq $0, -0x4(%rsp)");
+
+	return 0;
+}
+
 static inline u8 pmu_version(void)
 {
 	return cpuid(10).a & 0xff;
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 3e3d699..2ed20ec 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -10717,49 +10717,6 @@ static void vmx_pf_vpid_test(void)
 	__vmx_pf_vpid_test(invalidate_tlb_new_vpid, 1);
 }
 
-static void vmx_l2_gp_test(void)
-{
-	*(volatile u64 *)NONCANONICAL = 0;
-}
-
-static void vmx_l2_ud_test(void)
-{
-	asm volatile ("ud2");
-}
-
-static void vmx_l2_de_test(void)
-{
-	asm volatile (
-		"xor %%eax, %%eax\n\t"
-		"xor %%ebx, %%ebx\n\t"
-		"xor %%edx, %%edx\n\t"
-		"idiv %%ebx\n\t"
-		::: "eax", "ebx", "edx");
-}
-
-static void vmx_l2_bp_test(void)
-{
-	asm volatile ("int3");
-}
-
-static void vmx_l2_db_test(void)
-{
-	write_rflags(read_rflags() | X86_EFLAGS_TF);
-	asm volatile("nop");
-}
-
-static uint64_t usermode_callback(void)
-{
-	/*
-	 * Trigger an #AC by writing 8 bytes to a 4-byte aligned address.
-	 * Disclaimer: It is assumed that the stack pointer is aligned
-	 * on a 16-byte boundary as x86_64 stacks should be.
-	 */
-	asm volatile("movq $0, -0x4(%rsp)");
-
-	return 0;
-}
-
 static void vmx_l2_ac_test(void)
 {
 	bool hit_ac = false;
@@ -10767,7 +10724,7 @@ static void vmx_l2_ac_test(void)
 	write_cr0(read_cr0() | X86_CR0_AM);
 	write_rflags(read_rflags() | X86_EFLAGS_AC);
 
-	run_in_user(usermode_callback, AC_VECTOR, 0, 0, 0, 0, &hit_ac);
+	run_in_user(generate_usermode_ac, AC_VECTOR, 0, 0, 0, 0, &hit_ac);
 	report(hit_ac, "Usermode #AC handled in L2");
 	vmcall();
 }
@@ -10778,11 +10735,11 @@ struct vmx_exception_test {
 };
 
 struct vmx_exception_test vmx_exception_tests[] = {
-	{ GP_VECTOR, vmx_l2_gp_test },
-	{ UD_VECTOR, vmx_l2_ud_test },
-	{ DE_VECTOR, vmx_l2_de_test },
-	{ DB_VECTOR, vmx_l2_db_test },
-	{ BP_VECTOR, vmx_l2_bp_test },
+	{ GP_VECTOR, generate_non_canonical_gp },
+	{ UD_VECTOR, generate_ud },
+	{ DE_VECTOR, generate_de },
+	{ DB_VECTOR, generate_single_step_db },
+	{ BP_VECTOR, generate_bp },
 	{ AC_VECTOR, vmx_l2_ac_test },
 };
 
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 3/9] nVMX: Move #OF test to generic exceptions test
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 1/9] nVMX: Add "nop" after setting EFLAGS.TF to guarantee single-step #DB Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 2/9] x86: Move helpers to generate misc exceptions to processor.h Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 4/9] nVMX: Drop one-off INT3=>#BP test Sean Christopherson
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

Move the INTO=>#OF test, along with its more precise checking of the
exit interrupt info, to the generic nVMX exceptions test.

Move the  helper that generates #OF to processor.h so that it can be
reused by nSVM for an identical test.

Note, this effectively adds new checks for all other vectors, i.e.
affects more vectors than just #OF.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/processor.h | 35 +++++++++++++++++++++++
 x86/vmx_tests.c     | 67 +++++++++------------------------------------
 2 files changed, 48 insertions(+), 54 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index c3d112f..5865933 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -834,6 +834,41 @@ static inline uint64_t generate_usermode_ac(void)
 	return 0;
 }
 
+/*
+ * Switch from 64-bit to 32-bit mode and generate #OF via INTO.  Note, if RIP
+ * or RSP holds a 64-bit value, this helper will NOT generate #OF.
+ */
+static inline void generate_of(void)
+{
+	struct far_pointer32 fp = {
+		.offset = (uintptr_t)&&into,
+		.selector = KERNEL_CS32,
+	};
+	uintptr_t rsp;
+
+	asm volatile ("mov %%rsp, %0" : "=r"(rsp));
+
+	if (fp.offset != (uintptr_t)&&into) {
+		printf("Code address too high.\n");
+		return;
+	}
+	if ((u32)rsp != rsp) {
+		printf("Stack address too high.\n");
+		return;
+	}
+
+	asm goto ("lcall *%0" : : "m" (fp) : "rax" : into);
+	return;
+into:
+	asm volatile (".code32;"
+		      "movl $0x7fffffff, %eax;"
+		      "addl %eax, %eax;"
+		      "into;"
+		      "lret;"
+		      ".code64");
+	__builtin_unreachable();
+}
+
 static inline u8 pmu_version(void)
 {
 	return cpuid(10).a & 0xff;
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 2ed20ec..edb8062 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -2161,57 +2161,6 @@ static int int3_exit_handler(union exit_reason exit_reason)
 	return VMX_TEST_VMEXIT;
 }
 
-static int into_init(struct vmcs *vmcs)
-{
-	vmcs_write(EXC_BITMAP, ~0u);
-	return VMX_TEST_START;
-}
-
-static void into_guest_main(void)
-{
-	struct far_pointer32 fp = {
-		.offset = (uintptr_t)&&into,
-		.selector = KERNEL_CS32,
-	};
-	uintptr_t rsp;
-
-	asm volatile ("mov %%rsp, %0" : "=r"(rsp));
-
-	if (fp.offset != (uintptr_t)&&into) {
-		printf("Code address too high.\n");
-		return;
-	}
-	if ((u32)rsp != rsp) {
-		printf("Stack address too high.\n");
-		return;
-	}
-
-	asm goto ("lcall *%0" : : "m" (fp) : "rax" : into);
-	return;
-into:
-	asm volatile (".code32;"
-		      "movl $0x7fffffff, %eax;"
-		      "addl %eax, %eax;"
-		      "into;"
-		      "lret;"
-		      ".code64");
-	__builtin_unreachable();
-}
-
-static int into_exit_handler(union exit_reason exit_reason)
-{
-	u32 intr_info = vmcs_read(EXI_INTR_INFO);
-
-	report(exit_reason.basic == VMX_EXC_NMI &&
-	       (intr_info & INTR_INFO_VALID_MASK) &&
-	       (intr_info & INTR_INFO_VECTOR_MASK) == OF_VECTOR &&
-	       ((intr_info & INTR_INFO_INTR_TYPE_MASK) >>
-	        INTR_INFO_INTR_TYPE_SHIFT) == VMX_INTR_TYPE_SOFT_EXCEPTION,
-	       "L1 intercepts #OF");
-
-	return VMX_TEST_VMEXIT;
-}
-
 static void exit_monitor_from_l2_main(void)
 {
 	printf("Calling exit(0) from l2...\n");
@@ -10741,6 +10690,7 @@ struct vmx_exception_test vmx_exception_tests[] = {
 	{ DB_VECTOR, generate_single_step_db },
 	{ BP_VECTOR, generate_bp },
 	{ AC_VECTOR, vmx_l2_ac_test },
+	{ OF_VECTOR, generate_of },
 };
 
 static u8 vmx_exception_test_vector;
@@ -10769,14 +10719,24 @@ static void handle_exception_in_l2(u8 vector)
 static void handle_exception_in_l1(u32 vector)
 {
 	u32 old_eb = vmcs_read(EXC_BITMAP);
+	u32 intr_type;
+	u32 intr_info;
 
 	vmcs_write(EXC_BITMAP, old_eb | (1u << vector));
 
 	enter_guest();
 
+	if (vector == BP_VECTOR || vector == OF_VECTOR)
+		intr_type = VMX_INTR_TYPE_SOFT_EXCEPTION;
+	else
+		intr_type = VMX_INTR_TYPE_HARD_EXCEPTION;
+
+	intr_info = vmcs_read(EXI_INTR_INFO);
 	report((vmcs_read(EXI_REASON) == VMX_EXC_NMI) &&
-	       ((vmcs_read(EXI_INTR_INFO) & 0xff) == vector),
-	       "%s handled by L1", exception_mnemonic(vector));
+	       (intr_info & INTR_INFO_VALID_MASK) &&
+	       (intr_info & INTR_INFO_VECTOR_MASK) == vector &&
+	       ((intr_info & INTR_INFO_INTR_TYPE_MASK) >> INTR_INFO_INTR_TYPE_SHIFT) == intr_type,
+	       "%s correctly routed to L1", exception_mnemonic(vector));
 
 	vmcs_write(EXC_BITMAP, old_eb);
 }
@@ -10836,7 +10796,6 @@ struct vmx_test vmx_tests[] = {
 	{ "disable RDTSCP", disable_rdtscp_init, disable_rdtscp_main,
 		disable_rdtscp_exit_handler, NULL, {0} },
 	{ "int3", int3_init, int3_guest_main, int3_exit_handler, NULL, {0} },
-	{ "into", into_init, into_guest_main, into_exit_handler, NULL, {0} },
 	{ "exit_monitor_from_l2_test", NULL, exit_monitor_from_l2_main,
 		exit_monitor_from_l2_handler, NULL, {0} },
 	{ "invalid_msr", invalid_msr_init, invalid_msr_main,
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 4/9] nVMX: Drop one-off INT3=>#BP test
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
                   ` (2 preceding siblings ...)
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 3/9] nVMX: Move #OF test to generic exceptions test Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 5/9] x86: nSVM: Add an exception test framework and tests Sean Christopherson
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

Drop the dedicated INT3=>#BP test, it's a subset of what is covered by
the INT3=>#BP case in the generic exceptions test.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/vmx_tests.c | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index edb8062..368ad43 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -2136,31 +2136,6 @@ static int disable_rdtscp_exit_handler(union exit_reason exit_reason)
 	return VMX_TEST_VMEXIT;
 }
 
-static int int3_init(struct vmcs *vmcs)
-{
-	vmcs_write(EXC_BITMAP, ~0u);
-	return VMX_TEST_START;
-}
-
-static void int3_guest_main(void)
-{
-	asm volatile ("int3");
-}
-
-static int int3_exit_handler(union exit_reason exit_reason)
-{
-	u32 intr_info = vmcs_read(EXI_INTR_INFO);
-
-	report(exit_reason.basic == VMX_EXC_NMI &&
-	       (intr_info & INTR_INFO_VALID_MASK) &&
-	       (intr_info & INTR_INFO_VECTOR_MASK) == BP_VECTOR &&
-	       ((intr_info & INTR_INFO_INTR_TYPE_MASK) >>
-	        INTR_INFO_INTR_TYPE_SHIFT) == VMX_INTR_TYPE_SOFT_EXCEPTION,
-	       "L1 intercepts #BP");
-
-	return VMX_TEST_VMEXIT;
-}
-
 static void exit_monitor_from_l2_main(void)
 {
 	printf("Calling exit(0) from l2...\n");
@@ -10795,7 +10770,6 @@ struct vmx_test vmx_tests[] = {
 	{ "vmmcall", vmmcall_init, vmmcall_main, vmmcall_exit_handler, NULL, {0} },
 	{ "disable RDTSCP", disable_rdtscp_init, disable_rdtscp_main,
 		disable_rdtscp_exit_handler, NULL, {0} },
-	{ "int3", int3_init, int3_guest_main, int3_exit_handler, NULL, {0} },
 	{ "exit_monitor_from_l2_test", NULL, exit_monitor_from_l2_main,
 		exit_monitor_from_l2_handler, NULL, {0} },
 	{ "invalid_msr", invalid_msr_init, invalid_msr_main,
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 5/9] x86: nSVM: Add an exception test framework and tests
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
                   ` (3 preceding siblings ...)
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 4/9] nVMX: Drop one-off INT3=>#BP test Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 6/9] x86: nSVM: Move #BP test to exception test framework Sean Christopherson
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

From: Manali Shukla <manali.shukla@amd.com>

Copy nVMX's test that verifies an exception occurring in L2 is
forwarded to the right place (L1 or L2).

The test verifies two conditions for each exception.
1) Exception generated in L2, is handled by L2 when L2 exception handler
   is registered.
2) Exception generated in L2, is handled by L1 when intercept exception
   bit map is set in L1.

Note, v2 SVM tests have no parameters, but the SVM framework doesn't
differentiate between v1 and v2 when setting the guest code.  Fudge
around this shortcoming by casting to test_guest_func when invoking
test_set_guest().

Signed-off-by: Manali Shukla <manali.shukla@amd.com>
[sean: use common helpers to generate exception, call out this copies nVMX]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/svm_tests.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index e2ec954..805b2e0 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -10,6 +10,7 @@
 #include "isr.h"
 #include "apic.h"
 #include "delay.h"
+#include "x86/usermode.h"
 
 #define SVM_EXIT_MAX_DR_INTERCEPT 0x3f
 
@@ -3289,6 +3290,81 @@ static void svm_intr_intercept_mix_smi(void)
 	svm_intr_intercept_mix_run_guest(NULL, SVM_EXIT_SMI);
 }
 
+static void svm_l2_ac_test(void)
+{
+	bool hit_ac = false;
+
+	write_cr0(read_cr0() | X86_CR0_AM);
+	write_rflags(read_rflags() | X86_EFLAGS_AC);
+
+	run_in_user(generate_usermode_ac, AC_VECTOR, 0, 0, 0, 0, &hit_ac);
+	report(hit_ac, "Usermode #AC handled in L2");
+	vmmcall();
+}
+
+struct svm_exception_test {
+	u8 vector;
+	void (*guest_code)(void);
+};
+
+struct svm_exception_test svm_exception_tests[] = {
+	{ GP_VECTOR, generate_non_canonical_gp },
+	{ UD_VECTOR, generate_ud },
+	{ DE_VECTOR, generate_de },
+	{ DB_VECTOR, generate_single_step_db },
+	{ AC_VECTOR, svm_l2_ac_test },
+};
+
+static u8 svm_exception_test_vector;
+
+static void svm_exception_handler(struct ex_regs *regs)
+{
+	report(regs->vector == svm_exception_test_vector,
+		"Handling %s in L2's exception handler",
+		exception_mnemonic(svm_exception_test_vector));
+	vmmcall();
+}
+
+static void handle_exception_in_l2(u8 vector)
+{
+	handler old_handler = handle_exception(vector, svm_exception_handler);
+	svm_exception_test_vector = vector;
+
+	report(svm_vmrun() == SVM_EXIT_VMMCALL,
+		"%s handled by L2", exception_mnemonic(vector));
+
+	handle_exception(vector, old_handler);
+}
+
+static void handle_exception_in_l1(u32 vector)
+{
+	u32 old_ie = vmcb->control.intercept_exceptions;
+
+	vmcb->control.intercept_exceptions |= (1ULL << vector);
+
+	report(svm_vmrun() == (SVM_EXIT_EXCP_BASE + vector),
+		"%s handled by L1",  exception_mnemonic(vector));
+
+	vmcb->control.intercept_exceptions = old_ie;
+}
+
+static void svm_exception_test(void)
+{
+	struct svm_exception_test *t;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(svm_exception_tests); i++) {
+		t = &svm_exception_tests[i];
+		test_set_guest((test_guest_func)t->guest_code);
+
+		handle_exception_in_l2(t->vector);
+		vmcb_ident(vmcb);
+
+		handle_exception_in_l1(t->vector);
+		vmcb_ident(vmcb);
+	}
+}
+
 struct svm_test svm_tests[] = {
 	{ "null", default_supported, default_prepare,
 	  default_prepare_gif_clear, null_test,
@@ -3389,6 +3465,7 @@ struct svm_test svm_tests[] = {
 	TEST(svm_nm_test),
 	TEST(svm_int3_test),
 	TEST(svm_into_test),
+	TEST(svm_exception_test),
 	TEST(svm_lbrv_test0),
 	TEST(svm_lbrv_test1),
 	TEST(svm_lbrv_test2),
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 6/9] x86: nSVM: Move #BP test to exception test framework
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
                   ` (4 preceding siblings ...)
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 5/9] x86: nSVM: Add an exception test framework and tests Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 7/9] x86: nSVM: Move #OF " Sean Christopherson
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

From: Manali Shukla <manali.shukla@amd.com>

Remove boiler plate code for #BP test and move #BP exception test into
the exception test framework.

Signed-off-by: Manali Shukla <manali.shukla@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/svm_tests.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 805b2e0..1285f98 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -2804,26 +2804,6 @@ static void svm_into_test(void)
 	       "#OF is generated in L2 exception handler");
 }
 
-static int bp_test_counter;
-
-static void guest_test_bp_handler(struct ex_regs *r)
-{
-	bp_test_counter++;
-}
-
-static void svm_bp_test_guest(struct svm_test *test)
-{
-	asm volatile("int3");
-}
-
-static void svm_int3_test(void)
-{
-	handle_exception(BP_VECTOR, guest_test_bp_handler);
-	test_set_guest(svm_bp_test_guest);
-	report(svm_vmrun() == SVM_EXIT_VMMCALL && bp_test_counter == 1,
-	       "#BP is handled in L2 exception handler");
-}
-
 static int nm_test_counter;
 
 static void guest_test_nm_handler(struct ex_regs *r)
@@ -3312,6 +3292,7 @@ struct svm_exception_test svm_exception_tests[] = {
 	{ UD_VECTOR, generate_ud },
 	{ DE_VECTOR, generate_de },
 	{ DB_VECTOR, generate_single_step_db },
+	{ BP_VECTOR, generate_bp },
 	{ AC_VECTOR, svm_l2_ac_test },
 };
 
@@ -3463,7 +3444,6 @@ struct svm_test svm_tests[] = {
 	TEST(svm_vmload_vmsave),
 	TEST(svm_test_singlestep),
 	TEST(svm_nm_test),
-	TEST(svm_int3_test),
 	TEST(svm_into_test),
 	TEST(svm_exception_test),
 	TEST(svm_lbrv_test0),
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 7/9] x86: nSVM: Move #OF test to exception test framework
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
                   ` (5 preceding siblings ...)
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 6/9] x86: nSVM: Move #BP test to exception test framework Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 8/9] x86: nSVM: Move part of #NM " Sean Christopherson
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

From: Manali Shukla <manali.shukla@amd.com>

Remove the boiler plate code for #OF test and move #OF exception test in
exception test framework.

Signed-off-by: Manali Shukla <manali.shukla@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/svm_tests.c | 50 +------------------------------------------------
 1 file changed, 1 insertion(+), 49 deletions(-)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 1285f98..0870cc5 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -2756,54 +2756,6 @@ static void pause_filter_test(void)
 	}
 }
 
-
-static int of_test_counter;
-
-static void guest_test_of_handler(struct ex_regs *r)
-{
-	of_test_counter++;
-}
-
-static void svm_of_test_guest(struct svm_test *test)
-{
-	struct far_pointer32 fp = {
-		.offset = (uintptr_t)&&into,
-		.selector = KERNEL_CS32,
-	};
-	uintptr_t rsp;
-
-	asm volatile ("mov %%rsp, %0" : "=r"(rsp));
-
-	if (fp.offset != (uintptr_t)&&into) {
-		printf("Codee address too high.\n");
-		return;
-	}
-
-	if ((u32)rsp != rsp) {
-		printf("Stack address too high.\n");
-	}
-
-	asm goto("lcall *%0" : : "m" (fp) : "rax" : into);
-	return;
-into:
-
-	asm volatile (".code32;"
-		      "movl $0x7fffffff, %eax;"
-		      "addl %eax, %eax;"
-		      "into;"
-		      "lret;"
-		      ".code64");
-	__builtin_unreachable();
-}
-
-static void svm_into_test(void)
-{
-	handle_exception(OF_VECTOR, guest_test_of_handler);
-	test_set_guest(svm_of_test_guest);
-	report(svm_vmrun() == SVM_EXIT_VMMCALL && of_test_counter == 1,
-	       "#OF is generated in L2 exception handler");
-}
-
 static int nm_test_counter;
 
 static void guest_test_nm_handler(struct ex_regs *r)
@@ -3294,6 +3246,7 @@ struct svm_exception_test svm_exception_tests[] = {
 	{ DB_VECTOR, generate_single_step_db },
 	{ BP_VECTOR, generate_bp },
 	{ AC_VECTOR, svm_l2_ac_test },
+	{ OF_VECTOR, generate_of },
 };
 
 static u8 svm_exception_test_vector;
@@ -3444,7 +3397,6 @@ struct svm_test svm_tests[] = {
 	TEST(svm_vmload_vmsave),
 	TEST(svm_test_singlestep),
 	TEST(svm_nm_test),
-	TEST(svm_into_test),
 	TEST(svm_exception_test),
 	TEST(svm_lbrv_test0),
 	TEST(svm_lbrv_test1),
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 8/9] x86: nSVM: Move part of #NM test to exception test framework
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
                   ` (6 preceding siblings ...)
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 7/9] x86: nSVM: Move #OF " Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 9/9] nVMX: Move #NM test to generic " Sean Christopherson
  2022-10-12  4:17 ` [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Manali Shukla
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

From: Manali Shukla <manali.shukla@amd.com>

Remove the boiler plate code for #NM test and move #NM exception test
into the exception test framework.

Keep the test case for the condition where #NM exception is not
generated, but drop the #NM handler entirely and rely on an unexpected
exception being reported as such (the VMMCALL assertion would also fail).

Signed-off-by: Manali Shukla <manali.shukla@amd.com>
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/processor.h | 19 +++++++++++++++++++
 x86/svm_tests.c     | 46 +++++++--------------------------------------
 2 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 5865933..c178998 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -869,6 +869,25 @@ into:
 	__builtin_unreachable();
 }
 
+static inline void fnop(void)
+{
+	asm volatile("fnop");
+}
+
+/* If CR0.TS is set in L2, #NM is generated. */
+static inline void generate_cr0_ts_nm(void)
+{
+	write_cr0((read_cr0() & ~X86_CR0_EM) | X86_CR0_TS);
+	fnop();
+}
+
+/* If CR0.TS is cleared and CR0.EM is set, #NM is generated. */
+static inline void generate_cr0_em_nm(void)
+{
+	write_cr0((read_cr0() & ~X86_CR0_TS) | X86_CR0_EM);
+	fnop();
+}
+
 static inline u8 pmu_version(void)
 {
 	return cpuid(10).a & 0xff;
diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 0870cc5..27ce47b 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -2756,48 +2756,14 @@ static void pause_filter_test(void)
 	}
 }
 
-static int nm_test_counter;
-
-static void guest_test_nm_handler(struct ex_regs *r)
+/* If CR0.TS and CR0.EM are cleared in L2, no #NM is generated. */
+static void svm_no_nm_test(void)
 {
-	nm_test_counter++;
 	write_cr0(read_cr0() & ~X86_CR0_TS);
-	write_cr0(read_cr0() & ~X86_CR0_EM);
-}
-
-static void svm_nm_test_guest(struct svm_test *test)
-{
-	asm volatile("fnop");
-}
-
-/* This test checks that:
- *
- * (a) If CR0.TS is set in L2, #NM is handled by L2 when
- *     just an L2 handler is registered.
- *
- * (b) If CR0.TS is cleared and CR0.EM is set, #NM is handled
- *     by L2 when just an l2 handler is registered.
- *
- * (c) If CR0.TS and CR0.EM are cleared in L2, no exception
- *     is generated.
- */
-
-static void svm_nm_test(void)
-{
-	handle_exception(NM_VECTOR, guest_test_nm_handler);
-	write_cr0(read_cr0() & ~X86_CR0_TS);
-	test_set_guest(svm_nm_test_guest);
-
-	vmcb->save.cr0 = vmcb->save.cr0 | X86_CR0_TS;
-	report(svm_vmrun() == SVM_EXIT_VMMCALL && nm_test_counter == 1,
-	       "fnop with CR0.TS set in L2, #NM is triggered");
-
-	vmcb->save.cr0 = (vmcb->save.cr0 & ~X86_CR0_TS) | X86_CR0_EM;
-	report(svm_vmrun() == SVM_EXIT_VMMCALL && nm_test_counter == 2,
-	       "fnop with CR0.EM set in L2, #NM is triggered");
+	test_set_guest((test_guest_func)fnop);
 
 	vmcb->save.cr0 = vmcb->save.cr0 & ~(X86_CR0_TS | X86_CR0_EM);
-	report(svm_vmrun() == SVM_EXIT_VMMCALL && nm_test_counter == 2,
+	report(svm_vmrun() == SVM_EXIT_VMMCALL,
 	       "fnop with CR0.TS and CR0.EM unset no #NM excpetion");
 }
 
@@ -3247,6 +3213,8 @@ struct svm_exception_test svm_exception_tests[] = {
 	{ BP_VECTOR, generate_bp },
 	{ AC_VECTOR, svm_l2_ac_test },
 	{ OF_VECTOR, generate_of },
+	{ NM_VECTOR, generate_cr0_ts_nm },
+	{ NM_VECTOR, generate_cr0_em_nm },
 };
 
 static u8 svm_exception_test_vector;
@@ -3396,7 +3364,7 @@ struct svm_test svm_tests[] = {
 	TEST(svm_vmrun_errata_test),
 	TEST(svm_vmload_vmsave),
 	TEST(svm_test_singlestep),
-	TEST(svm_nm_test),
+	TEST(svm_no_nm_test),
 	TEST(svm_exception_test),
 	TEST(svm_lbrv_test0),
 	TEST(svm_lbrv_test1),
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* [kvm-unit-tests PATCH v3 9/9] nVMX: Move #NM test to generic exception test framework
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
                   ` (7 preceding siblings ...)
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 8/9] x86: nSVM: Move part of #NM " Sean Christopherson
@ 2022-10-05 23:52 ` Sean Christopherson
  2022-10-12  4:17 ` [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Manali Shukla
  9 siblings, 0 replies; 11+ messages in thread
From: Sean Christopherson @ 2022-10-05 23:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Sean Christopherson, Manali Shukla

Move the #NM test cases to the generic exception test framework, and
rename the dedicated test to note that it tests the "no #NM" case.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 x86/vmx_tests.c | 67 ++++++-------------------------------------------
 1 file changed, 8 insertions(+), 59 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 368ad43..2438022 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -8359,67 +8359,14 @@ static void vmx_cr4_osxsave_test(void)
 	TEST_ASSERT(this_cpu_has(X86_FEATURE_OSXSAVE));
 }
 
-static void vmx_nm_test_guest(void)
-{
-	write_cr0(read_cr0() | X86_CR0_TS);
-	asm volatile("fnop");
-}
-
-static void check_nm_exit(const char *test)
-{
-	u32 reason = vmcs_read(EXI_REASON);
-	u32 intr_info = vmcs_read(EXI_INTR_INFO);
-	const u32 expected = INTR_INFO_VALID_MASK | INTR_TYPE_HARD_EXCEPTION |
-		NM_VECTOR;
-
-	report(reason == VMX_EXC_NMI && intr_info == expected, "%s", test);
-}
-
 /*
- * This test checks that:
- *
- * (a) If L2 launches with CR0.TS clear, but later sets CR0.TS, then
- *     a subsequent #NM VM-exit is reflected to L1.
- *
- * (b) If L2 launches with CR0.TS clear and CR0.EM set, then a
- *     subsequent #NM VM-exit is reflected to L1.
+ * FNOP with both CR0.TS and CR0.EM clear should not generate #NM, and the L2
+ * guest should exit normally.
  */
-static void vmx_nm_test(void)
+static void vmx_no_nm_test(void)
 {
-	unsigned long cr0 = read_cr0();
-
-	test_set_guest(vmx_nm_test_guest);
-
-	/*
-	 * L1 wants to intercept #NM exceptions encountered in L2.
-	 */
-	vmcs_write(EXC_BITMAP, 1 << NM_VECTOR);
-
-	/*
-	 * Launch L2 with CR0.TS clear, but don't claim host ownership of
-	 * any CR0 bits. L2 will set CR0.TS and then try to execute fnop,
-	 * which will raise #NM. L0 should reflect the #NM VM-exit to L1.
-	 */
-	vmcs_write(CR0_MASK, 0);
-	vmcs_write(GUEST_CR0, cr0 & ~X86_CR0_TS);
-	enter_guest();
-	check_nm_exit("fnop with CR0.TS set in L2 triggers #NM VM-exit to L1");
-
-	/*
-	 * Re-enter L2 at the fnop instruction, with CR0.TS clear but
-	 * CR0.EM set. The fnop will still raise #NM, and L0 should
-	 * reflect the #NM VM-exit to L1.
-	 */
-	vmcs_write(GUEST_CR0, (cr0 & ~X86_CR0_TS) | X86_CR0_EM);
-	enter_guest();
-	check_nm_exit("fnop with CR0.EM set in L2 triggers #NM VM-exit to L1");
-
-	/*
-	 * Re-enter L2 at the fnop instruction, with both CR0.TS and
-	 * CR0.EM clear. There will be no #NM, and the L2 guest should
-	 * exit normally.
-	 */
-	vmcs_write(GUEST_CR0, cr0 & ~(X86_CR0_TS | X86_CR0_EM));
+	test_set_guest(fnop);
+	vmcs_write(GUEST_CR0, read_cr0() & ~(X86_CR0_TS | X86_CR0_EM));
 	enter_guest();
 }
 
@@ -10666,6 +10613,8 @@ struct vmx_exception_test vmx_exception_tests[] = {
 	{ BP_VECTOR, generate_bp },
 	{ AC_VECTOR, vmx_l2_ac_test },
 	{ OF_VECTOR, generate_of },
+	{ NM_VECTOR, generate_cr0_ts_nm },
+	{ NM_VECTOR, generate_cr0_em_nm },
 };
 
 static u8 vmx_exception_test_vector;
@@ -10804,7 +10753,7 @@ struct vmx_test vmx_tests[] = {
 	TEST(vmx_ldtr_test),
 	TEST(vmx_cr_load_test),
 	TEST(vmx_cr4_osxsave_test),
-	TEST(vmx_nm_test),
+	TEST(vmx_no_nm_test),
 	TEST(vmx_db_test),
 	TEST(vmx_nmi_window_test),
 	TEST(vmx_intr_window_test),
-- 
2.38.0.rc1.362.ged0d419d3c-goog


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

* Re: [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests
  2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
                   ` (8 preceding siblings ...)
  2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 9/9] nVMX: Move #NM test to generic " Sean Christopherson
@ 2022-10-12  4:17 ` Manali Shukla
  9 siblings, 0 replies; 11+ messages in thread
From: Manali Shukla @ 2022-10-12  4:17 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm

On 10/6/2022 5:22 AM, Sean Christopherson wrote:
> This is a continuation of Manali's series[*] to add nSVM exception routing
> tests.  The functionality is largely the same, but instead of copy+pasting
> nVMX tests (and vice versa), move the helpers that generate exceptions to
> processor.h so that at least the gory details can be shared.
> 
> An added bonus is that by consolidating code, nVMX can do some of the same
> cleanups that Manali's patches do for nSVM, e.g. move more testcases to
> the generic framework and drop fully redundant tests.
> 
> https://lore.kernel.org/all/20220810050738.7442-1-manali.shukla@amd.com
> 
> Manali Shukla (4):
>   x86: nSVM: Add an exception test framework and tests
>   x86: nSVM: Move #BP test to exception test framework
>   x86: nSVM: Move #OF test to exception test framework
>   x86: nSVM: Move part of #NM test to exception test framework
> 
> Sean Christopherson (5):
>   nVMX: Add "nop" after setting EFLAGS.TF to guarantee single-step #DB
>   x86: Move helpers to generate misc exceptions to processor.h
>   nVMX: Move #OF test to generic exceptions test
>   nVMX: Drop one-off INT3=>#BP test
>   nVMX: Move #NM test to generic exception test framework
> 
>  lib/x86/processor.h |  97 ++++++++++++++++++++
>  x86/svm_tests.c     | 195 ++++++++++++++++++----------------------
>  x86/vmx_tests.c     | 214 ++++++--------------------------------------
>  3 files changed, 210 insertions(+), 296 deletions(-)
> 
> 
> base-commit: d8a4f9e5e8d69d4ef257b40d6cd666bd2f63494e

Hi Sean,

Thank you for reviewing my changes.
I have tested the changes on AMD Milan/Napples and it works as expected.

-Manali

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

end of thread, other threads:[~2022-10-12  4:17 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-05 23:52 [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 1/9] nVMX: Add "nop" after setting EFLAGS.TF to guarantee single-step #DB Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 2/9] x86: Move helpers to generate misc exceptions to processor.h Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 3/9] nVMX: Move #OF test to generic exceptions test Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 4/9] nVMX: Drop one-off INT3=>#BP test Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 5/9] x86: nSVM: Add an exception test framework and tests Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 6/9] x86: nSVM: Move #BP test to exception test framework Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 7/9] x86: nSVM: Move #OF " Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 8/9] x86: nSVM: Move part of #NM " Sean Christopherson
2022-10-05 23:52 ` [kvm-unit-tests PATCH v3 9/9] nVMX: Move #NM test to generic " Sean Christopherson
2022-10-12  4:17 ` [kvm-unit-tests PATCH v3 0/9] x86: n{VMX,SVM} exception tests Manali Shukla

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).