Message ID | 20180723224240.18360-2-krish.sadhukhan@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [kvm-unit-test] nVMX x86: "external-interrupt exiting" must be set if "virtual-interrupt delivery" is set | expand |
On Mon, Jul 23, 2018 at 3:42 PM, Krish Sadhukhan <krish.sadhukhan@oracle.com> wrote: > 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 "virtual-interrupt delivery" VM-execution control is 1, the > "external-interrupt exiting" VM-execution control must be 1. > > This unit-test validates the above vmentry check. > > Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com> > Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com> Reviewed-by: Jim Mattson <jmattson@google.com> > --- > x86/vmx_tests.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+) > > diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c > index e9fbc22..8821aed 100644 > --- a/x86/vmx_tests.c > +++ b/x86/vmx_tests.c > @@ -3690,11 +3690,57 @@ static void test_apic_virtual_ctls(void) > vmcs_write(CPU_EXEC_CTRL1, saved_secondary); > } > > +/* > + * If the "virtual-interrupt delivery" VM-execution control is 1, the > + * "external-interrupt exiting" VM-execution control must be 1. > + * [Intel SDM] > + */ > +static void test_virtual_intr_ctls(void) > +{ > + u32 saved_primary = vmcs_read(CPU_EXEC_CTRL0); > + u32 saved_secondary = vmcs_read(CPU_EXEC_CTRL1); > + u32 pin_saved = vmcs_read(PIN_CONTROLS); Perhaps saved_pin for consistency? > + u32 primary = saved_primary; > + u32 secondary = saved_secondary; > + u32 pin = pin_saved; > + > + if (!((ctrl_cpu_rev[1].clr & CPU_VINTD) && > + (ctrl_pin_rev.clr & PIN_EXTINT))) > + return; > + > + vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY | CPU_TPR_SHADOW); > + vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VINTD); > + vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT); > + report_prefix_pushf("Virtualize interrupt-delivery disabled; external-interrupt exiting disabled"); > + test_vmx_controls(true, false); > + report_prefix_pop(); > + > + vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD); > + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled"); > + test_vmx_controls(false, false); > + report_prefix_pop(); > + > + vmcs_write(PIN_CONTROLS, pin | PIN_EXTINT); > + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting enabled"); > + test_vmx_controls(true, false); > + report_prefix_pop(); > + > + vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT); > + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled"); > + test_vmx_controls(false, false); > + report_prefix_pop(); > + > + vmcs_write(CPU_EXEC_CTRL0, saved_primary); > + vmcs_write(CPU_EXEC_CTRL1, saved_secondary); > + vmcs_write(PIN_CONTROLS, pin_saved); > +} > + > static void test_apic_ctls(void) > { > test_apic_virt_addr(); > test_apic_access_addr(); > test_apic_virtual_ctls(); > + test_virtual_intr_ctls(); > } > > static void set_vtpr(unsigned vtpr) > -- > 2.9.5 >
On 08/08/2018 10:01 AM, Jim Mattson wrote: > On Mon, Jul 23, 2018 at 3:42 PM, Krish Sadhukhan > <krish.sadhukhan@oracle.com> wrote: >> 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 "virtual-interrupt delivery" VM-execution control is 1, the >> "external-interrupt exiting" VM-execution control must be 1. >> >> This unit-test validates the above vmentry check. >> >> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com> >> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com> > Reviewed-by: Jim Mattson <jmattson@google.com> >> --- >> x86/vmx_tests.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 46 insertions(+) >> >> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c >> index e9fbc22..8821aed 100644 >> --- a/x86/vmx_tests.c >> +++ b/x86/vmx_tests.c >> @@ -3690,11 +3690,57 @@ static void test_apic_virtual_ctls(void) >> vmcs_write(CPU_EXEC_CTRL1, saved_secondary); >> } >> >> +/* >> + * If the "virtual-interrupt delivery" VM-execution control is 1, the >> + * "external-interrupt exiting" VM-execution control must be 1. >> + * [Intel SDM] >> + */ >> +static void test_virtual_intr_ctls(void) >> +{ >> + u32 saved_primary = vmcs_read(CPU_EXEC_CTRL0); >> + u32 saved_secondary = vmcs_read(CPU_EXEC_CTRL1); >> + u32 pin_saved = vmcs_read(PIN_CONTROLS); > Perhaps saved_pin for consistency? Will fix it. Thanks, Krish >> + u32 primary = saved_primary; >> + u32 secondary = saved_secondary; >> + u32 pin = pin_saved; >> + >> + if (!((ctrl_cpu_rev[1].clr & CPU_VINTD) && >> + (ctrl_pin_rev.clr & PIN_EXTINT))) >> + return; >> + >> + vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY | CPU_TPR_SHADOW); >> + vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VINTD); >> + vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT); >> + report_prefix_pushf("Virtualize interrupt-delivery disabled; external-interrupt exiting disabled"); >> + test_vmx_controls(true, false); >> + report_prefix_pop(); >> + >> + vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD); >> + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled"); >> + test_vmx_controls(false, false); >> + report_prefix_pop(); >> + >> + vmcs_write(PIN_CONTROLS, pin | PIN_EXTINT); >> + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting enabled"); >> + test_vmx_controls(true, false); >> + report_prefix_pop(); >> + >> + vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT); >> + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled"); >> + test_vmx_controls(false, false); >> + report_prefix_pop(); >> + >> + vmcs_write(CPU_EXEC_CTRL0, saved_primary); >> + vmcs_write(CPU_EXEC_CTRL1, saved_secondary); >> + vmcs_write(PIN_CONTROLS, pin_saved); >> +} >> + >> static void test_apic_ctls(void) >> { >> test_apic_virt_addr(); >> test_apic_access_addr(); >> test_apic_virtual_ctls(); >> + test_virtual_intr_ctls(); >> } >> >> static void set_vtpr(unsigned vtpr) >> -- >> 2.9.5 >>
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index e9fbc22..8821aed 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -3690,11 +3690,57 @@ static void test_apic_virtual_ctls(void) vmcs_write(CPU_EXEC_CTRL1, saved_secondary); } +/* + * If the "virtual-interrupt delivery" VM-execution control is 1, the + * "external-interrupt exiting" VM-execution control must be 1. + * [Intel SDM] + */ +static void test_virtual_intr_ctls(void) +{ + u32 saved_primary = vmcs_read(CPU_EXEC_CTRL0); + u32 saved_secondary = vmcs_read(CPU_EXEC_CTRL1); + u32 pin_saved = vmcs_read(PIN_CONTROLS); + u32 primary = saved_primary; + u32 secondary = saved_secondary; + u32 pin = pin_saved; + + if (!((ctrl_cpu_rev[1].clr & CPU_VINTD) && + (ctrl_pin_rev.clr & PIN_EXTINT))) + return; + + vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY | CPU_TPR_SHADOW); + vmcs_write(CPU_EXEC_CTRL1, secondary & ~CPU_VINTD); + vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT); + report_prefix_pushf("Virtualize interrupt-delivery disabled; external-interrupt exiting disabled"); + test_vmx_controls(true, false); + report_prefix_pop(); + + vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD); + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled"); + test_vmx_controls(false, false); + report_prefix_pop(); + + vmcs_write(PIN_CONTROLS, pin | PIN_EXTINT); + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting enabled"); + test_vmx_controls(true, false); + report_prefix_pop(); + + vmcs_write(PIN_CONTROLS, pin & ~PIN_EXTINT); + report_prefix_pushf("Virtualize interrupt-delivery enabled; external-interrupt exiting disabled"); + test_vmx_controls(false, false); + report_prefix_pop(); + + vmcs_write(CPU_EXEC_CTRL0, saved_primary); + vmcs_write(CPU_EXEC_CTRL1, saved_secondary); + vmcs_write(PIN_CONTROLS, pin_saved); +} + static void test_apic_ctls(void) { test_apic_virt_addr(); test_apic_access_addr(); test_apic_virtual_ctls(); + test_virtual_intr_ctls(); } static void set_vtpr(unsigned vtpr)