[PATCH 4/4] kvm-unit-test: nVMX: Check GUEST_DEBUGCTL and GUEST_DR7 on vmentry of nested guests

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

 



According to section "Checks on Guest Control Registers, Debug Registers, and
and MSRs" in Intel SDM vol 3C, the following checks are performed on vmentry
of nested guests:

    If the "load debug controls" VM-entry control is 1,

       - bits reserved in the IA32_DEBUGCTL MSR must be 0 in the field for
         that register. The first processors to support the virtual-machine
         extensions supported only the 1-setting of this control and thus
         performed this check unconditionally.

       - bits 63:32 in the DR7 field must be 0.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
Reviewed-by: Karl Heubaum <karl.heubaum@xxxxxxxxxx>
---
 x86/vmx_tests.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 8ad2674..0207caf 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -7154,6 +7154,64 @@ static void test_load_guest_pat(void)
 	test_pat(GUEST_PAT, "GUEST_PAT", ENT_CONTROLS, ENT_LOAD_PAT);
 }
 
+/*
+ * If the “load debug controls” VM-entry control is 1,
+ *
+ *   - bits reserved in the IA32_DEBUGCTL MSR must be 0 in the field for
+ *     that register.
+ *   - bits 63:32 in the DR7 field must be 0.
+ */
+static void test_debugctl(void)
+{
+	u64 debugctl_saved = vmcs_read(GUEST_DEBUGCTL);
+	u32 entry_ctl_saved = vmcs_read(ENT_CONTROLS);
+	u64 tmp;
+	int i;
+	u64 dr7_saved = vmcs_read(GUEST_DR7);
+
+	if (!(ctrl_exit_rev.clr & ENT_LOAD_DBGCTLS)) {
+		printf("\"IA32_DEBUGCTL\" VM-entry control not supported\n");
+		return;
+	}
+
+	vmx_set_test_stage(1);
+	test_set_guest(guest_state_test_main);
+
+#define	DEBUGCTL_RESERVED_BITS	0xFFFFFFFFFFFF203C
+
+	if (!(entry_ctl_saved & ENT_LOAD_DBGCTLS))
+		vmcs_write(ENT_CONTROLS, entry_ctl_saved | ENT_LOAD_DBGCTLS);
+
+	for (i = 2; i < 32; (i >= 16 ? i = i + 4 : i++)) {
+		if (!((1 << i) & DEBUGCTL_RESERVED_BITS))
+			continue;
+		tmp = debugctl_saved | (1 << i);
+		vmcs_write(GUEST_DEBUGCTL, tmp);
+		enter_guest_with_invalid_guest_state();
+		report_guest_state_test("ENT_LOAD_DBGCTLS enabled",
+				        VMX_FAIL_STATE | VMX_ENTRY_FAILURE,
+				        tmp, "GUEST_DEBUGCTL");
+	}
+
+	for (i = 32; i < 64; i = i + 4) {
+		tmp = dr7_saved | (1ull << i);
+		vmcs_write(GUEST_DR7, tmp);
+		enter_guest_with_invalid_guest_state();
+		report_guest_state_test("ENT_LOAD_DBGCTLS enabled",
+				        VMX_FAIL_STATE | VMX_ENTRY_FAILURE,
+				        tmp, "GUEST_DR7");
+	}
+
+	/*
+	 * Let the guest finish execution
+	 */
+	vmx_set_test_stage(2);
+	vmcs_write(GUEST_DEBUGCTL, debugctl_saved);
+	vmcs_write(ENT_CONTROLS, entry_ctl_saved);
+	vmcs_write(GUEST_DR7, dr7_saved);
+	enter_guest();
+}
+
 /*
  * Check that the virtual CPU checks the VMX Guest State Area as
  * documented in the Intel SDM.
@@ -7161,6 +7219,7 @@ static void test_load_guest_pat(void)
 static void vmx_guest_state_area_test(void)
 {
 	test_load_guest_pat();
+	test_debugctl();
 }
 
 static bool valid_vmcs_for_vmentry(void)
-- 
2.20.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