@@ -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);
}