kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] kvm-unit-tests: VMX: Split VMX test suites to separate file
@ 2013-08-05  3:32 Arthur Chunqi Li
  2013-08-07 15:29 ` Paolo Bonzini
  0 siblings, 1 reply; 2+ messages in thread
From: Arthur Chunqi Li @ 2013-08-05  3:32 UTC (permalink / raw)
  To: kvm; +Cc: jan.kiszka, gleb, pbonzini, Arthur Chunqi Li

Reconstruct VMX codes and put all VMX test suites in x86/vmx_tests.c.

Signed-off-by: Arthur Chunqi Li <yzt356@gmail.com>
---

ChangeLog to v2:
	Remove some unused extern definitions in vmx.h.

 config-x86-common.mak |    2 +-
 x86/vmx.c             |  115 ++++++++-----------------------------------------
 x86/vmx.h             |   41 ++++++++++++------
 x86/vmx_tests.c       |   88 +++++++++++++++++++++++++++++++++++++
 4 files changed, 135 insertions(+), 111 deletions(-)
 create mode 100644 x86/vmx_tests.c

diff --git a/config-x86-common.mak b/config-x86-common.mak
index 34a41e1..bf88c67 100644
--- a/config-x86-common.mak
+++ b/config-x86-common.mak
@@ -101,7 +101,7 @@ $(TEST_DIR)/asyncpf.elf: $(cstart.o) $(TEST_DIR)/asyncpf.o
 
 $(TEST_DIR)/pcid.elf: $(cstart.o) $(TEST_DIR)/pcid.o
 
-$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o
+$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
 
 arch_clean:
 	$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
diff --git a/x86/vmx.c b/x86/vmx.c
index 082c3bb..efee3df 100644
--- a/x86/vmx.c
+++ b/x86/vmx.c
@@ -7,19 +7,24 @@
 #include "smp.h"
 #include "io.h"
 
-int fails = 0, tests = 0;
+int fails, tests;
 u32 *vmxon_region;
 struct vmcs *vmcs_root;
 u32 vpid_cnt;
 void *guest_stack, *guest_syscall_stack;
 u32 ctrl_pin, ctrl_enter, ctrl_exit, ctrl_cpu[2];
-ulong fix_cr0_set, fix_cr0_clr;
-ulong fix_cr4_set, fix_cr4_clr;
 struct regs regs;
 struct vmx_test *current;
-u64 hypercall_field = 0;
+u64 hypercall_field;
 bool launched;
 
+union vmx_basic basic;
+union vmx_ctrl_pin ctrl_pin_rev;
+union vmx_ctrl_cpu ctrl_cpu_rev[2];
+union vmx_ctrl_exit ctrl_exit_rev;
+union vmx_ctrl_ent ctrl_enter_rev;
+union vmx_ept_vpid  ept_vpid;
+
 extern u64 gdt64_desc[];
 extern u64 idt_descr[];
 extern u64 tss_descr[];
@@ -27,7 +32,7 @@ extern void *vmx_return;
 extern void *entry_sysenter;
 extern void *guest_entry;
 
-static void report(const char *name, int result)
+void report(const char *name, int result)
 {
 	++tests;
 	if (result)
@@ -80,7 +85,7 @@ static inline int vmx_off()
 	return ret;
 }
 
-static void print_vmexit_info()
+void print_vmexit_info()
 {
 	u64 guest_rip, guest_rsp;
 	ulong reason = vmcs_read(EXI_REASON) & 0xff;
@@ -311,6 +316,9 @@ static int init_vmcs(struct vmcs **vmcs)
 
 static void init_vmx(void)
 {
+	ulong fix_cr0_set, fix_cr0_clr;
+	ulong fix_cr4_set, fix_cr4_clr;
+
 	vmxon_region = alloc_page();
 	memset(vmxon_region, 0, PAGE_SIZE);
 
@@ -440,12 +448,10 @@ static int exit_handler()
 	int ret;
 
 	current->exits++;
-	current->guest_regs = regs;
 	if (is_hypercall())
 		ret = handle_hypercall();
 	else
 		ret = current->exit_handler();
-	regs = current->guest_regs;
 	switch (ret) {
 	case VMX_TEST_VMEXIT:
 	case VMX_TEST_RESUME:
@@ -552,98 +558,16 @@ static int test_run(struct vmx_test *test)
 	return 0;
 }
 
-static void basic_init()
-{
-}
-
-static void basic_guest_main()
-{
-	/* Here is null guest_main, print Hello World */
-	printf("\tHello World, this is null_guest_main!\n");
-}
-
-static int basic_exit_handler()
-{
-	u64 guest_rip;
-	ulong reason;
-
-	guest_rip = vmcs_read(GUEST_RIP);
-	reason = vmcs_read(EXI_REASON) & 0xff;
-
-	switch (reason) {
-	case VMX_VMCALL:
-		print_vmexit_info();
-		vmcs_write(GUEST_RIP, guest_rip + 3);
-		return VMX_TEST_RESUME;
-	default:
-		break;
-	}
-	printf("ERROR : Unhandled vmx exit.\n");
-	print_vmexit_info();
-	return VMX_TEST_EXIT;
-}
-
-static void basic_syscall_handler(u64 syscall_no)
-{
-}
-
-static void vmenter_main()
-{
-	u64 rax;
-	u64 rsp, resume_rsp;
-
-	report("test vmlaunch", 1);
-
-	asm volatile(
-		"mov %%rsp, %0\n\t"
-		"mov %3, %%rax\n\t"
-		"vmcall\n\t"
-		"mov %%rax, %1\n\t"
-		"mov %%rsp, %2\n\t"
-		: "=r"(rsp), "=r"(rax), "=r"(resume_rsp)
-		: "g"(0xABCD));
-	report("test vmresume", (rax == 0xFFFF) && (rsp == resume_rsp));
-}
-
-static int vmenter_exit_handler()
-{
-	u64 guest_rip;
-	ulong reason;
-
-	guest_rip = vmcs_read(GUEST_RIP);
-	reason = vmcs_read(EXI_REASON) & 0xff;
-	switch (reason) {
-	case VMX_VMCALL:
-		if (current->guest_regs.rax != 0xABCD) {
-			report("test vmresume", 0);
-			return VMX_TEST_VMEXIT;
-		}
-		current->guest_regs.rax = 0xFFFF;
-		vmcs_write(GUEST_RIP, guest_rip + 3);
-		return VMX_TEST_RESUME;
-	default:
-		report("test vmresume", 0);
-		print_vmexit_info();
-	}
-	return VMX_TEST_VMEXIT;
-}
-
-
-/* name/init/guest_main/exit_handler/syscall_handler/guest_regs
-   basic_* just implement some basic functions */
-static struct vmx_test vmx_tests[] = {
-	{ "null", basic_init, basic_guest_main, basic_exit_handler,
-		basic_syscall_handler, {0} },
-	{ "vmenter", basic_init, vmenter_main, vmenter_exit_handler,
-		basic_syscall_handler, {0} },
-};
+extern struct vmx_test vmx_tests[];
 
 int main(void)
 {
-	int i;
+	int i = 0;
 
 	setup_vm();
 	setup_idt();
+	fails = tests = 0;
+	hypercall_field = 0;
 
 	if (test_vmx_capability() != 0) {
 		printf("ERROR : vmx not supported, check +vmx option\n");
@@ -664,10 +588,9 @@ int main(void)
 	}
 	test_vmxoff();
 
-	for (i = 1; i < ARRAY_SIZE(vmx_tests); ++i) {
+	while (vmx_tests[++i].name != NULL)
 		if (test_run(&vmx_tests[i]))
 			goto exit;
-	}
 
 exit:
 	printf("\nSUMMARY: %d tests, %d failures\n", tests, fails);
diff --git a/x86/vmx.h b/x86/vmx.h
index d80e000..06d31c7 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -1,5 +1,5 @@
-#ifndef __HYPERVISOR_H
-#define __HYPERVISOR_H
+#ifndef __VMX_H
+#define __VMX_H
 
 #include "libcflat.h"
 
@@ -41,7 +41,7 @@ struct vmx_test {
 	int exits;
 };
 
-static union vmx_basic {
+union vmx_basic {
 	u64 val;
 	struct {
 		u32 revision;
@@ -53,37 +53,37 @@ static union vmx_basic {
 			insouts:1,
 			ctrl:1;
 	};
-} basic;
+};
 
-static union vmx_ctrl_pin {
+union vmx_ctrl_pin {
 	u64 val;
 	struct {
 		u32 set, clr;
 	};
-} ctrl_pin_rev;
+};
 
-static union vmx_ctrl_cpu {
+union vmx_ctrl_cpu {
 	u64 val;
 	struct {
 		u32 set, clr;
 	};
-} ctrl_cpu_rev[2];
+};
 
-static union vmx_ctrl_exit {
+union vmx_ctrl_exit {
 	u64 val;
 	struct {
 		u32 set, clr;
 	};
-} ctrl_exit_rev;
+};
 
-static union vmx_ctrl_ent {
+union vmx_ctrl_ent {
 	u64 val;
 	struct {
 		u32 set, clr;
 	};
-} ctrl_enter_rev;
+};
 
-static union vmx_ept_vpid {
+union vmx_ept_vpid {
 	u64 val;
 	struct {
 		u32:16,
@@ -93,7 +93,7 @@ static union vmx_ept_vpid {
 			: 11;
 		u32	invvpid:1;
 	};
-} ept_vpid;
+};
 
 struct descr {
 	u16 limit;
@@ -432,6 +432,16 @@ enum Ctrl1 {
 #define HYPERCALL_MASK		0xFFF
 #define HYPERCALL_VMEXIT	0x1
 
+
+extern struct regs regs;
+
+extern union vmx_basic basic;
+extern union vmx_ctrl_pin ctrl_pin_rev;
+extern union vmx_ctrl_cpu ctrl_cpu_rev[2];
+extern union vmx_ctrl_exit ctrl_exit_rev;
+extern union vmx_ctrl_ent ctrl_enter_rev;
+extern union vmx_ept_vpid  ept_vpid;
+
 static inline int vmcs_clear(struct vmcs *vmcs)
 {
 	bool ret;
@@ -462,5 +472,8 @@ static inline int vmcs_save(struct vmcs **vmcs)
 	return ret;
 }
 
+void report(const char *name, int result);
+void print_vmexit_info();
+
 #endif
 
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
new file mode 100644
index 0000000..1995837
--- /dev/null
+++ b/x86/vmx_tests.c
@@ -0,0 +1,88 @@
+#include "vmx.h"
+
+void basic_init()
+{
+}
+
+void basic_guest_main()
+{
+	/* Here is a basic guest_main, print Hello World */
+	printf("\tHello World, this is null_guest_main!\n");
+}
+
+int basic_exit_handler()
+{
+	u64 guest_rip;
+	ulong reason;
+
+	guest_rip = vmcs_read(GUEST_RIP);
+	reason = vmcs_read(EXI_REASON) & 0xff;
+
+	switch (reason) {
+	case VMX_VMCALL:
+		print_vmexit_info();
+		vmcs_write(GUEST_RIP, guest_rip + 3);
+		return VMX_TEST_RESUME;
+	default:
+		break;
+	}
+	printf("ERROR : Unhandled vmx exit.\n");
+	print_vmexit_info();
+	return VMX_TEST_EXIT;
+}
+
+void basic_syscall_handler(u64 syscall_no)
+{
+}
+
+void vmenter_main()
+{
+	u64 rax;
+	u64 rsp, resume_rsp;
+
+	report("test vmlaunch", 1);
+
+	asm volatile(
+		"mov %%rsp, %0\n\t"
+		"mov %3, %%rax\n\t"
+		"vmcall\n\t"
+		"mov %%rax, %1\n\t"
+		"mov %%rsp, %2\n\t"
+		: "=r"(rsp), "=r"(rax), "=r"(resume_rsp)
+		: "g"(0xABCD));
+	report("test vmresume", (rax == 0xFFFF) && (rsp == resume_rsp));
+}
+
+int vmenter_exit_handler()
+{
+	u64 guest_rip;
+	ulong reason;
+
+	guest_rip = vmcs_read(GUEST_RIP);
+	reason = vmcs_read(EXI_REASON) & 0xff;
+	switch (reason) {
+	case VMX_VMCALL:
+		if (regs.rax != 0xABCD) {
+			report("test vmresume", 0);
+			return VMX_TEST_VMEXIT;
+		}
+		regs.rax = 0xFFFF;
+		vmcs_write(GUEST_RIP, guest_rip + 3);
+		return VMX_TEST_RESUME;
+	default:
+		report("test vmresume", 0);
+		print_vmexit_info();
+	}
+	return VMX_TEST_VMEXIT;
+}
+
+/* name/init/guest_main/exit_handler/syscall_handler/guest_regs
+   basic_* just implement some basic functions */
+struct vmx_test vmx_tests[] = {
+	{ "null", basic_init, basic_guest_main, basic_exit_handler,
+		basic_syscall_handler, {0} },
+	{ "vmenter", basic_init, vmenter_main, vmenter_exit_handler,
+		basic_syscall_handler, {0} },
+	{ NULL, NULL, NULL, NULL, NULL, {0} },
+};
+
-- 
1.7.9.5


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

* Re: [PATCH v3] kvm-unit-tests: VMX: Split VMX test suites to separate file
  2013-08-05  3:32 [PATCH v3] kvm-unit-tests: VMX: Split VMX test suites to separate file Arthur Chunqi Li
@ 2013-08-07 15:29 ` Paolo Bonzini
  0 siblings, 0 replies; 2+ messages in thread
From: Paolo Bonzini @ 2013-08-07 15:29 UTC (permalink / raw)
  To: Arthur Chunqi Li; +Cc: kvm, jan.kiszka, gleb

On 08/05/2013 05:32 AM, Arthur Chunqi Li wrote:
> Reconstruct VMX codes and put all VMX test suites in x86/vmx_tests.c.
>
> Signed-off-by: Arthur Chunqi Li <yzt356@gmail.com>
> ---
>
> ChangeLog to v2:
> 	Remove some unused extern definitions in vmx.h.
>
>   config-x86-common.mak |    2 +-
>   x86/vmx.c             |  115 ++++++++-----------------------------------------
>   x86/vmx.h             |   41 ++++++++++++------
>   x86/vmx_tests.c       |   88 +++++++++++++++++++++++++++++++++++++
>   4 files changed, 135 insertions(+), 111 deletions(-)
>   create mode 100644 x86/vmx_tests.c
>
> diff --git a/config-x86-common.mak b/config-x86-common.mak
> index 34a41e1..bf88c67 100644
> --- a/config-x86-common.mak
> +++ b/config-x86-common.mak
> @@ -101,7 +101,7 @@ $(TEST_DIR)/asyncpf.elf: $(cstart.o) $(TEST_DIR)/asyncpf.o
>
>   $(TEST_DIR)/pcid.elf: $(cstart.o) $(TEST_DIR)/pcid.o
>
> -$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o
> +$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
>
>   arch_clean:
>   	$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
> diff --git a/x86/vmx.c b/x86/vmx.c
> index 082c3bb..efee3df 100644
> --- a/x86/vmx.c
> +++ b/x86/vmx.c
> @@ -7,19 +7,24 @@
>   #include "smp.h"
>   #include "io.h"
>
> -int fails = 0, tests = 0;
> +int fails, tests;
>   u32 *vmxon_region;
>   struct vmcs *vmcs_root;
>   u32 vpid_cnt;
>   void *guest_stack, *guest_syscall_stack;
>   u32 ctrl_pin, ctrl_enter, ctrl_exit, ctrl_cpu[2];
> -ulong fix_cr0_set, fix_cr0_clr;
> -ulong fix_cr4_set, fix_cr4_clr;
>   struct regs regs;
>   struct vmx_test *current;
> -u64 hypercall_field = 0;
> +u64 hypercall_field;
>   bool launched;

If these are not used outside vmx.c, please make them static.  Otherwise 
looks good.  I'll apply this patch as soon as I test it.

Paolo

> +union vmx_basic basic;
> +union vmx_ctrl_pin ctrl_pin_rev;
> +union vmx_ctrl_cpu ctrl_cpu_rev[2];
> +union vmx_ctrl_exit ctrl_exit_rev;
> +union vmx_ctrl_ent ctrl_enter_rev;
> +union vmx_ept_vpid  ept_vpid;
> +
>   extern u64 gdt64_desc[];
>   extern u64 idt_descr[];
>   extern u64 tss_descr[];
> @@ -27,7 +32,7 @@ extern void *vmx_return;
>   extern void *entry_sysenter;
>   extern void *guest_entry;
>
> -static void report(const char *name, int result)
> +void report(const char *name, int result)
>   {
>   	++tests;
>   	if (result)
> @@ -80,7 +85,7 @@ static inline int vmx_off()
>   	return ret;
>   }
>
> -static void print_vmexit_info()
> +void print_vmexit_info()
>   {
>   	u64 guest_rip, guest_rsp;
>   	ulong reason = vmcs_read(EXI_REASON) & 0xff;
> @@ -311,6 +316,9 @@ static int init_vmcs(struct vmcs **vmcs)
>
>   static void init_vmx(void)
>   {
> +	ulong fix_cr0_set, fix_cr0_clr;
> +	ulong fix_cr4_set, fix_cr4_clr;
> +
>   	vmxon_region = alloc_page();
>   	memset(vmxon_region, 0, PAGE_SIZE);
>
> @@ -440,12 +448,10 @@ static int exit_handler()
>   	int ret;
>
>   	current->exits++;
> -	current->guest_regs = regs;
>   	if (is_hypercall())
>   		ret = handle_hypercall();
>   	else
>   		ret = current->exit_handler();
> -	regs = current->guest_regs;
>   	switch (ret) {
>   	case VMX_TEST_VMEXIT:
>   	case VMX_TEST_RESUME:
> @@ -552,98 +558,16 @@ static int test_run(struct vmx_test *test)
>   	return 0;
>   }
>
> -static void basic_init()
> -{
> -}
> -
> -static void basic_guest_main()
> -{
> -	/* Here is null guest_main, print Hello World */
> -	printf("\tHello World, this is null_guest_main!\n");
> -}
> -
> -static int basic_exit_handler()
> -{
> -	u64 guest_rip;
> -	ulong reason;
> -
> -	guest_rip = vmcs_read(GUEST_RIP);
> -	reason = vmcs_read(EXI_REASON) & 0xff;
> -
> -	switch (reason) {
> -	case VMX_VMCALL:
> -		print_vmexit_info();
> -		vmcs_write(GUEST_RIP, guest_rip + 3);
> -		return VMX_TEST_RESUME;
> -	default:
> -		break;
> -	}
> -	printf("ERROR : Unhandled vmx exit.\n");
> -	print_vmexit_info();
> -	return VMX_TEST_EXIT;
> -}
> -
> -static void basic_syscall_handler(u64 syscall_no)
> -{
> -}
> -
> -static void vmenter_main()
> -{
> -	u64 rax;
> -	u64 rsp, resume_rsp;
> -
> -	report("test vmlaunch", 1);
> -
> -	asm volatile(
> -		"mov %%rsp, %0\n\t"
> -		"mov %3, %%rax\n\t"
> -		"vmcall\n\t"
> -		"mov %%rax, %1\n\t"
> -		"mov %%rsp, %2\n\t"
> -		: "=r"(rsp), "=r"(rax), "=r"(resume_rsp)
> -		: "g"(0xABCD));
> -	report("test vmresume", (rax == 0xFFFF) && (rsp == resume_rsp));
> -}
> -
> -static int vmenter_exit_handler()
> -{
> -	u64 guest_rip;
> -	ulong reason;
> -
> -	guest_rip = vmcs_read(GUEST_RIP);
> -	reason = vmcs_read(EXI_REASON) & 0xff;
> -	switch (reason) {
> -	case VMX_VMCALL:
> -		if (current->guest_regs.rax != 0xABCD) {
> -			report("test vmresume", 0);
> -			return VMX_TEST_VMEXIT;
> -		}
> -		current->guest_regs.rax = 0xFFFF;
> -		vmcs_write(GUEST_RIP, guest_rip + 3);
> -		return VMX_TEST_RESUME;
> -	default:
> -		report("test vmresume", 0);
> -		print_vmexit_info();
> -	}
> -	return VMX_TEST_VMEXIT;
> -}
> -
> -
> -/* name/init/guest_main/exit_handler/syscall_handler/guest_regs
> -   basic_* just implement some basic functions */
> -static struct vmx_test vmx_tests[] = {
> -	{ "null", basic_init, basic_guest_main, basic_exit_handler,
> -		basic_syscall_handler, {0} },
> -	{ "vmenter", basic_init, vmenter_main, vmenter_exit_handler,
> -		basic_syscall_handler, {0} },
> -};
> +extern struct vmx_test vmx_tests[];
>
>   int main(void)
>   {
> -	int i;
> +	int i = 0;
>
>   	setup_vm();
>   	setup_idt();
> +	fails = tests = 0;
> +	hypercall_field = 0;
>
>   	if (test_vmx_capability() != 0) {
>   		printf("ERROR : vmx not supported, check +vmx option\n");
> @@ -664,10 +588,9 @@ int main(void)
>   	}
>   	test_vmxoff();
>
> -	for (i = 1; i < ARRAY_SIZE(vmx_tests); ++i) {
> +	while (vmx_tests[++i].name != NULL)
>   		if (test_run(&vmx_tests[i]))
>   			goto exit;
> -	}
>
>   exit:
>   	printf("\nSUMMARY: %d tests, %d failures\n", tests, fails);
> diff --git a/x86/vmx.h b/x86/vmx.h
> index d80e000..06d31c7 100644
> --- a/x86/vmx.h
> +++ b/x86/vmx.h
> @@ -1,5 +1,5 @@
> -#ifndef __HYPERVISOR_H
> -#define __HYPERVISOR_H
> +#ifndef __VMX_H
> +#define __VMX_H
>
>   #include "libcflat.h"
>
> @@ -41,7 +41,7 @@ struct vmx_test {
>   	int exits;
>   };
>
> -static union vmx_basic {
> +union vmx_basic {
>   	u64 val;
>   	struct {
>   		u32 revision;
> @@ -53,37 +53,37 @@ static union vmx_basic {
>   			insouts:1,
>   			ctrl:1;
>   	};
> -} basic;
> +};
>
> -static union vmx_ctrl_pin {
> +union vmx_ctrl_pin {
>   	u64 val;
>   	struct {
>   		u32 set, clr;
>   	};
> -} ctrl_pin_rev;
> +};
>
> -static union vmx_ctrl_cpu {
> +union vmx_ctrl_cpu {
>   	u64 val;
>   	struct {
>   		u32 set, clr;
>   	};
> -} ctrl_cpu_rev[2];
> +};
>
> -static union vmx_ctrl_exit {
> +union vmx_ctrl_exit {
>   	u64 val;
>   	struct {
>   		u32 set, clr;
>   	};
> -} ctrl_exit_rev;
> +};
>
> -static union vmx_ctrl_ent {
> +union vmx_ctrl_ent {
>   	u64 val;
>   	struct {
>   		u32 set, clr;
>   	};
> -} ctrl_enter_rev;
> +};
>
> -static union vmx_ept_vpid {
> +union vmx_ept_vpid {
>   	u64 val;
>   	struct {
>   		u32:16,
> @@ -93,7 +93,7 @@ static union vmx_ept_vpid {
>   			: 11;
>   		u32	invvpid:1;
>   	};
> -} ept_vpid;
> +};
>
>   struct descr {
>   	u16 limit;
> @@ -432,6 +432,16 @@ enum Ctrl1 {
>   #define HYPERCALL_MASK		0xFFF
>   #define HYPERCALL_VMEXIT	0x1
>
> +
> +extern struct regs regs;
> +
> +extern union vmx_basic basic;
> +extern union vmx_ctrl_pin ctrl_pin_rev;
> +extern union vmx_ctrl_cpu ctrl_cpu_rev[2];
> +extern union vmx_ctrl_exit ctrl_exit_rev;
> +extern union vmx_ctrl_ent ctrl_enter_rev;
> +extern union vmx_ept_vpid  ept_vpid;
> +
>   static inline int vmcs_clear(struct vmcs *vmcs)
>   {
>   	bool ret;
> @@ -462,5 +472,8 @@ static inline int vmcs_save(struct vmcs **vmcs)
>   	return ret;
>   }
>
> +void report(const char *name, int result);
> +void print_vmexit_info();
> +
>   #endif
>
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> new file mode 100644
> index 0000000..1995837
> --- /dev/null
> +++ b/x86/vmx_tests.c
> @@ -0,0 +1,88 @@
> +#include "vmx.h"
> +
> +void basic_init()
> +{
> +}
> +
> +void basic_guest_main()
> +{
> +	/* Here is a basic guest_main, print Hello World */
> +	printf("\tHello World, this is null_guest_main!\n");
> +}
> +
> +int basic_exit_handler()
> +{
> +	u64 guest_rip;
> +	ulong reason;
> +
> +	guest_rip = vmcs_read(GUEST_RIP);
> +	reason = vmcs_read(EXI_REASON) & 0xff;
> +
> +	switch (reason) {
> +	case VMX_VMCALL:
> +		print_vmexit_info();
> +		vmcs_write(GUEST_RIP, guest_rip + 3);
> +		return VMX_TEST_RESUME;
> +	default:
> +		break;
> +	}
> +	printf("ERROR : Unhandled vmx exit.\n");
> +	print_vmexit_info();
> +	return VMX_TEST_EXIT;
> +}
> +
> +void basic_syscall_handler(u64 syscall_no)
> +{
> +}
> +
> +void vmenter_main()
> +{
> +	u64 rax;
> +	u64 rsp, resume_rsp;
> +
> +	report("test vmlaunch", 1);
> +
> +	asm volatile(
> +		"mov %%rsp, %0\n\t"
> +		"mov %3, %%rax\n\t"
> +		"vmcall\n\t"
> +		"mov %%rax, %1\n\t"
> +		"mov %%rsp, %2\n\t"
> +		: "=r"(rsp), "=r"(rax), "=r"(resume_rsp)
> +		: "g"(0xABCD));
> +	report("test vmresume", (rax == 0xFFFF) && (rsp == resume_rsp));
> +}
> +
> +int vmenter_exit_handler()
> +{
> +	u64 guest_rip;
> +	ulong reason;
> +
> +	guest_rip = vmcs_read(GUEST_RIP);
> +	reason = vmcs_read(EXI_REASON) & 0xff;
> +	switch (reason) {
> +	case VMX_VMCALL:
> +		if (regs.rax != 0xABCD) {
> +			report("test vmresume", 0);
> +			return VMX_TEST_VMEXIT;
> +		}
> +		regs.rax = 0xFFFF;
> +		vmcs_write(GUEST_RIP, guest_rip + 3);
> +		return VMX_TEST_RESUME;
> +	default:
> +		report("test vmresume", 0);
> +		print_vmexit_info();
> +	}
> +	return VMX_TEST_VMEXIT;
> +}
> +
> +/* name/init/guest_main/exit_handler/syscall_handler/guest_regs
> +   basic_* just implement some basic functions */
> +struct vmx_test vmx_tests[] = {
> +	{ "null", basic_init, basic_guest_main, basic_exit_handler,
> +		basic_syscall_handler, {0} },
> +	{ "vmenter", basic_init, vmenter_main, vmenter_exit_handler,
> +		basic_syscall_handler, {0} },
> +	{ NULL, NULL, NULL, NULL, NULL, {0} },
> +};
> +
>


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

end of thread, other threads:[~2013-08-07 15:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-05  3:32 [PATCH v3] kvm-unit-tests: VMX: Split VMX test suites to separate file Arthur Chunqi Li
2013-08-07 15:29 ` Paolo Bonzini

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