[3/4,v2,kvm-unit-test,nVMX] : Change 'test_vmx_controls' to 'test_vmlaunch' and add a parameter for expected error
diff mbox series

Message ID 20190205223427.7387-4-krish.sadhukhan@oracle.com
State New
Headers show
Series
  • [1/4,v2,nVMX] : Add a vmentry check for HOST_SYSENTER_ESP and HOST_SYSENTER_EIP fields
Related show

Commit Message

Krish Sadhukhan Feb. 5, 2019, 10:34 p.m. UTC
The function 'test_vmx_controls' has thus far been used to test the VMX
controls and has the expected error code (returned by KVM) hard-coded in it.
When vmlaunch fails due to a bad Host State Area, the error code returned by
KVM is different. So rename this function and add a new parameter so that it
can also be used for testing the Host State Area during vmlaunch of L2 guests.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
---
 x86/vmx_tests.c | 164 +++++++++++++++++++++++++-----------------------
 1 file changed, 86 insertions(+), 78 deletions(-)

Comments

Sean Christopherson Feb. 5, 2019, 11:30 p.m. UTC | #1
On Tue, Feb 05, 2019 at 05:34:26PM -0500, Krish Sadhukhan wrote:
> The function 'test_vmx_controls' has thus far been used to test the VMX
> controls and has the expected error code (returned by KVM) hard-coded in it.
> When vmlaunch fails due to a bad Host State Area, the error code returned by
> KVM is different. So rename this function and add a new parameter so that it
> can also be used for testing the Host State Area during vmlaunch of L2 guests.
> 
> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
> ---
>  x86/vmx_tests.c | 164 +++++++++++++++++++++++++-----------------------
>  1 file changed, 86 insertions(+), 78 deletions(-)
> 
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index 9a3cdee..b69a7d9 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -3285,7 +3285,7 @@ success:
>  /*
>   * Try to launch the current VMCS.
>   */
> -static void test_vmx_controls(bool controls_valid, bool xfail)
> +static void test_vmlaunch(bool controls_valid, bool xfail, u32 error_expected)
>  {
>  	bool success = vmlaunch_succeeds();
>  	u32 vmx_inst_err;
> @@ -3295,8 +3295,8 @@ static void test_vmx_controls(bool controls_valid, bool xfail)
>  	if (!success) {
>  		vmx_inst_err = vmcs_read(VMX_INST_ERROR);
>  		report("VMX inst error is %d (actual %d)",
> -		       vmx_inst_err == VMXERR_ENTRY_INVALID_CONTROL_FIELD,
> -		       VMXERR_ENTRY_INVALID_CONTROL_FIELD, vmx_inst_err);
> +		       vmx_inst_err == error_expected, error_expected,
> +		       vmx_inst_err);
>  	}

That's a lot of call sites to change just to reuse a few lines of code.
And the xfail stuff isn't needed for the new host state checks.  What
about moving the VMX_INST_ERROR logic to a helper and reusing that?

From 01c9fe2e0d4e0b4593334396a0a880f5adfd3fb5 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <sean.j.christopherson@intel.com>
Date: Tue, 5 Feb 2019 15:25:24 -0800
Subject: [PATCH] KVM: nVMX: Add helper to check VMX_INST_ERROR after failed
 vmlaunch

...so that the code can be reused for failure due to reasons other than
invalid controls, e.g. invalid host state.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
---
 x86/vmx_tests.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 28bab81..97c2163 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3285,22 +3285,26 @@ success:
 	return true;
 }
 
+static void check_vmx_instr_err(u32 expected)
+{
+	u32 vmx_inst_err;
+
+	vmx_inst_err = vmcs_read(VMX_INST_ERROR);
+	report("VMX inst error is %d (actual %d)",
+	       vmx_inst_err == expected, expected, vmx_inst_err);
+}
+
 /*
  * Try to launch the current VMCS.
  */
 static void test_vmx_controls(bool controls_valid, bool xfail)
 {
 	bool success = vmlaunch_succeeds();
-	u32 vmx_inst_err;
 
 	report_xfail("vmlaunch %s", xfail, success == controls_valid,
 		     controls_valid ? "succeeds" : "fails");
-	if (!success) {
-		vmx_inst_err = vmcs_read(VMX_INST_ERROR);
-		report("VMX inst error is %d (actual %d)",
-		       vmx_inst_err == VMXERR_ENTRY_INVALID_CONTROL_FIELD,
-		       VMXERR_ENTRY_INVALID_CONTROL_FIELD, vmx_inst_err);
-	}
+	if (!success)
+		check_vmx_instr_err(VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 }
 
 /*
Krish Sadhukhan Feb. 6, 2019, 2:19 a.m. UTC | #2
On 02/05/2019 03:30 PM, Sean Christopherson wrote:
> On Tue, Feb 05, 2019 at 05:34:26PM -0500, Krish Sadhukhan wrote:
>> The function 'test_vmx_controls' has thus far been used to test the VMX
>> controls and has the expected error code (returned by KVM) hard-coded in it.
>> When vmlaunch fails due to a bad Host State Area, the error code returned by
>> KVM is different. So rename this function and add a new parameter so that it
>> can also be used for testing the Host State Area during vmlaunch of L2 guests.
>>
>> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
>> ---
>>   x86/vmx_tests.c | 164 +++++++++++++++++++++++++-----------------------
>>   1 file changed, 86 insertions(+), 78 deletions(-)
>>
>> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
>> index 9a3cdee..b69a7d9 100644
>> --- a/x86/vmx_tests.c
>> +++ b/x86/vmx_tests.c
>> @@ -3285,7 +3285,7 @@ success:
>>   /*
>>    * Try to launch the current VMCS.
>>    */
>> -static void test_vmx_controls(bool controls_valid, bool xfail)
>> +static void test_vmlaunch(bool controls_valid, bool xfail, u32 error_expected)
>>   {
>>   	bool success = vmlaunch_succeeds();
>>   	u32 vmx_inst_err;
>> @@ -3295,8 +3295,8 @@ static void test_vmx_controls(bool controls_valid, bool xfail)
>>   	if (!success) {
>>   		vmx_inst_err = vmcs_read(VMX_INST_ERROR);
>>   		report("VMX inst error is %d (actual %d)",
>> -		       vmx_inst_err == VMXERR_ENTRY_INVALID_CONTROL_FIELD,
>> -		       VMXERR_ENTRY_INVALID_CONTROL_FIELD, vmx_inst_err);
>> +		       vmx_inst_err == error_expected, error_expected,
>> +		       vmx_inst_err);
>>   	}
> That's a lot of call sites to change just to reuse a few lines of code.
> And the xfail stuff isn't needed for the new host state checks.  What
> about moving the VMX_INST_ERROR logic to a helper and reusing that?
>
>  From 01c9fe2e0d4e0b4593334396a0a880f5adfd3fb5 Mon Sep 17 00:00:00 2001
> From: Sean Christopherson <sean.j.christopherson@intel.com>
> Date: Tue, 5 Feb 2019 15:25:24 -0800
> Subject: [PATCH] KVM: nVMX: Add helper to check VMX_INST_ERROR after failed
>   vmlaunch
>
> ...so that the code can be reused for failure due to reasons other than
> invalid controls, e.g. invalid host state.
>
> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> ---
>   x86/vmx_tests.c | 18 +++++++++++-------
>   1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index 28bab81..97c2163 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -3285,22 +3285,26 @@ success:
>   	return true;
>   }
>   
> +static void check_vmx_instr_err(u32 expected)
> +{
> +	u32 vmx_inst_err;
> +
> +	vmx_inst_err = vmcs_read(VMX_INST_ERROR);
> +	report("VMX inst error is %d (actual %d)",
> +	       vmx_inst_err == expected, expected, vmx_inst_err);
> +}
> +
>   /*
>    * Try to launch the current VMCS.
>    */
>   static void test_vmx_controls(bool controls_valid, bool xfail)
>   {
>   	bool success = vmlaunch_succeeds();
> -	u32 vmx_inst_err;
>   
>   	report_xfail("vmlaunch %s", xfail, success == controls_valid,
>   		     controls_valid ? "succeeds" : "fails");
> -	if (!success) {
> -		vmx_inst_err = vmcs_read(VMX_INST_ERROR);
> -		report("VMX inst error is %d (actual %d)",
> -		       vmx_inst_err == VMXERR_ENTRY_INVALID_CONTROL_FIELD,
> -		       VMXERR_ENTRY_INVALID_CONTROL_FIELD, vmx_inst_err);
> -	}
> +	if (!success)
> +		check_vmx_instr_err(VMXERR_ENTRY_INVALID_CONTROL_FIELD);
>   }
>   
>   /*

First of all,  'test_vmx_controls' seems a misnomer to me. All that this 
function does is vmlaunch'es the current VMCS and checks the error. From 
that perspective, something like 'do_vmlaunch' seems a more appropriate 
name to me. Also, we need to encapsulate the vmlaunch call and the error 
checking within a function such that the function can be reused for any 
VMCS field and not just the VMX control fields.

With respect to your suggested changes in patch# 4, the following lines 
of code will have to be duplicated each time we test a Host State Area 
field (or any other non-VMX-control field):

         success = vmlaunch_succeeds();
         report("vmlaunch %s", !success, "fails");
         if (!success)
check_vmx_instr_err(VMXERR_ENTRY_INVALID_HOST_STATE_FIELD);


Even though the call sites need to be changed, how about having two 
different versions of 'do_vmlaunch' - one for 'xfail' cases and the 
other for regular cases - such that any of these 'do_vmlaunch' functions 
can be used for any type of VMCS field and not just the VMX controls ?

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index ee0c9ff..336d0df 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3282,22 +3282,43 @@ success:
         return true;
  }

+static void check_vmx_instr_err(u32 expected)
+{
+       u32 vmx_inst_err;
+
+       vmx_inst_err = vmcs_read(VMX_INST_ERROR);
+       report("VMX inst error is %d (actual %d)",
+              vmx_inst_err == expected, expected, vmx_inst_err);
+}
+
  /*
   * Try to launch the current VMCS.
   */
-static void test_vmx_controls(bool controls_valid, bool xfail)
+static void do_vmlaunch(bool controls_valid, u32 error_expected)
+{
+       bool success = vmlaunch_succeeds();
+       u32 vmx_inst_err;
+
+       report("vmlaunch %s", success == controls_valid,
+                    controls_valid ? "succeeds" : "fails");
+       if (!success)
+               check_vmx_instr_err(error_expected);
+}
+
+
+/*
+ * Try to launch the current VMCS.
+ */
+static void do_vmlaunch_xfail(bool controls_valid, u32 error_expected,
+                               bool xfail)
  {
         bool success = vmlaunch_succeeds();
         u32 vmx_inst_err;

         report_xfail("vmlaunch %s", xfail, success == controls_valid,
                      controls_valid ? "succeeds" : "fails");
-       if (!success) {
-               vmx_inst_err = vmcs_read(VMX_INST_ERROR);
-               report("VMX inst error is %d (actual %d)",
-                      vmx_inst_err == VMXERR_ENTRY_INVALID_CONTROL_FIELD,
-                      VMXERR_ENTRY_INVALID_CONTROL_FIELD, vmx_inst_err);
-       }
+       if (!success)
+               check_vmx_instr_err(error_expected);
  }

Patch
diff mbox series

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 9a3cdee..b69a7d9 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3285,7 +3285,7 @@  success:
 /*
  * Try to launch the current VMCS.
  */
-static void test_vmx_controls(bool controls_valid, bool xfail)
+static void test_vmlaunch(bool controls_valid, bool xfail, u32 error_expected)
 {
 	bool success = vmlaunch_succeeds();
 	u32 vmx_inst_err;
@@ -3295,8 +3295,8 @@  static void test_vmx_controls(bool controls_valid, bool xfail)
 	if (!success) {
 		vmx_inst_err = vmcs_read(VMX_INST_ERROR);
 		report("VMX inst error is %d (actual %d)",
-		       vmx_inst_err == VMXERR_ENTRY_INVALID_CONTROL_FIELD,
-		       VMXERR_ENTRY_INVALID_CONTROL_FIELD, vmx_inst_err);
+		       vmx_inst_err == error_expected, error_expected,
+		       vmx_inst_err);
 	}
 }
 
@@ -3334,7 +3334,7 @@  static void test_rsvd_ctl_bit_value(const char *name, union vmx_ctrl_msr msr,
 		vmcs_write(encoding, msr.set & ~mask);
 		expected = !(msr.set & mask);
 	}
-	test_vmx_controls(expected, false);
+	test_vmlaunch(expected, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	vmcs_write(encoding, controls);
 	report_prefix_pop();
 }
@@ -3430,7 +3430,7 @@  static void try_cr3_target_count(unsigned i, unsigned max)
 {
 	report_prefix_pushf("CR3 target count 0x%x", i);
 	vmcs_write(CR3_TARGET_COUNT, i);
-	test_vmx_controls(i <= max, false);
+	test_vmlaunch(i <= max, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 }
 
@@ -3475,9 +3475,9 @@  static void test_vmcs_addr(const char *name,
 
 	report_prefix_pushf("%s = %lx", name, addr);
 	vmcs_write(encoding, addr);
-	test_vmx_controls(ignored || (IS_ALIGNED(addr, align) &&
+	test_vmlaunch(ignored || (IS_ALIGNED(addr, align) &&
 				  addr < (1ul << cpuid_maxphyaddr())),
-			  xfail);
+			  xfail, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 	xfail = false;
 }
@@ -3696,7 +3696,8 @@  static void test_apic_virtual_ctls(void)
 			vmcs_write(CPU_EXEC_CTRL1, secondary);
 			report_prefix_pushf("Use TPR shadow %s, virtualize x2APIC mode %s, APIC-register virtualization %s, virtual-interrupt delivery %s",
 				str, (secondary & CPU_VIRT_X2APIC) ? "enabled" : "disabled", (secondary & CPU_APIC_REG_VIRT) ? "enabled" : "disabled", (secondary & CPU_VINTD) ? "enabled" : "disabled");
-			test_vmx_controls(ctrl, false);
+			test_vmlaunch(ctrl, false,
+					VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 			report_prefix_pop();
 		}
 
@@ -3723,22 +3724,22 @@  static void test_apic_virtual_ctls(void)
 	secondary &= ~CPU_VIRT_APIC_ACCESSES;
 	vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VIRT_X2APIC);
 	report_prefix_pushf("Virtualize x2APIC mode disabled; virtualize APIC access disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VIRT_APIC_ACCESSES);
 	report_prefix_pushf("Virtualize x2APIC mode disabled; virtualize APIC access enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VIRT_X2APIC);
 	report_prefix_pushf("Virtualize x2APIC mode enabled; virtualize APIC access enabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VIRT_APIC_ACCESSES);
 	report_prefix_pushf("Virtualize x2APIC mode enabled; virtualize APIC access disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL0, saved_primary);
@@ -3767,22 +3768,22 @@  static void test_virtual_intr_ctls(void)
 	vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VINTD);
 	vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT);
 	report_prefix_pushf("Virtualize interrupt-delivery disabled; external-interrupt exiting disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD);
 	report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, pin | PIN_EXTINT);
 	report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT);
 	report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL0, saved_primary);
@@ -3794,7 +3795,7 @@  static void test_pi_desc_addr(u64 addr, bool ctrl)
 {
 	vmcs_write(POSTED_INTR_DESC_ADDR, addr);
 	report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-descriptor-address 0x%lx", addr);
-	test_vmx_controls(ctrl, false);
+	test_vmlaunch(ctrl, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 }
 
@@ -3839,37 +3840,37 @@  static void test_posted_intr(void)
 	secondary &= ~CPU_VINTD;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery disabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary |= CPU_VINTD;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	exit_ctl &= ~EXI_INTA;
 	vmcs_write(EXI_CONTROLS, exit_ctl);
 	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled; acknowledge-interrupt-on-exit disabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	exit_ctl |= EXI_INTA;
 	vmcs_write(EXI_CONTROLS, exit_ctl);
 	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled; acknowledge-interrupt-on-exit enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary &= ~CPU_VINTD;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery disabled; acknowledge-interrupt-on-exit enabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary |= CPU_VINTD;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled; acknowledge-interrupt-on-exit enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/*
@@ -3879,21 +3880,21 @@  static void test_posted_intr(void)
 		vec = (1ul << i);
 		vmcs_write(PINV, vec);
 		report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-notification-vector %u", vec);
-		test_vmx_controls(true, false);
+		test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 	for (i = 8; i < 16; i++) {
 		vec = (1ul << i);
 		vmcs_write(PINV, vec);
 		report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-notification-vector %u", vec);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 
 	vec &= ~(0xff << 8);
 	vmcs_write(PINV, vec);
 	report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-notification-vector %u", vec);
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/*
@@ -3950,19 +3951,19 @@  static void test_vpid(void)
 	vmcs_write(CPU_EXEC_CTRL1, saved_secondary & ~CPU_VPID);
 	vmcs_write(VPID, vpid);
 	report_prefix_pushf("VPID disabled; VPID value %x", vpid);
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL1, saved_secondary | CPU_VPID);
 	report_prefix_pushf("VPID enabled; VPID value %x", vpid);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	for (i = 0; i < 16; i++) {
 		vpid = (short)1 << i;;
 		vmcs_write(VPID, vpid);
 		report_prefix_pushf("VPID enabled; VPID value %x", vpid);
-		test_vmx_controls(true, false);
+		test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 
@@ -3989,7 +3990,7 @@  static void try_tpr_threshold_and_vtpr(unsigned threshold, unsigned vtpr)
 	set_vtpr(vtpr);
 	report_prefix_pushf("TPR threshold 0x%x, VTPR.class 0x%x",
 	    threshold, (vtpr >> 4) & 0xf);
-	test_vmx_controls(valid, false);
+	test_vmlaunch(valid, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 }
 
@@ -4016,7 +4017,7 @@  static void test_invalid_event_injection(void)
 			    "RESERVED interruption type invalid [-]",
 			    ent_intr_info);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	ent_intr_info = ent_intr_info_base | INTR_TYPE_EXT_INTR |
@@ -4025,7 +4026,7 @@  static void test_invalid_event_injection(void)
 			    "RESERVED interruption type invalid [+]",
 			    ent_intr_info);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/* If the interruption type is other event, the vector is 0. */
@@ -4034,7 +4035,7 @@  static void test_invalid_event_injection(void)
 			    "(OTHER EVENT && vector != 0) invalid [-]",
 			    ent_intr_info);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/* If the interruption type is NMI, the vector is 2 (negative case). */
@@ -4042,7 +4043,7 @@  static void test_invalid_event_injection(void)
 	report_prefix_pushf("%s, VM-entry intr info=0x%x",
 			    "(NMI && vector != 2) invalid [-]", ent_intr_info);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/* If the interruption type is NMI, the vector is 2 (positive case). */
@@ -4050,7 +4051,7 @@  static void test_invalid_event_injection(void)
 	report_prefix_pushf("%s, VM-entry intr info=0x%x",
 			    "(NMI && vector == 2) valid [+]", ent_intr_info);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/*
@@ -4062,7 +4063,7 @@  static void test_invalid_event_injection(void)
 			    "(HW exception && vector > 31) invalid [-]",
 			    ent_intr_info);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/*
@@ -4078,7 +4079,7 @@  static void test_invalid_event_injection(void)
 	disable_unrestricted_guest();
 	vmcs_write(GUEST_CR0, guest_cr0_save & ~X86_CR0_PE & ~X86_CR0_PG);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	ent_intr_info = ent_intr_info_base | INTR_INFO_DELIVER_CODE_MASK |
@@ -4089,7 +4090,7 @@  static void test_invalid_event_injection(void)
 	disable_unrestricted_guest();
 	vmcs_write(GUEST_CR0, guest_cr0_save & ~X86_CR0_PE & ~X86_CR0_PG);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	ent_intr_info = ent_intr_info_base | INTR_INFO_DELIVER_CODE_MASK |
@@ -4100,7 +4101,7 @@  static void test_invalid_event_injection(void)
 	enable_unrestricted_guest();
 	vmcs_write(GUEST_CR0, guest_cr0_save & ~X86_CR0_PE & ~X86_CR0_PG);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	ent_intr_info = ent_intr_info_base | INTR_TYPE_HARD_EXCEPTION |
@@ -4110,7 +4111,7 @@  static void test_invalid_event_injection(void)
 			    ent_intr_info);
 	vmcs_write(GUEST_CR0, guest_cr0_save | X86_CR0_PE);
 	vmcs_write(ENT_INTR_INFO, ent_intr_info);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/* deliver-error-code is 1 iff the interruption type is HW exception */
@@ -4126,7 +4127,7 @@  static void test_invalid_event_injection(void)
 		report_prefix_pushf("VM-entry intr info=0x%x [-]",
 				    ent_intr_info);
 		vmcs_write(ENT_INTR_INFO, ent_intr_info);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 	report_prefix_pop();
@@ -4160,7 +4161,8 @@  static void test_invalid_event_injection(void)
 		report_prefix_pushf("VM-entry intr info=0x%x [-]",
 				    ent_intr_info);
 		vmcs_write(ENT_INTR_INFO, ent_intr_info);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false,
+				VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 
 		/* Positive case */
@@ -4172,7 +4174,7 @@  static void test_invalid_event_injection(void)
 		report_prefix_pushf("VM-entry intr info=0x%x [+]",
 				    ent_intr_info);
 		vmcs_write(ENT_INTR_INFO, ent_intr_info);
-		test_vmx_controls(true, false);
+		test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 	report_prefix_pop();
@@ -4187,7 +4189,8 @@  static void test_invalid_event_injection(void)
 		report_prefix_pushf("VM-entry intr info=0x%x [-]",
 				    ent_intr_info);
 		vmcs_write(ENT_INTR_INFO, ent_intr_info);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false,
+				VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 	report_prefix_pop();
@@ -4207,7 +4210,8 @@  static void test_invalid_event_injection(void)
 		report_prefix_pushf("VM-entry intr error=0x%x [-]",
 				    ent_intr_err);
 		vmcs_write(ENT_INTR_ERROR, ent_intr_err);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false,
+				VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 	vmcs_write(ENT_INTR_ERROR, 0x00000000);
@@ -4244,7 +4248,8 @@  static void test_invalid_event_injection(void)
 		report_prefix_pushf("VM-entry intr length = 0x%x [-]",
 				    ent_intr_len);
 		vmcs_write(ENT_INST_LEN, ent_intr_len);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false,
+				VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 
 		/* Instruction length set to 16 should fail */
@@ -4252,7 +4257,8 @@  static void test_invalid_event_injection(void)
 		report_prefix_pushf("VM-entry intr length = 0x%x [-]",
 				    ent_intr_len);
 		vmcs_write(ENT_INST_LEN, 0x00000010);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false,
+				VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 
 		report_prefix_pop();
@@ -4292,7 +4298,7 @@  static void try_tpr_threshold(unsigned threshold)
 	set_vtpr(-1);
 	vmcs_write(TPR_THRESHOLD, threshold);
 	report_prefix_pushf("TPR threshold 0x%x, VTPR.class 0xf", threshold);
-	test_vmx_controls(valid, false);
+	test_vmlaunch(valid, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	if (valid)
@@ -4440,22 +4446,22 @@  static void test_nmi_ctrls(void)
 
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls);
 	report_prefix_pushf("NMI-exiting disabled, virtual-NMIs disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls | PIN_VIRT_NMI);
 	report_prefix_pushf("NMI-exiting disabled, virtual-NMIs enabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls | (PIN_NMI | PIN_VIRT_NMI));
 	report_prefix_pushf("NMI-exiting enabled, virtual-NMIs enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls | PIN_NMI);
 	report_prefix_pushf("NMI-exiting enabled, virtual-NMIs disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	if (!(ctrl_cpu_rev[0].clr & CPU_NMI_WINDOW)) {
@@ -4466,25 +4472,25 @@  static void test_nmi_ctrls(void)
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls);
 	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0 | CPU_NMI_WINDOW);
 	report_prefix_pushf("Virtual-NMIs disabled, NMI-window-exiting enabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls);
 	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0);
 	report_prefix_pushf("Virtual-NMIs disabled, NMI-window-exiting disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls | (PIN_NMI | PIN_VIRT_NMI));
 	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0 | CPU_NMI_WINDOW);
 	report_prefix_pushf("Virtual-NMIs enabled, NMI-window-exiting enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, test_pin_ctrls | (PIN_NMI | PIN_VIRT_NMI));
 	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0);
 	report_prefix_pushf("Virtual-NMIs enabled, NMI-window-exiting disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	/* Restore the controls to their original values */
@@ -4498,7 +4504,7 @@  static void test_eptp_ad_bit(u64 eptp, bool ctrl)
 	vmcs_write(EPTP, eptp);
 	report_prefix_pushf("Enable-EPT enabled; EPT accessed and dirty flag %s",
 	    (eptp & EPTP_AD_FLAG) ? "1": "0");
-	test_vmx_controls(ctrl, false);
+	test_vmlaunch(ctrl, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 }
@@ -4581,7 +4587,7 @@  static void test_ept_eptp(void)
 		vmcs_write(EPTP, eptp);
 		report_prefix_pushf("Enable-EPT enabled; EPT memory type %lu",
 		    eptp & EPT_MEM_TYPE_MASK);
-		test_vmx_controls(ctrl, false);
+		test_vmlaunch(ctrl, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 
@@ -4601,7 +4607,7 @@  static void test_ept_eptp(void)
 		vmcs_write(EPTP, eptp);
 		report_prefix_pushf("Enable-EPT enabled; EPT page walk length %lu",
 		    eptp & EPTP_PG_WALK_LEN_MASK);
-		test_vmx_controls(ctrl, false);
+		test_vmlaunch(ctrl, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 
@@ -4643,7 +4649,7 @@  static void test_ept_eptp(void)
 		report_prefix_pushf("Enable-EPT enabled; reserved bits [11:7] %lu",
 		    (eptp >> EPTP_RESERV_BITS_SHIFT) &
 		    EPTP_RESERV_BITS_MASK);
-		test_vmx_controls(ctrl, false);
+		test_vmlaunch(ctrl, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 
@@ -4665,32 +4671,32 @@  static void test_ept_eptp(void)
 		vmcs_write(EPTP, eptp);
 		report_prefix_pushf("Enable-EPT enabled; reserved bits [63:N] %lu",
 		    (eptp >> maxphysaddr) & resv_bits_mask);
-		test_vmx_controls(ctrl, false);
+		test_vmlaunch(ctrl, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 
 	secondary &= ~(CPU_EPT | CPU_URG);
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Enable-EPT disabled, unrestricted-guest disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary |= CPU_URG;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Enable-EPT disabled, unrestricted-guest enabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary |= CPU_EPT;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Enable-EPT enabled, unrestricted-guest enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary &= ~CPU_URG;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("Enable-EPT enabled, unrestricted-guest disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(CPU_EXEC_CTRL0, primary_saved);
@@ -4727,25 +4733,25 @@  static void test_pml(void)
 	secondary &= ~(CPU_PML | CPU_EPT);
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("enable-PML disabled, enable-EPT disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary |= CPU_PML;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("enable-PML enabled, enable-EPT disabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary |= CPU_EPT;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("enable-PML enabled, enable-EPT enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	secondary &= ~CPU_PML;
 	vmcs_write(CPU_EXEC_CTRL1, secondary);
 	report_prefix_pushf("enable-PML disabled, enable EPT enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	test_vmcs_addr_reference(CPU_PML, PMLADDR, "PML address", "PML",
@@ -4779,25 +4785,25 @@  static void test_vmx_preemption_timer(void)
 	exit &= ~EXI_SAVE_PREEMPT;
 	vmcs_write(EXI_CONTROLS, exit);
 	report_prefix_pushf("enable-VMX-preemption-timer enabled, save-VMX-preemption-timer disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	exit |= EXI_SAVE_PREEMPT;
 	vmcs_write(EXI_CONTROLS, exit);
 	report_prefix_pushf("enable-VMX-preemption-timer enabled, save-VMX-preemption-timer enabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	pin &= ~PIN_PREEMPT;
 	vmcs_write(PIN_CONTROLS, pin);
 	report_prefix_pushf("enable-VMX-preemption-timer disabled, save-VMX-preemption-timer enabled");
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	exit &= ~EXI_SAVE_PREEMPT;
 	vmcs_write(EXI_CONTROLS, exit);
 	report_prefix_pushf("enable-VMX-preemption-timer disabled, save-VMX-preemption-timer disabled");
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	report_prefix_pop();
 
 	vmcs_write(PIN_CONTROLS, saved_pin);
@@ -4867,7 +4873,8 @@  static void test_exit_msr_store(void)
 		vmcs_write(EXIT_MSR_ST_ADDR, tmp);
 		report_prefix_pushf("VM-exit MSR-store addr [4:0] %lx",
 				    tmp & 0xf);
-		test_vmx_controls(false, false);
+		test_vmlaunch(false, false,
+				VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 		report_prefix_pop();
 	}
 
@@ -4889,16 +4896,17 @@  static void test_exit_msr_store(void)
 			1ul << i;
 		vmcs_write(EXIT_MSR_ST_ADDR,
 			   tmp - (exit_msr_st_cnt * 16 - 1));
-                test_vmx_controls(false, false);
+                test_vmlaunch(false, false,
+				VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	}
 
 	vmcs_write(EXI_MSR_ST_CNT, 2);
 	vmcs_write(EXIT_MSR_ST_ADDR, (1ULL << cpuid_maxphyaddr()) - 16);
-	test_vmx_controls(false, false);
+	test_vmlaunch(false, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	vmcs_write(EXIT_MSR_ST_ADDR, (1ULL << cpuid_maxphyaddr()) - 32);
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 	vmcs_write(EXIT_MSR_ST_ADDR, (1ULL << cpuid_maxphyaddr()) - 48);
-	test_vmx_controls(true, false);
+	test_vmlaunch(true, false, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 }
 
 /*