This test checks that a nested VM-entry fails if reserved bits in the primary processor-based VM-execution controls are not set properly (according to either the IA32_VMX_PROCBASED_CTLS MSR or the IA32_VMX_TRUE_PROCBASED_CTLS MSR, as appropriate). It also checks that a nested VM-entry fails if the "activate secondary controls" VM-execution control is set and a reserved bit is set in the secondary processor-based VM-execution controls (according to the IA32_VMX_PROCBASED_CTLS2 MSR). Signed-off-by: Jim Mattson <jmattson@xxxxxxxxxx> --- x86/vmx_tests.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 9c4bcc9..8853875 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -3253,6 +3253,65 @@ static void test_pin_based_ctls(void) ctrl_pin_rev, PIN_CONTROLS, bit); } +/* + * Reserved bits in the primary processor-based VM-execution controls + * must be set properly. Software may consult the VMX capability MSRs + * to determine the proper settings. + * [Intel SDM] + */ +static void test_primary_processor_based_ctls(void) +{ + unsigned bit; + + printf("\n%s: %lx\n", basic.ctrl ? "MSR_IA32_VMX_TRUE_PROC" : + "MSR_IA32_VMX_PROCBASED_CTLS", ctrl_cpu_rev[0].val); + for (bit = 0; bit < 32; bit++) + test_rsvd_ctl_bit("primary processor-based controls", + ctrl_cpu_rev[0], CPU_EXEC_CTRL0, bit); +} + +/* + * If the "activate secondary controls" primary processor-based + * VM-execution control is 1, reserved bits in the secondary + * processor-based VM-execution controls must be cleared. Software may + * consult the VMX capability MSRs to determine which bits are + * reserved. + * If the "activate secondary controls" primary processor-based + * VM-execution control is 0 (or if the processor does not support the + * 1-setting of that control), no checks are performed on the + * secondary processor-based VM-execution controls. + * [Intel SDM] + */ +static void test_secondary_processor_based_ctls(void) +{ + u32 primary; + u32 secondary; + unsigned bit; + + if (!(ctrl_cpu_rev[0].clr & CPU_SECONDARY)) + return; + + primary = vmcs_read(CPU_EXEC_CTRL0); + secondary = vmcs_read(CPU_EXEC_CTRL1); + + vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY); + printf("\nMSR_IA32_VMX_PROCBASED_CTLS2: %lx\n", ctrl_cpu_rev[1].val); + for (bit = 0; bit < 32; bit++) + test_rsvd_ctl_bit("secondary processor-based controls", + ctrl_cpu_rev[1], CPU_EXEC_CTRL1, bit); + + /* + * When the "activate secondary controls" VM-execution control + * is clear, there are no checks on the secondary controls. + */ + vmcs_write(CPU_EXEC_CTRL0, primary & ~CPU_SECONDARY); + vmcs_write(CPU_EXEC_CTRL1, ~0); + report("Secondary processor-based controls ignored", + vmlaunch_succeeds()); + vmcs_write(CPU_EXEC_CTRL1, secondary); + vmcs_write(CPU_EXEC_CTRL0, primary); +} + /* * Test a particular address setting for a physical page reference in * the VMCS. @@ -3357,6 +3416,8 @@ static void vmx_controls_test(void) vmcs_write(GUEST_RFLAGS, 0); test_pin_based_ctls(); + test_primary_processor_based_ctls(); + test_secondary_processor_based_ctls(); test_io_bitmaps(); test_msr_bitmap(); } -- 2.14.1.342.g6490525c54-goog