[2/2,kvm-unit-test] nVMX x86: Check VPID value on vmentry of L2 guests
diff mbox series

Message ID 20180904184259.12873-3-krish.sadhukhan@oracle.com
State New
Headers show
Series
  • [1/2] nVMX x86: Check VPID value on vmentry of L2 guests
Related show

Commit Message

Krish Sadhukhan Sept. 4, 2018, 6:42 p.m. UTC
According to section "Checks on VMX Controls" in Intel SDM vol 3C, the
following check needs to be enforced on vmentry of L2 guests:

    If the “enable VPID” VM-execution control is 1, the value of the
    of the VPID VM-execution control field must not be 0000H.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Reviewed-by: Mark Kanda <mark.kanda@oracle.com>
---
 x86/vmx_tests.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

Patch
diff mbox series

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 7a41732..99f4352 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3757,6 +3757,48 @@  static void test_apic_ctls(void)
 	test_virtual_intr_ctls();
 }
 
+/*
+ * If the “enable VPID” VM-execution control is 1, the value of the
+ * of the VPID VM-execution control field must not be 0000H.
+ * [Intel SDM]
+ */
+static void test_vpid(void)
+{
+	u32 saved_primary = vmcs_read(CPU_EXEC_CTRL0);
+	u32 saved_secondary = vmcs_read(CPU_EXEC_CTRL1);
+	u16 vpid = 0x0000;
+	int i;
+
+	if (!((ctrl_cpu_rev[0].clr & CPU_SECONDARY) &&
+	    (ctrl_cpu_rev[1].clr & CPU_VPID))) {
+		test_skip("Secondary controls and/or VPID not supported");
+		return;
+	}
+
+	vmcs_write(CPU_EXEC_CTRL0, saved_primary | CPU_SECONDARY);
+	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);
+	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);
+	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);
+		report_prefix_pop();
+	}
+
+	vmcs_write(CPU_EXEC_CTRL0, saved_primary);
+	vmcs_write(CPU_EXEC_CTRL1, saved_secondary);
+}
+
 static void set_vtpr(unsigned vtpr)
 {
 	*(u32 *)phys_to_virt(vmcs_read(APIC_VIRT_ADDR) + APIC_TASKPRI) = vtpr;
@@ -4304,6 +4346,7 @@  static void vmx_controls_test(void)
 	test_tpr_threshold();
 	test_nmi_ctrls();
 	test_invalid_event_injection();
+	test_vpid();
 }
 
 static bool valid_vmcs_for_vmentry(void)