diff mbox

[nVMX,TEST,2/2] x86: Add test for checking NMI controls on vmentry of L2 guests

Message ID 71a46d1d-6794-4318-9512-9c6ac81380a8@default (mailing list archive)
State New, archived
Headers show

Commit Message

Liran Alon Dec. 23, 2017, 1:34 a.m. UTC
Reviewed-by: Liran Alon <liran.alon@oracle.com>

----- Original Message -----
From: krish.sadhukhan@oracle.com
To: kvm@vger.kernel.org
Cc: pbonzini@redhat.com, jmattson@google.com, rkrcmar@redhat.com
Sent: Saturday, December 23, 2017 2:26:45 AM (GMT+0200) Auto-Detected
Subject: [PATCH nVMX TEST 2/2] x86: Add test for checking NMI controls on vmentry of L2 guests

This test validates the following vmentry checks from Intel SDM 26.2.1.1:

 1. If the “NMI exiting” VM-execution control is 0,
    the “virtual NMIs” VM-execution control must be 0.

 2. If the “virtual NMIs” VM-execution control is 0,
    the “NMI-window exiting” VM-execution control must be 0.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
---
 x86/vmx_tests.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)
diff mbox

Patch

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index e8c97f2..1eb8af7 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3553,6 +3553,88 @@  static void test_tpr_threshold(void)
 }
 
 /*
+ * This test verifies the following two vmentry checks:
+ *
+ *  If the "NMI exiting" VM-execution control is 0, "Virtual NMIs"
+ *  VM-execution control must be 0.
+ *  [Intel SDM]
+ *
+ *  If the “virtual NMIs” VM-execution control is 0, the “NMI-window
+ *  exiting” VM-execution control must be 0.
+ *  [Intel SDM]
+ */
+static void test_nmi_ctrls(void)
+{
+	u32 pin_ctrls, cpu_ctrls0, test_pin_ctrls, test_cpu_ctrls0;
+
+	if (((ctrl_pin_rev.clr & (PIN_NMI | PIN_VIRT_NMI)) !=
+	    (PIN_NMI | PIN_VIRT_NMI)) ||
+	    ! (ctrl_cpu_rev[0].clr & CPU_NMI_WINDOW)) {
+		test_skip("NMI controls not supported !");
+		return;
+	}
+
+	/* Save the controls so that we can restore them after our tests */
+	pin_ctrls = vmcs_read(PIN_CONTROLS);
+	cpu_ctrls0 = vmcs_read(CPU_EXEC_CTRL0);
+
+	test_pin_ctrls = pin_ctrls & ~(PIN_NMI | PIN_VIRT_NMI);
+	test_cpu_ctrls0 = cpu_ctrls0 & ~CPU_NMI_WINDOW;
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls);
+	report_prefix_pushf("NMI-exiting disabled, virtual-NMIs disabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls | PIN_VIRT_NMI);
+	report_prefix_pushf("NMI-exiting disabled, virtual-NMIs enabled");
+	test_vmx_controls(false, false);
+	report_prefix_pop();
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls | (PIN_NMI | PIN_VIRT_NMI));
+	report_prefix_pushf("NMI-exiting enabled, virtual-NMIs enabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls | PIN_NMI);
+	report_prefix_pushf("NMI-exiting enabled, virtual-NMIs disabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls);
+	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0 | CPU_NMI_WINDOW);
+	report_prefix_pushf("Virtual-NMIs disabled, NMI-window-exiting "
+	    "enabled");
+	test_vmx_controls(false, false);
+	report_prefix_pop();
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls);
+	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0);
+	report_prefix_pushf("Virtual-NMIs disabled, NMI-window-exiting "
+	    "disabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls | (PIN_NMI | PIN_VIRT_NMI));
+	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0 | CPU_NMI_WINDOW);
+	report_prefix_pushf("Virtual-NMIs enabled, NMI-window-exiting "
+	    "enabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	vmcs_write(PIN_CONTROLS, test_pin_ctrls | (PIN_NMI | PIN_VIRT_NMI));
+	vmcs_write(CPU_EXEC_CTRL0, test_cpu_ctrls0);
+	report_prefix_pushf("Virtual-NMIs enabled, NMI-window-exiting "
+	    "disabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	/* Restore the controls to their original values */
+	vmcs_write(CPU_EXEC_CTRL0, cpu_ctrls0);
+	vmcs_write(PIN_CONTROLS, pin_ctrls);
+}
+
+/*
  * Check that the virtual CPU checks all of the VMX controls as
  * documented in the Intel SDM.
  */
@@ -3573,6 +3655,7 @@  static void vmx_controls_test(void)
 	test_msr_bitmap();
 	test_apic_virt_addr();
 	test_tpr_threshold();
+	test_nmi_ctrls();
 }
 
 static bool valid_vmcs_for_vmentry(void)