kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] kvm-unit-test: nSVM: Add alternative (v2) test framework and add test for SVME.EFER vmcb field
@ 2020-03-17 20:05 Krish Sadhukhan
  2020-03-17 20:05 ` [PATCH 1/3] kvm-unit-test: nSVM: Add alternative (v2) test format for nested guests Krish Sadhukhan
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Krish Sadhukhan @ 2020-03-17 20:05 UTC (permalink / raw)
  To: kvm; +Cc: pbonzini

This patchset builds on top of my previous patch titled:

	"[PATCH] kvm-unit-test: nSVM: Restructure nSVM test code"

The idea here is to create an alternative (v2) test framework that nVMX has
so that tests that don't need the functions that the current framework
requires, can be added.
Patch# 1: Adds the alternative (v2) framework.
Patch# 2: Adds helper functions for reading and writing vmcb fields by the
	  tests.
Patch# 3: Adds a test for SVME.EFER field.

[PATCH 1/3] kvm-unit-test: nSVM: Add alternative (v2) test format for nested guests
[PATCH 2/3] kvm-unit-test: nSVM: Add helper functions to write and read vmcb fields
[PATCH 3/3] kvm-unit-test: nSVM: Test SVME.EFER on VMRUN of nested guests

 x86/svm.c       | 91 ++++++++++++++++++++++++++++++++++++++++++++-------------
 x86/svm.h       |  8 +++++
 x86/svm_tests.c | 25 ++++++++++++++++
 3 files changed, 104 insertions(+), 20 deletions(-)

Krish Sadhukhan (3):
      nSVM: Add alternative (v2) test format for nested guests
      nSVM: Add helper functions to write and read vmcb fields
      nSVM: Test SVME.EFER on VMRUN of nested guests


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

* [PATCH 1/3] kvm-unit-test: nSVM: Add alternative (v2) test format for nested guests
  2020-03-17 20:05 [PATCH 0/3] kvm-unit-test: nSVM: Add alternative (v2) test framework and add test for SVME.EFER vmcb field Krish Sadhukhan
@ 2020-03-17 20:05 ` Krish Sadhukhan
  2020-03-17 20:05 ` [PATCH 2/3] kvm-unit-test: nSVM: Add helper functions to write and read vmcb fields Krish Sadhukhan
  2020-03-17 20:05 ` [PATCH 3/3] kvm-unit-test: nSVM: Test SVME.EFER on VMRUN of nested guests Krish Sadhukhan
  2 siblings, 0 replies; 5+ messages in thread
From: Krish Sadhukhan @ 2020-03-17 20:05 UTC (permalink / raw)
  To: kvm; +Cc: pbonzini

  ..so that we can add tests such as VMCB consistency tests, that require
  the tests to only proceed up to the execution of the first guest (nested)
  instruction and do not require us to define all the functions that the
  current format dictates.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
---
 x86/svm.c       | 75 ++++++++++++++++++++++++++++++++++++++++++---------------
 x86/svm.h       |  6 +++++
 x86/svm_tests.c |  2 ++
 3 files changed, 63 insertions(+), 20 deletions(-)

diff --git a/x86/svm.c b/x86/svm.c
index 07571e9..7ce33a6 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -110,9 +110,16 @@ inline void vmmcall(void)
 	asm volatile ("vmmcall" : : : "memory");
 }
 
+static test_guest_func guest_main;
+
+void test_set_guest(test_guest_func func)
+{
+	guest_main = func;
+}
+
 static void test_thunk(struct svm_test *test)
 {
-	test->guest_func(test);
+	guest_main(test);
 	vmmcall();
 }
 
@@ -191,14 +198,49 @@ struct regs get_regs(void)
 
 #define LOAD_GPR_C      SAVE_GPR_C
 
-static void test_run(struct svm_test *test, struct vmcb *vmcb)
+struct svm_test *v2_test;
+struct vmcb *vmcb;
+
+#define ASM_VMRUN_CMD                           \
+                "vmload %%rax\n\t"              \
+                "mov regs+0x80, %%r15\n\t"      \
+                "mov %%r15, 0x170(%%rax)\n\t"   \
+                "mov regs, %%r15\n\t"           \
+                "mov %%r15, 0x1f8(%%rax)\n\t"   \
+                LOAD_GPR_C                      \
+                "vmrun %%rax\n\t"               \
+                SAVE_GPR_C                      \
+                "mov 0x170(%%rax), %%r15\n\t"   \
+                "mov %%r15, regs+0x80\n\t"      \
+                "mov 0x1f8(%%rax), %%r15\n\t"   \
+                "mov %%r15, regs\n\t"           \
+                "vmsave %%rax\n\t"              \
+
+u64 guest_stack[10000];
+
+int svm_vmrun(void)
+{
+	vmcb->save.rip = (ulong)test_thunk;
+	vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
+	regs.rdi = (ulong)v2_test;
+
+	asm volatile (
+		ASM_VMRUN_CMD
+		:
+		: "a" (virt_to_phys(vmcb))
+		: "memory");
+
+	return (vmcb->control.exit_code);
+}
+
+static void test_run(struct svm_test *test)
 {
 	u64 vmcb_phys = virt_to_phys(vmcb);
-	u64 guest_stack[10000];
 
 	irq_disable();
 	test->vmcb = vmcb;
 	test->prepare(test);
+	guest_main = test->guest_func;
 	vmcb->save.rip = (ulong)test_thunk;
 	vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack));
 	regs.rdi = (ulong)test;
@@ -210,19 +252,7 @@ static void test_run(struct svm_test *test, struct vmcb *vmcb)
 			"sti \n\t"
 			"call *%c[PREPARE_GIF_CLEAR](%[test]) \n \t"
 			"mov %[vmcb_phys], %%rax \n\t"
-			"vmload %%rax\n\t"
-			"mov regs+0x80, %%r15\n\t"  // rflags
-			"mov %%r15, 0x170(%%rax)\n\t"
-			"mov regs, %%r15\n\t"       // rax
-			"mov %%r15, 0x1f8(%%rax)\n\t"
-			LOAD_GPR_C
-			"vmrun %%rax\n\t"
-			SAVE_GPR_C
-			"mov 0x170(%%rax), %%r15\n\t"  // rflags
-			"mov %%r15, regs+0x80\n\t"
-			"mov 0x1f8(%%rax), %%r15\n\t"  // rax
-			"mov %%r15, regs\n\t"
-			"vmsave %%rax\n\t"
+			ASM_VMRUN_CMD
 			"cli \n\t"
 			"stgi"
 			: // inputs clobbered by the guest:
@@ -303,7 +333,6 @@ extern struct svm_test svm_tests[];
 int main(int ac, char **av)
 {
 	int i = 0;
-	struct vmcb *vmcb;
 
 	setup_vm();
 	smp_init();
@@ -318,9 +347,15 @@ int main(int ac, char **av)
 	vmcb = alloc_page();
 
 	for (; svm_tests[i].name != NULL; i++) {
-		if (!svm_tests[i].supported())
-			continue;
-		test_run(&svm_tests[i], vmcb);
+		if (svm_tests[i].v2 == NULL) {
+			if (!svm_tests[i].supported())
+				continue;
+			test_run(&svm_tests[i]);
+		} else {
+			vmcb_ident(vmcb);
+			v2_test = &(svm_tests[i]);
+			svm_tests[i].v2();
+		}
 	}
 
 	return report_summary();
diff --git a/x86/svm.h b/x86/svm.h
index ccc5172..25514de 100644
--- a/x86/svm.h
+++ b/x86/svm.h
@@ -337,6 +337,8 @@ struct svm_test {
 	struct vmcb *vmcb;
 	int exits;
 	ulong scratch;
+	/* Alternative test interface. */
+	void (*v2)(void);
 };
 
 struct regs {
@@ -359,6 +361,8 @@ struct regs {
 	u64 rflags;
 };
 
+typedef void (*test_guest_func)(struct svm_test *);
+
 u64 *npt_get_pte(u64 address);
 u64 *npt_get_pde(u64 address);
 u64 *npt_get_pdpe(void);
@@ -374,5 +378,7 @@ void inc_test_stage(struct svm_test *test);
 void vmcb_ident(struct vmcb *vmcb);
 struct regs get_regs(void);
 void vmmcall(void);
+int svm_vmrun(void);
+void test_set_guest(test_guest_func func);
 
 #endif
diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 264f8de..580bce6 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -1195,6 +1195,8 @@ static bool pending_event_check_vmask(struct svm_test *test)
     return get_test_stage(test) == 2;
 }
 
+#define TEST(name) { #name, .v2 = name }
+
 struct svm_test svm_tests[] = {
     { "null", default_supported, default_prepare,
       default_prepare_gif_clear, null_test,
-- 
1.8.3.1


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

* [PATCH 2/3] kvm-unit-test: nSVM: Add helper functions to write and read vmcb fields
  2020-03-17 20:05 [PATCH 0/3] kvm-unit-test: nSVM: Add alternative (v2) test framework and add test for SVME.EFER vmcb field Krish Sadhukhan
  2020-03-17 20:05 ` [PATCH 1/3] kvm-unit-test: nSVM: Add alternative (v2) test format for nested guests Krish Sadhukhan
@ 2020-03-17 20:05 ` Krish Sadhukhan
  2020-03-18 12:45   ` Paolo Bonzini
  2020-03-17 20:05 ` [PATCH 3/3] kvm-unit-test: nSVM: Test SVME.EFER on VMRUN of nested guests Krish Sadhukhan
  2 siblings, 1 reply; 5+ messages in thread
From: Krish Sadhukhan @ 2020-03-17 20:05 UTC (permalink / raw)
  To: kvm; +Cc: pbonzini

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
---
 x86/svm.c | 16 ++++++++++++++++
 x86/svm.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/x86/svm.c b/x86/svm.c
index 7ce33a6..3803032 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -233,6 +233,22 @@ int svm_vmrun(void)
 	return (vmcb->control.exit_code);
 }
 
+u64 vmcb_save_read64(size_t offset)
+{
+	u64 *ptr = (u64 *) ((char *) vmcb + offsetof(struct vmcb, save) +
+	    offset);
+
+       return (*ptr);
+}
+
+void vmcb_save_write64(size_t offset, u64 value)
+{
+	u64 *ptr = (u64 *) ((char *) vmcb + offsetof(struct vmcb, save) +
+	    offset);
+
+       *ptr = value;
+}
+
 static void test_run(struct svm_test *test)
 {
 	u64 vmcb_phys = virt_to_phys(vmcb);
diff --git a/x86/svm.h b/x86/svm.h
index 25514de..3a6af6e 100644
--- a/x86/svm.h
+++ b/x86/svm.h
@@ -380,5 +380,7 @@ struct regs get_regs(void);
 void vmmcall(void);
 int svm_vmrun(void);
 void test_set_guest(test_guest_func func);
+u64 vmcb_save_read64(size_t offset);
+void vmcb_save_write64(size_t offset, u64 value);
 
 #endif
-- 
1.8.3.1


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

* [PATCH 3/3] kvm-unit-test: nSVM: Test SVME.EFER on VMRUN of nested guests
  2020-03-17 20:05 [PATCH 0/3] kvm-unit-test: nSVM: Add alternative (v2) test framework and add test for SVME.EFER vmcb field Krish Sadhukhan
  2020-03-17 20:05 ` [PATCH 1/3] kvm-unit-test: nSVM: Add alternative (v2) test format for nested guests Krish Sadhukhan
  2020-03-17 20:05 ` [PATCH 2/3] kvm-unit-test: nSVM: Add helper functions to write and read vmcb fields Krish Sadhukhan
@ 2020-03-17 20:05 ` Krish Sadhukhan
  2 siblings, 0 replies; 5+ messages in thread
From: Krish Sadhukhan @ 2020-03-17 20:05 UTC (permalink / raw)
  To: kvm; +Cc: pbonzini

According to the section "Canonicalization and Consistency Checks" in 15.5.1
in APM vol 2, setting EFER.SVME to zero is an illegal guest state and will
cause the nested guest to VMEXIT to the guest with an exit code of
VMEXIT_INVALID.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
---
 x86/svm_tests.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 580bce6..8de4b8e 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -1197,6 +1197,28 @@ static bool pending_event_check_vmask(struct svm_test *test)
 
 #define TEST(name) { #name, .v2 = name }
 
+/*
+ * v2 tests
+ */
+
+static void basic_guest_main(struct svm_test *test)
+{
+}
+
+static void svm_guest_state_test(void)
+{
+	size_t offset = offsetof(struct vmcb_save_area, efer);
+	u64 efer_saved = vmcb_save_read64(offset);
+	u64 efer = efer_saved;
+
+	test_set_guest(basic_guest_main);
+	report (svm_vmrun() == SVM_EXIT_VMMCALL, "EFER.SVME: %lx", efer);
+	efer &= ~EFER_SVME;
+	vmcb_save_write64(offset, efer);
+	report (svm_vmrun() == SVM_EXIT_ERR, "EFER.SVME: %lx", efer);
+	vmcb_save_write64(offset, efer_saved);
+}
+
 struct svm_test svm_tests[] = {
     { "null", default_supported, default_prepare,
       default_prepare_gif_clear, null_test,
@@ -1277,5 +1299,6 @@ struct svm_test svm_tests[] = {
       pending_event_prepare_gif_clear_vmask,
       pending_event_test_vmask, pending_event_finished_vmask,
       pending_event_check_vmask },
+    TEST(svm_guest_state_test),
     { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 };
-- 
1.8.3.1


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

* Re: [PATCH 2/3] kvm-unit-test: nSVM: Add helper functions to write and read vmcb fields
  2020-03-17 20:05 ` [PATCH 2/3] kvm-unit-test: nSVM: Add helper functions to write and read vmcb fields Krish Sadhukhan
@ 2020-03-18 12:45   ` Paolo Bonzini
  0 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2020-03-18 12:45 UTC (permalink / raw)
  To: Krish Sadhukhan, kvm

On 17/03/20 21:05, Krish Sadhukhan wrote:
> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
> ---
>  x86/svm.c | 16 ++++++++++++++++
>  x86/svm.h |  2 ++
>  2 files changed, 18 insertions(+)

I prefer to just make vmcb public in svm.h.

Please check kvm-unit-tests.git's master branch and kvm.git's queue branch.

Thanks for contributing to nested SVM tests as well!

Paolo

> diff --git a/x86/svm.c b/x86/svm.c
> index 7ce33a6..3803032 100644
> --- a/x86/svm.c
> +++ b/x86/svm.c
> @@ -233,6 +233,22 @@ int svm_vmrun(void)
>  	return (vmcb->control.exit_code);
>  }
>  
> +u64 vmcb_save_read64(size_t offset)
> +{
> +	u64 *ptr = (u64 *) ((char *) vmcb + offsetof(struct vmcb, save) +
> +	    offset);
> +
> +       return (*ptr);
> +}
> +
> +void vmcb_save_write64(size_t offset, u64 value)
> +{
> +	u64 *ptr = (u64 *) ((char *) vmcb + offsetof(struct vmcb, save) +
> +	    offset);
> +
> +       *ptr = value;
> +}
> +
>  static void test_run(struct svm_test *test)
>  {
>  	u64 vmcb_phys = virt_to_phys(vmcb);
> diff --git a/x86/svm.h b/x86/svm.h
> index 25514de..3a6af6e 100644
> --- a/x86/svm.h
> +++ b/x86/svm.h
> @@ -380,5 +380,7 @@ struct regs get_regs(void);
>  void vmmcall(void);
>  int svm_vmrun(void);
>  void test_set_guest(test_guest_func func);
> +u64 vmcb_save_read64(size_t offset);
> +void vmcb_save_write64(size_t offset, u64 value);
>  
>  #endif
> 


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

end of thread, other threads:[~2020-03-18 12:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-17 20:05 [PATCH 0/3] kvm-unit-test: nSVM: Add alternative (v2) test framework and add test for SVME.EFER vmcb field Krish Sadhukhan
2020-03-17 20:05 ` [PATCH 1/3] kvm-unit-test: nSVM: Add alternative (v2) test format for nested guests Krish Sadhukhan
2020-03-17 20:05 ` [PATCH 2/3] kvm-unit-test: nSVM: Add helper functions to write and read vmcb fields Krish Sadhukhan
2020-03-18 12:45   ` Paolo Bonzini
2020-03-17 20:05 ` [PATCH 3/3] kvm-unit-test: nSVM: Test SVME.EFER on VMRUN of nested guests Krish Sadhukhan

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