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 "VMCS shadowing" VM-execution control is 1, the VMREAD-bitmap and VMWRITE-bitmap addresses must each satisfy the following checks: - Bits 11:0 of the address must be 0. - The address must not set any bits beyond the processor’s physical-address width. We just need to call test_vmcs_page_reference() here as the tests are done by test_vmcs_page_values() and test_vmcs_page_addr() respectively. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- x86/vmx_tests.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index b105b23..57ee344 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -4721,6 +4721,55 @@ static void test_pml(void) vmcs_write(CPU_EXEC_CTRL1, secondary_saved); } +enum vmcs_access { + ACCESS_VMREAD, + ACCESS_VMWRITE, + ACCESS_NONE, +}; + +/* + * If the "VMCS shadowing" VM-execution control is 1, the VMREAD-bitmap + * and VMWRITE-bitmap addresses must each satisfy the following checks: + * + * - Bits 11:0 of the address must be 0. + * - The address must not set any bits beyond the processor’s + * physical-address width. + * + * [Intel SDM] + */ +static void test_vmread_vmwrite_bitmap(void) +{ + u8 *bitmap[2]; + u32 primary_saved = vmcs_read(CPU_EXEC_CTRL0); + u32 secondary_saved = vmcs_read(CPU_EXEC_CTRL1); + u32 primary = primary_saved; + u32 secondary = secondary_saved; + + if (!((ctrl_cpu_rev[0].clr & CPU_SECONDARY) && + (ctrl_cpu_rev[1].clr & CPU_SHADOW_VMCS))) { + test_skip("\"Secondary execution\" control and/or \"VMCS shadowing\" control is not supported !"); + return; + } + + primary |= CPU_SECONDARY; + vmcs_write(CPU_EXEC_CTRL0, primary); + secondary |= CPU_SHADOW_VMCS; + vmcs_write(CPU_EXEC_CTRL1, secondary); + + bitmap[ACCESS_VMREAD] = alloc_page(); + bitmap[ACCESS_VMWRITE] = alloc_page(); + vmcs_write(VMREAD_BITMAP, virt_to_phys(bitmap[ACCESS_VMREAD])); + vmcs_write(VMWRITE_BITMAP, virt_to_phys(bitmap[ACCESS_VMWRITE])); + + test_vmcs_page_reference(CPU_SHADOW_VMCS, VMREAD_BITMAP, + "VMREAD bitmap", "VMCS shadowing", false, false); + test_vmcs_page_reference(CPU_SHADOW_VMCS, VMWRITE_BITMAP, + "VMWRITE bitmap", "VMCS shadowing", false, false); + + vmcs_write(CPU_EXEC_CTRL0, primary_saved); + vmcs_write(CPU_EXEC_CTRL1, secondary_saved); +} + /* * Check that the virtual CPU checks all of the VMX controls as * documented in the Intel SDM. @@ -4747,6 +4796,7 @@ static void vmx_controls_test(void) test_invalid_event_injection(); test_vpid(); test_eptp(); + test_vmread_vmwrite_bitmap(); } static bool valid_vmcs_for_vmentry(void) @@ -5468,12 +5518,6 @@ static void vmx_apic_passthrough_thread_test(void) vmx_apic_passthrough(true); } -enum vmcs_access { - ACCESS_VMREAD, - ACCESS_VMWRITE, - ACCESS_NONE, -}; - struct vmcs_shadow_test_common { enum vmcs_access op; enum Reason reason; -- 2.9.5