...to verify KVM performs the appropriate consistency checks for loading IA32_PERF_GLOBAL_CTRL as part of running a nested guest. According to section "Checks on Host Control Registers and MSRs" in Intel SDM vol 3C, the following checks are performed on vmentry of nested guests: If the "load IA32_PERF_GLOBAL_CTRL" VM-exit control is 1, bits reserved in the IA32_PERF_GLOBAL_CTRL MSR must be 0 in the field for that register. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx> Reviewed-by: Karl Heubaum <karl.heubaum@xxxxxxxxxx> --- x86/vmx_tests.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 66a87f6..85fa8d5 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -4995,6 +4995,63 @@ static void test_sysenter_field(u32 field, const char *name) vmcs_write(field, addr_saved); } +#define PERF_GLOBAL_CTRL_VALID_BITS 0x0000000700000003 + +static void test_perf_global_ctl(u32 field, const char * field_name, + u32 ctrl_field, u64 ctrl_bit) +{ + u32 ctrl_saved = vmcs_read(ctrl_field); + u64 perf_global_saved = vmcs_read(field); + u64 i, val; + + vmcs_write(ctrl_field, ctrl_saved & ~ctrl_bit); + for (i = 0; i < 64; i++) { + val = 1ull << i; + vmcs_write(field, val); + report_prefix_pushf("\"load IA32_PERF_GLOBAL_CTRL\" " + "VM-exit control is off, HOST_PERF_GLOBAL_CTRL %lx", val); + test_vmx_vmlaunch(0, false); + report_prefix_pop(); + } + + vmcs_write(ctrl_field, ctrl_saved | ctrl_bit); + for (i = 0; i < 64; i++) { + val = 1ull << i; + vmcs_write(field, val); + report_prefix_pushf("\"load IA32_PERF_GLOBAL_CTRL\" " + "VM-exit control is on, HOST_PERF_GLOBAL_CTRL %lx", val); + if (PERF_GLOBAL_CTRL_VALID_BITS & (1ull << i)) { + test_vmx_vmlaunch(0, false); + } else { + test_vmx_vmlaunch(VMXERR_ENTRY_INVALID_HOST_STATE_FIELD, + false); + } + report_prefix_pop(); + } + + vmcs_write(ctrl_field, ctrl_saved); + vmcs_write(field, perf_global_saved); +} + +/* + * If the "load IA32_PERF_GLOBAL_CTRL" VM-exit control is 1, bits reserved + * in the IA32_PERF_GLOBAL_CTRL MSR must be 0 in the field for that + * register. + * + * [Intel SDM] + */ +static void test_host_perf_global_ctl(void) +{ + if (!(ctrl_exit_rev.clr & EXI_LOAD_PERF)) { + printf("\"load IA32_PERF_GLOBAL_CTRL\" VM-exit control not " + "supported\n"); + return; + } + + test_perf_global_ctl(HOST_PERF_GLOBAL_CTRL, "HOST_PERF_GLOBAL_CTRL", + EXI_CONTROLS, EXI_LOAD_PERF); +} + /* * Check that the virtual CPU checks the VMX Host State Area as * documented in the Intel SDM. @@ -5010,6 +5067,8 @@ static void vmx_host_state_area_test(void) test_sysenter_field(HOST_SYSENTER_ESP, "HOST_SYSENTER_ESP"); test_sysenter_field(HOST_SYSENTER_EIP, "HOST_SYSENTER_EIP"); + + test_host_perf_global_ctl(); } static bool valid_vmcs_for_vmentry(void) -- 2.17.2