[PATCH kvm-unit-tests 2/4] x86: vmx_tests: extend HOST_EFER tests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Extend the tests to cover the host address size bit.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 x86/vmx_tests.c | 126 +++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 74 insertions(+), 52 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index b404219..8851f64 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -6720,59 +6720,62 @@ static void test_host_ctl_regs(void)
 	vmcs_write(HOST_CR3, cr3_saved);
 }
 
-static void test_efer_bit(u32 fld, const char * fld_name, u32 ctrl_fld,
-			   u64 ctrl_bit, u64 efer_bit,
-			   const char *efer_bit_name)
+static void test_efer_one(u32 fld, const char * fld_name, u64 efer,
+			  u32 ctrl_fld, u64 ctrl,
+			  int i, const char *efer_bit_name)
 {
-	u64 efer_saved = vmcs_read(fld);
-	u32 ctrl_saved = vmcs_read(ctrl_fld);
-	u64 host_addr_size = ctrl_saved & EXI_HOST_64;
-	u64 efer;
+	bool ok;
 
-	vmcs_write(ctrl_fld, ctrl_saved & ~ctrl_bit);
-	efer = efer_saved & ~efer_bit;
-	vmcs_write(fld, efer);
-	report_prefix_pushf("%s bit turned off, %s %lx", efer_bit_name,
-			    fld_name, efer);
-	test_vmx_vmlaunch(0, false);
-	report_prefix_pop();
+	ok = true;
+	if (ctrl & EXI_LOAD_EFER) {
+		if (!!(efer & EFER_LMA) != !!(ctrl & EXI_HOST_64))
+			ok = false;
+		if (!!(efer & EFER_LME) != !!(ctrl & EXI_HOST_64))
+			ok = false;
+	}
 
-	efer = efer_saved | efer_bit;
+	vmcs_write(ctrl_fld, ctrl);
 	vmcs_write(fld, efer);
-	report_prefix_pushf("%s bit turned on, %s %lx", efer_bit_name,
-			    fld_name, efer);
-	test_vmx_vmlaunch(0, false);
-	report_prefix_pop();
+	report_prefix_pushf("%s %s bit turned %s, controls %s",
+			    fld_name, efer_bit_name,
+			    (i & 1) ? "on" : "off",
+			    (i & 2) ? "on" : "off");
 
-	vmcs_write(ctrl_fld, ctrl_saved | ctrl_bit);
-	efer = efer_saved & ~efer_bit;
-	vmcs_write(fld, efer);
-	report_prefix_pushf("%s bit turned off, %s %lx", efer_bit_name,
-			    fld_name, efer);
-	if (host_addr_size)
-		test_vmx_vmlaunch(VMXERR_ENTRY_INVALID_HOST_STATE_FIELD,
-				  false);
-	else
-		test_vmx_vmlaunch(0, false);
-	report_prefix_pop();
-
-	efer = efer_saved | efer_bit;
-	vmcs_write(fld, efer);
-	report_prefix_pushf("%s bit turned on, %s %lx", efer_bit_name,
-			    fld_name, efer);
-	if (host_addr_size)
+	if (ok)
 		test_vmx_vmlaunch(0, false);
 	else
 		test_vmx_vmlaunch(VMXERR_ENTRY_INVALID_HOST_STATE_FIELD,
 				  false);
 	report_prefix_pop();
+}
+
+static void test_efer_bit(u32 fld, const char * fld_name,
+			  u32 ctrl_fld, u64 ctrl_bit, u64 efer_bit,
+			  const char *efer_bit_name)
+{
+	u64 efer_saved = vmcs_read(fld);
+	u32 ctrl_saved = vmcs_read(ctrl_fld);
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		u64 efer = efer_saved & ~efer_bit;
+		u64 ctrl = ctrl_saved & ~ctrl_bit;
+
+		if (i & 1)
+			efer |= efer_bit;
+		if (i & 2)
+			ctrl |= ctrl_bit;
+
+		test_efer_one(fld, fld_name, efer, ctrl_fld, ctrl,
+			      i, efer_bit_name);
+	}
 
 	vmcs_write(ctrl_fld, ctrl_saved);
 	vmcs_write(fld, efer_saved);
 }
 
 static void test_efer(u32 fld, const char * fld_name, u32 ctrl_fld,
-		      u64 ctrl_bit)
+		      u64 ctrl_bit1, u64 ctrl_bit2)
 {
 	u64 efer_saved = vmcs_read(fld);
 	u32 ctrl_saved = vmcs_read(ctrl_fld);
@@ -6783,10 +6786,19 @@ static void test_efer(u32 fld, const char * fld_name, u32 ctrl_fld,
 	if (cpu_has_efer_nx())
 		efer_reserved_bits &= ~EFER_NX;
 
+	if (!ctrl_bit1) {
+		printf("\"Load-IA32-EFER\" exit control not supported\n");
+		goto test_entry_exit_mode;
+	}
+
+	report_prefix_pushf("%s %lx", fld_name, efer_saved);
+	test_vmx_vmlaunch(0, false);
+	report_prefix_pop();
+
 	/*
 	 * Check reserved bits
 	 */
-	vmcs_write(ctrl_fld, ctrl_saved & ~ctrl_bit);
+	vmcs_write(ctrl_fld, ctrl_saved & ~ctrl_bit1);
 	for (i = 0; i < 64; i++) {
 		if ((1ull << i) & efer_reserved_bits) {
 			efer = efer_saved | (1ull << i);
@@ -6797,15 +6809,14 @@ static void test_efer(u32 fld, const char * fld_name, u32 ctrl_fld,
 		}
 	}
 
-	vmcs_write(ctrl_fld, ctrl_saved | ctrl_bit);
+	vmcs_write(ctrl_fld, ctrl_saved | ctrl_bit1);
 	for (i = 0; i < 64; i++) {
 		if ((1ull << i) & efer_reserved_bits) {
 			efer = efer_saved | (1ull << i);
 			vmcs_write(fld, efer);
 			report_prefix_pushf("%s %lx", fld_name, efer);
-			test_vmx_vmlaunch(
-				VMXERR_ENTRY_INVALID_HOST_STATE_FIELD,
-				false);
+			test_vmx_vmlaunch(VMXERR_ENTRY_INVALID_HOST_STATE_FIELD,
+					  false);
 			report_prefix_pop();
 		}
 	}
@@ -6816,28 +6827,39 @@ static void test_efer(u32 fld, const char * fld_name, u32 ctrl_fld,
 	/*
 	 * Check LMA and LME bits
 	 */
-	test_efer_bit(fld, fld_name, ctrl_fld, ctrl_bit, EFER_LMA,
+	test_efer_bit(fld, fld_name,
+		      ctrl_fld, ctrl_bit1,
+		      EFER_LMA,
+		      "EFER_LMA");
+	test_efer_bit(fld, fld_name,
+		      ctrl_fld, ctrl_bit1,
+		      EFER_LME,
+		      "EFER_LME");
+
+test_entry_exit_mode:
+	test_efer_bit(fld, fld_name,
+		      ctrl_fld, ctrl_bit2,
+		      EFER_LMA,
 		      "EFER_LMA");
-	test_efer_bit(fld, fld_name, ctrl_fld, ctrl_bit, EFER_LME,
+	test_efer_bit(fld, fld_name,
+		      ctrl_fld, ctrl_bit2,
+		      EFER_LME,
 		      "EFER_LME");
 }
 
 /*
- * If the “load IA32_EFER†VM-exit control is 1, bits reserved in the
+ * If the 'load IA32_EFER' VM-exit control is 1, bits reserved in the
  * IA32_EFER MSR must be 0 in the field for that register. In addition,
  * the values of the LMA and LME bits in the field must each be that of
- * the “host address-space size†VM-exit control.
+ * the 'host address-space size' VM-exit control.
  *
  *  [Intel SDM]
  */
 static void test_host_efer(void)
 {
-	if (!(ctrl_exit_rev.clr & EXI_LOAD_EFER)) {
-		printf("\"Load-IA32-EFER\" exit control not supported\n");
-		return;
-	}
-
-	test_efer(HOST_EFER, "HOST_EFER", EXI_CONTROLS, EXI_LOAD_EFER);
+	test_efer(HOST_EFER, "HOST_EFER", EXI_CONTROLS, 
+		  ctrl_exit_rev.clr & EXI_LOAD_EFER,
+		  EXI_HOST_64);
 }
 
 /*
-- 
1.8.3.1





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux