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 "virtualize x2APIC mode" VM-execution control is 1, the
"virtualize APIC accesses" VM-execution control must be 0.
This unit-test validates the above vmentry check.
Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
Reviewed-by: Jim Mattson <jmattson@xxxxxxxxxx>
Reviewed-by: Karl Heubaum <karl.heubaum@xxxxxxxxxx>
---
x86/vmx_tests.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 64be48f..e549362 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3586,6 +3586,11 @@ static void test_apic_access_addr(void)
* - virtualize x2APIC mode
* - APIC-register virtualization
* - virtual-interrupt delivery
+ * [Intel SDM]
+ *
+ * 2. If the "virtualize x2APIC mode" VM-execution control is 1, the
+ * "virtualize APIC accesses" VM-execution control must be 0.
+ * [Intel SDM]
*/
static void test_apic_virtual_ctls(void)
{
@@ -3597,6 +3602,9 @@ static void test_apic_virtual_ctls(void)
bool cpu_has_apic_reg_virt = 0;
bool cpu_has_vintd = 0;
+ /*
+ * First test
+ */
if (!((ctrl_cpu_rev[0].clr & (CPU_SECONDARY | CPU_TPR_SHADOW)) ==
(CPU_SECONDARY | CPU_TPR_SHADOW)))
return;
@@ -3674,6 +3682,38 @@ static void test_apic_virtual_ctls(void)
report_prefix_pop();
}
+ /*
+ * Second test
+ */
+ u32 apic_virt_ctls = (CPU_VIRT_X2APIC | CPU_VIRT_APIC_ACCESSES);
+
+ primary = saved_primary;
+ secondary = saved_secondary;
+ if (!((ctrl_cpu_rev[1].clr & apic_virt_ctls) == apic_virt_ctls))
+ return;
+
+ vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY);
+ secondary &= ~CPU_VIRT_APIC_ACCESSES;
+ vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VIRT_X2APIC);
+ report_prefix_pushf("Virtualize x2APIC mode disabled; virtualize APIC access disabled");
+ test_vmx_controls(true, false);
+ report_prefix_pop();
+
+ vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VIRT_APIC_ACCESSES);
+ report_prefix_pushf("Virtualize x2APIC mode disabled; virtualize APIC access enabled");
+ test_vmx_controls(true, false);
+ report_prefix_pop();
+
+ vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VIRT_X2APIC);
+ report_prefix_pushf("Virtualize x2APIC mode enabled; virtualize APIC access enabled");
+ test_vmx_controls(false, false);
+ report_prefix_pop();
+
+ vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VIRT_APIC_ACCESSES);
+ report_prefix_pushf("Virtualize x2APIC mode enabled; virtualize APIC access disabled");
+ test_vmx_controls(true, false);
+ report_prefix_pop();
+
vmcs_write(CPU_EXEC_CTRL0, saved_primary);
vmcs_write(CPU_EXEC_CTRL1, saved_secondary);
}
--
2.9.5