According to section "Checks on Guest Control Registers, Debug Registers, and MSRs" in Intel SDM vol 3C, the following checks are performed on vmentry of nested guests: If the "load IA32_BNDCFGS" VM-entry control is 1, the following checks are performed on the field for the IA32_BNDCFGS MSR: — Bits reserved in the IA32_BNDCFGS MSR must be 0. — The linear address in bits 63:12 must be canonical. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx> --- x86/vmx_tests.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index a7abd63..5ea15d0 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -7681,6 +7681,58 @@ static void test_load_guest_pat(void) test_pat(GUEST_PAT, "GUEST_PAT", ENT_CONTROLS, ENT_LOAD_PAT); } +#define MSR_IA32_BNDCFGS_RSVD_MASK 0x00000ffc + +/* + * If the “load IA32_BNDCFGS” VM-entry control is 1, the following + * checks are performed on the field for the IA32_BNDCFGS MSR: + * + * — Bits reserved in the IA32_BNDCFGS MSR must be 0. + * — The linear address in bits 63:12 must be canonical. + * + * [Intel SDM] + */ +static void test_load_guest_bndcfgs(void) +{ + u64 bndcfgs_saved = vmcs_read(GUEST_BNDCFGS); + u64 bndcfgs; + + if (!(ctrl_enter_rev.clr & ENT_LOAD_BNDCFGS)) { + printf("\"Load-IA32-BNDCFGS\" entry control not supported\n"); + return; + } + + vmcs_clear_bits(ENT_CONTROLS, ENT_LOAD_BNDCFGS); + + vmcs_write(GUEST_BNDCFGS, NONCANONICAL); + enter_guest(); + report_guest_state_test("ENT_LOAD_BNDCFGS disabled", + VMX_VMCALL, NONCANONICAL, "GUEST_BNDCFGS"); + + bndcfgs = bndcfgs_saved | MSR_IA32_BNDCFGS_RSVD_MASK; + vmcs_write(GUEST_BNDCFGS, bndcfgs); + enter_guest(); + report_guest_state_test("ENT_LOAD_BNDCFGS disabled", + VMX_VMCALL, bndcfgs, "GUEST_BNDCFGS"); + + vmcs_set_bits(ENT_CONTROLS, ENT_LOAD_BNDCFGS); + + vmcs_write(GUEST_BNDCFGS, NONCANONICAL); + enter_guest_with_invalid_guest_state(); + report_guest_state_test("ENT_LOAD_BNDCFGS enabled", + VMX_FAIL_STATE | VMX_ENTRY_FAILURE, + NONCANONICAL, "GUEST_BNDCFGS"); + + bndcfgs = bndcfgs_saved | MSR_IA32_BNDCFGS_RSVD_MASK; + vmcs_write(GUEST_BNDCFGS, bndcfgs); + enter_guest_with_invalid_guest_state(); + report_guest_state_test("ENT_LOAD_BNDCFGS enabled", + VMX_FAIL_STATE | VMX_ENTRY_FAILURE, bndcfgs, + "GUEST_BNDCFGS"); + + vmcs_write(GUEST_BNDCFGS, bndcfgs_saved); +} + /* * Check that the virtual CPU checks the VMX Guest State Area as * documented in the Intel SDM. @@ -7701,6 +7753,7 @@ static void vmx_guest_state_area_test(void) test_load_guest_pat(); test_guest_efer(); test_load_guest_perf_global_ctrl(); + test_load_guest_bndcfgs(); /* * Let the guest finish execution -- 1.8.3.1