[PATCH nVMX TEST 2/2] x86: Add test for checking APIC-access page on vmentry of L2 guests

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

 



According to the sub-section titled 'VM-Execution Control Fields' in the
section titled 'Basic VM-Entry Checks' in Intel SDM vol. 3C, the following
vmentry check must be enforced:

    If the “virtualize APIC-accesses” VM-execution control is 1, the
    APIC-access address must satisfy the following checks:

	- Bits 11:0 of the address must be 0.
	- The address should not set any bits beyond the processor’s
	  physical-address width.

This patch adds a unit-test to validate the vmentry check.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
Reviewed-by: Mihai Carabas <mihai.carabas@xxxxxxxxxx>
---
 x86/vmx_tests.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 9 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 613a8bd..d596d8c 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3430,23 +3430,40 @@ static void test_vmcs_page_values(const char *name,
 static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
 				     const char *field_name,
 				     const char *control_name,
-				     bool xfail_beyond_mapped_ram)
+				     bool xfail_beyond_mapped_ram,
+				     bool control_primary)
 {
 	u32 primary = vmcs_read(CPU_EXEC_CTRL0);
+	u32 secondary = vmcs_read(CPU_EXEC_CTRL1);
 	u64 page_addr;
 
-	if (!(ctrl_cpu_rev[0].clr & control_bit))
-		return;
+	if (control_primary) {
+		if (!(ctrl_cpu_rev[0].clr & control_bit))
+			return;
+	} else {
+		if (!(ctrl_cpu_rev[1].clr & control_bit))
+			return;
+	}
 
 	page_addr = vmcs_read(field);
 
 	report_prefix_pushf("%s enabled", control_name);
-	vmcs_write(CPU_EXEC_CTRL0, primary | control_bit);
+	if (control_primary) {
+		vmcs_write(CPU_EXEC_CTRL0, primary | control_bit);
+	} else {
+		vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY);
+		vmcs_write(CPU_EXEC_CTRL1, secondary | control_bit);
+	}
 	test_vmcs_page_values(field_name, field, false, xfail_beyond_mapped_ram);
 	report_prefix_pop();
 
 	report_prefix_pushf("%s disabled", control_name);
-	vmcs_write(CPU_EXEC_CTRL0, primary & ~control_bit);
+	if (control_primary) {
+		vmcs_write(CPU_EXEC_CTRL0, primary & ~control_bit);
+	} else {
+		vmcs_write(CPU_EXEC_CTRL0, primary & ~CPU_SECONDARY);
+		vmcs_write(CPU_EXEC_CTRL1, secondary & ~control_bit);
+	}
 	test_vmcs_page_values(field_name, field, true, false);
 	report_prefix_pop();
 
@@ -3463,9 +3480,11 @@ static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
 static void test_io_bitmaps(void)
 {
 	test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_A,
-				 "I/O bitmap A", "Use I/O bitmaps", false);
+				 "I/O bitmap A", "Use I/O bitmaps", false,
+				 true);
 	test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_B,
-				 "I/O bitmap B", "Use I/O bitmaps", false);
+				 "I/O bitmap B", "Use I/O bitmaps", false,
+				 true);
 }
 
 /*
@@ -3477,7 +3496,8 @@ static void test_io_bitmaps(void)
 static void test_msr_bitmap(void)
 {
 	test_vmcs_page_reference(CPU_MSR_BITMAP, MSR_BITMAP,
-				 "MSR bitmap", "Use MSR bitmaps", false);
+				 "MSR bitmap", "Use MSR bitmaps", false,
+				 true);
 }
 
 /*
@@ -3491,7 +3511,27 @@ static void test_msr_bitmap(void)
 static void test_apic_virt_addr(void)
 {
 	test_vmcs_page_reference(CPU_TPR_SHADOW, APIC_VIRT_ADDR,
-				 "virtual-APIC address", "Use TPR shadow", true);
+				 "virtual-APIC address", "Use TPR shadow",
+				 true, true);
+}
+
+/*
+ * If the "virtualize APIC-accesses" VM-execution control is 1, the
+ * APIC-access address must satisfy the following checks:
+ *  - Bits 11:0 of the address must be 0.
+ *  - The address should not set any bits beyond the processor's
+ *    physical-address width.
+ * [Intel SDM]
+ */
+static void test_apic_access_addr(void)
+{
+	void *apic_access_page = alloc_page();
+
+	vmcs_write(APIC_ACCS_ADDR, virt_to_phys(apic_access_page));
+
+	test_vmcs_page_reference(CPU_VIRT_APIC_ACCESSES, APIC_ACCS_ADDR,
+				 "APIC-access address",
+				 "virtualize APIC-accesses", true, false);
 }
 
 static void set_vtpr(unsigned vtpr)
@@ -3761,6 +3801,7 @@ static void vmx_controls_test(void)
 	test_io_bitmaps();
 	test_msr_bitmap();
 	test_apic_virt_addr();
+	test_apic_access_addr();
 	test_tpr_threshold();
 	test_nmi_ctrls();
 }
-- 
2.9.5




[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