According to section "Checks on VMX Controls" in Intel SDM vol 3C, the following checks performed for the VM-exit MSR-store address if the the VM-exit MSR-store count field is non-zero: - The lower 4 bits of the VM-exit MSR-store address must be 0. The address should not set any bits beyond the processor’s physical-address width. - The address of the last byte in the VM-exit MSR-store area should not set any bits beyond the processor’s physical-address width. The address of this last byte is VM-exit MSR-store address + (MSR count * 16) - 1. (The arithmetic used for the computation uses more bits than the processor’s physical-address width.) If IA32_VMX_BASIC[48] is read as 1, neither address should set any bits in the range 63:32. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx> Reviewed-by: Mihai Carabas <mihai.carabas@xxxxxxxxxx> --- x86/vmx_tests.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 900dcf4..af856cf 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -4731,6 +4731,75 @@ static void test_pml(void) } /* + * The following checks are performed for the VM-exit MSR-store address if + * the VM-exit MSR-store count field is non-zero: + * + * - The lower 4 bits of the VM-exit MSR-store address must be 0. + * The address should not set any bits beyond the processor’s + * physical-address width. + * + * - The address of the last byte in the VM-exit MSR-store area + * should not set any bits beyond the processor’s physical-address + * width. The address of this last byte is VM-exit MSR-store address + * + (MSR count * 16) - 1. (The arithmetic used for the computation + * uses more bits than the processor’s physical-address width.) + * + * If IA32_VMX_BASIC[48] is read as 1, neither address should set any bits + * in the range 63:32. + * + * [Intel SDM] + */ +static void test_exit_msr_store(void) +{ + exit_msr_store = alloc_page(); + u64 tmp; + u32 exit_msr_st_cnt = 1; + int i; + bool ctrl = true; + u32 addr_len = 64; + + vmcs_write(EXI_MSR_ST_CNT, exit_msr_st_cnt); + + /* Check first 4 bits of VM-exit MSR-store address */ + for (i = 0; i < 4; i++) { + tmp = (u64)exit_msr_store | 1ull << i; + vmcs_write(EXIT_MSR_ST_ADDR, tmp); + report_prefix_pushf("VM-exit MSR-store addr [4:0] %lx", + tmp & 0xf); + if (i && ctrl == true) { + ctrl = false; + } + test_vmx_controls(false, false); + report_prefix_pop(); + } + + if (basic.val & (1ul << 48)) + addr_len = 32; + + test_vmcs_page_values("VM-exit-MSR-store address", + EXIT_MSR_ST_ADDR, false, false, 16, + 4, addr_len - 1); + + /* Check last byte of VM-exit MSR-store address */ + for (i = (addr_len == 64 ? cpuid_maxphyaddr() : addr_len); i < 64; i++) { + exit_msr_store = (struct vmx_msr_entry *) + (((u64)exit_msr_store + (exit_msr_st_cnt * 16) - 1) | + 1ul << i); + + vmcs_write(EXIT_MSR_ST_ADDR, (u64)exit_msr_store); + test_vmx_controls(false, false); + } +} + +/* + * Tests for VMX exit controls + */ +static void test_exit_ctls(void) +{ + test_exit_msr_store(); +} + +/* * Check that the virtual CPU checks all of the VMX controls as * documented in the Intel SDM. */ @@ -4756,6 +4825,7 @@ static void vmx_controls_test(void) test_invalid_event_injection(); test_vpid(); test_eptp(); + test_exit_ctls(); } static bool valid_vmcs_for_vmentry(void) -- 2.9.5