[1/2,kvm-unit-test,nVMX] : Move the functionality of enter_guest() to __enter_guest() and make the former a wrapper of the latter
diff mbox series

Message ID 20190418213941.20977-2-krish.sadhukhan@oracle.com
State New
Headers show
Series
  • [1/2,kvm-unit-test,nVMX] : Move the functionality of enter_guest() to __enter_guest() and make the former a wrapper of the latter
Related show

Commit Message

Krish Sadhukhan April 18, 2019, 9:39 p.m. UTC
Currently enter_guest() aborts on any type of vmentry failures (early
failures or invalid guest state). But the vmentry tests that want to
validate the guest state need to continue running in spite of vmentry
failures arising out of an invalid guest state.

This patch moves the functionality of enter_guest() to __enter_guest() which
accepts a parameter to conditionally abort the test as opposed to the behavior
of enter_guest(). enter_guest() now calls __enter_guest() and preserves
compatibility of existing callers which expect the test to be aborted on
any type of vmentry failures.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Suggested-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
---
 x86/vmx.c | 27 ++++++++++++++++++---------
 x86/vmx.h |  4 ++++
 2 files changed, 22 insertions(+), 9 deletions(-)

Patch
diff mbox series

diff --git a/x86/vmx.c b/x86/vmx.c
index 6ba56bc..d29d21a 100644
--- a/x86/vmx.c
+++ b/x86/vmx.c
@@ -1583,10 +1583,10 @@  entry_failure_handler(struct vmentry_failure *failure)
 }
 
 /*
- * Tries to enter the guest. Returns true iff entry succeeded. Otherwise,
+ * Tries to enter the guest. Returns true if entry succeeded. Otherwise,
  * populates @failure.
  */
-static bool vmx_enter_guest(struct vmentry_failure *failure)
+static void vmx_enter_guest(struct vmentry_failure *failure)
 {
 	failure->early = 0;
 
@@ -1620,8 +1620,6 @@  static bool vmx_enter_guest(struct vmentry_failure *failure)
 
 	failure->vmlaunch = !launched;
 	failure->instr = launched ? "vmresume" : "vmlaunch";
-
-	return !failure->early && !(vmcs_read(EXI_REASON) & VMX_ENTRY_FAILURE);
 }
 
 static int vmx_run(void)
@@ -1631,7 +1629,9 @@  static int vmx_run(void)
 		bool entered;
 		struct vmentry_failure failure;
 
-		entered = vmx_enter_guest(&failure);
+		vmx_enter_guest(&failure);
+		entered = !failure.early &&
+			  !(vmcs_read(EXI_REASON) & VMX_ENTRY_FAILURE);
 
 		if (entered) {
 			/*
@@ -1765,10 +1765,9 @@  void test_set_guest(test_guest_func func)
 
 /*
  * Enters the guest (or launches it for the first time). Error to call once the
- * guest has returned (i.e., run past the end of its guest() function). Also
- * aborts if guest entry fails.
+ * guest has returned (i.e., run past the end of its guest() function).
  */
-void enter_guest(void)
+void __enter_guest(u8 abort_flag)
 {
 	struct vmentry_failure failure;
 
@@ -1778,7 +1777,11 @@  void enter_guest(void)
 	TEST_ASSERT_MSG(!guest_finished,
 			"Called enter_guest() after guest returned.");
 
-	if (!vmx_enter_guest(&failure)) {
+	vmx_enter_guest(&failure);
+	if ((abort_flag & ABORT_ON_EARLY_VMENTRY_FAIL && failure.early) ||
+	    (abort_flag & ABORT_ON_INVALID_GUEST_STATE &&
+	    vmcs_read(EXI_REASON) & VMX_ENTRY_FAILURE)) {
+
 		print_vmentry_failure_info(&failure);
 		abort();
 	}
@@ -1807,6 +1810,12 @@  void enter_guest(void)
 	}
 }
 
+void enter_guest(void)
+{
+	__enter_guest(ABORT_ON_EARLY_VMENTRY_FAIL |
+		      ABORT_ON_INVALID_GUEST_STATE);
+}
+
 extern struct vmx_test vmx_tests[];
 
 static bool
diff --git a/x86/vmx.h b/x86/vmx.h
index 8a00f73..eefd5dc 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -645,6 +645,9 @@  enum vm_instruction_error_number {
 #define VMCS_FIELD_RESERVED_SHIFT	(15)
 #define VMCS_FIELD_BIT_SIZE		(BITS_PER_LONG)
 
+#define        ABORT_ON_EARLY_VMENTRY_FAIL     0x1
+#define        ABORT_ON_INVALID_GUEST_STATE    0x2
+
 extern struct regs regs;
 
 extern union vmx_basic basic;
@@ -830,6 +833,7 @@  bool ept_execute_only_supported(void);
 bool ept_ad_bits_supported(void);
 
 void enter_guest(void);
+void __enter_guest(u8);
 
 typedef void (*test_guest_func)(void);
 typedef void (*test_teardown_func)(void *data);