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

Message ID 20190829205635.20189-5-krish.sadhukhan@oracle.com
State New
Headers show
Series
  • KVM: nVMX: Check GUEST_DEBUGCTL and GUEST_DR7 on vmentry of nested guests
Related show

Commit Message

Krish Sadhukhan Aug. 29, 2019, 8:56 p.m. UTC
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@oracle.com>
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
---
 x86/vmx_tests.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

Comments

Jim Mattson Aug. 29, 2019, 11:17 p.m. UTC | #1
On Thu, Aug 29, 2019 at 2:30 PM Krish Sadhukhan
<krish.sadhukhan@oracle.com> wrote:
>
> 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@oracle.com>
> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
> ---
> ...
> +#define        DEBUGCTL_RESERVED_BITS  0xFFFFFFFFFFFF203C

For the virtual CPU implemented by kvm today, only bits 0 and 1 are allowed.
Nadav Amit Aug. 30, 2019, 1:12 a.m. UTC | #2
> On Aug 29, 2019, at 4:17 PM, Jim Mattson <jmattson@google.com> wrote:
> 
> On Thu, Aug 29, 2019 at 2:30 PM Krish Sadhukhan
> <krish.sadhukhan@oracle.com> wrote:
>> 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@oracle.com>
>> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
>> ---
>> ...
>> +#define        DEBUGCTL_RESERVED_BITS  0xFFFFFFFFFFFF203C
> 
> For the virtual CPU implemented by kvm today, only bits 0 and 1 are allowed.

Please build the tests so they would pass on bare-metal.

Patch
diff mbox series

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)