Re: [kvm-unit-test 1/2] nVMX x86: APIC virtual controls must be unset if "Use TPR shadow" is unset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Krish,

I think this would be more succint as two loops: an outer loop that
tested "use TPR shadow" values and an inner loop that tested
combinations of the other three controls. But this looks fine to me as
it is.

Reviewed-by: Jim Mattson <jmattson@xxxxxxxxxx>

On Fri, Jun 29, 2018 at 12:07 PM, Krish Sadhukhan
<krish.sadhukhan@xxxxxxxxxx> 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 "use TPR shadow" VM-execution control is 0, the following
>     VM-execution controls must also be 0: "virtualize x2APIC mode",
>     "APIC-register virtualization" and "virtual-interrupt delivery".
>
> This unit-test validates the above vmentry check.
>
> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
> Reviewed-by: Karl Heubaum <karl.heubaum@xxxxxxxxxx>
> ---
>  x86/vmx_tests.c | 108
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 106 insertions(+), 2 deletions(-)
>
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index 38f10f4..64be48f 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -3580,6 +3580,111 @@ static void test_apic_access_addr(void)
>                                  "virtualize APIC-accesses", true, false);
>  }
>  +/*
> + * If the "use TPR shadow" VM-execution control is 0, the following
> + * VM-execution controls must also be 0:
> + *     - virtualize x2APIC mode
> + *     - APIC-register virtualization
> + *     - virtual-interrupt delivery
> + */
> +static void test_apic_virtual_ctls(void)
> +{
> +       u32 saved_primary = vmcs_read(CPU_EXEC_CTRL0);
> +       u32 saved_secondary = vmcs_read(CPU_EXEC_CTRL1);
> +       u32 primary = saved_primary;
> +       u32 secondary = saved_secondary;
> +       bool cpu_has_virt_x2apic = 0;
> +       bool cpu_has_apic_reg_virt = 0;
> +       bool cpu_has_vintd = 0;
> +
> +       if (!((ctrl_cpu_rev[0].clr & (CPU_SECONDARY | CPU_TPR_SHADOW)) ==
> +           (CPU_SECONDARY | CPU_TPR_SHADOW)))
> +               return;
> +
> +       if ((ctrl_cpu_rev[1].clr & CPU_VIRT_X2APIC) == CPU_VIRT_X2APIC)
> +               cpu_has_virt_x2apic = 1;
> +       if ((ctrl_cpu_rev[1].clr & CPU_APIC_REG_VIRT) == CPU_APIC_REG_VIRT)
> +               cpu_has_apic_reg_virt = 1;
> +       if ((ctrl_cpu_rev[1].clr & CPU_VINTD) == CPU_VINTD)
> +               cpu_has_vintd = 1;
> +
> +       primary |= CPU_SECONDARY;
> +       vmcs_write(CPU_EXEC_CTRL0, primary & ~CPU_TPR_SHADOW);
> +
> +       if (cpu_has_virt_x2apic) {
> +               secondary &= ~(CPU_APIC_REG_VIRT | CPU_VINTD);
> +               vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VIRT_X2APIC);
> +               report_prefix_pushf("Use TPR shadow disabled; virtualize
> x2APIC mode enabled");
> +               test_vmx_controls(false, false);
> +               report_prefix_pop();
> +
> +               if (cpu_has_apic_reg_virt) {
> +                       vmcs_write(CPU_EXEC_CTRL1, secondary |
> +                           CPU_APIC_REG_VIRT);
> +                       report_prefix_pushf("Use TPR shadow disabled;
> virtualize x2APIC mode enabled; APIC-register virtualization enabled");
> +                       test_vmx_controls(false, false);
> +                       report_prefix_pop();
> +               }
> +
> +               if (cpu_has_vintd) {
> +                       secondary &= ~CPU_APIC_REG_VIRT;
> +                       vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD);
> +                       report_prefix_pushf("Use TPR shadow disabled;
> virtualize x2APIC mode enabled; virtual-interrupt delivery enabled");
> +                       test_vmx_controls(false, false);
> +                       report_prefix_pop();
> +               }
> +       }
> +
> +       if (cpu_has_apic_reg_virt) {
> +               secondary &= ~(~CPU_VIRT_X2APIC | CPU_VINTD);
> +               vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_APIC_REG_VIRT);
> +               report_prefix_pushf("Use TPR shadow disabled; APIC-register
> virtualization enabled");
> +               test_vmx_controls(false, false);
> +               report_prefix_pop();
> +
> +               if (cpu_has_vintd) {
> +                       secondary &= ~CPU_VIRT_X2APIC;
> +                       vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD);
> +                       report_prefix_pushf("Use TPR shadow disabled;
> APIC-register virtualization enabled; virtual-interrupt delivery enabled");
> +                       test_vmx_controls(false, false);
> +                       report_prefix_pop();
> +               }
> +       }
> +
> +       if (cpu_has_vintd) {
> +               secondary &= ~(~CPU_VIRT_X2APIC | CPU_APIC_REG_VIRT);
> +               vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD);
> +               report_prefix_pushf("Use TPR shadow disabled;
> virtual-interrupt delivery enabled");
> +               test_vmx_controls(false, false);
> +               report_prefix_pop();
> +       }
> +
> +       if (cpu_has_virt_x2apic && cpu_has_apic_reg_virt &&
> +           cpu_has_vintd) {
> +
> +               vmcs_write(CPU_EXEC_CTRL1, secondary | (CPU_VIRT_X2APIC |
> +                   CPU_APIC_REG_VIRT | CPU_VINTD));
> +               report_prefix_pushf("Use TPR shadow disabled; virtualize
> x2APIC mode enabled; APIC-register virtualization enabled; virtual-interrupt
> delivery enabled");
> +               test_vmx_controls(false, false);
> +               report_prefix_pop();
> +
> +               vmcs_write(CPU_EXEC_CTRL0, primary | CPU_TPR_SHADOW);
> +               report_prefix_pushf("Use TPR shadow enabled; virtualize
> x2APIC mode enabled; APIC-register virtualization enabled; virtual-interrupt
> delivery enabled");
> +               test_vmx_controls(true, false);
> +               report_prefix_pop();
> +       }
> +
> +       vmcs_write(CPU_EXEC_CTRL0, saved_primary);
> +       vmcs_write(CPU_EXEC_CTRL1, saved_secondary);
> +}
> +
> +static void test_apic_ctls(void)
> +{
> +       test_apic_virt_addr();
> +       test_apic_access_addr();
> +       test_apic_virtual_ctls();
> +}
> +
>  static void set_vtpr(unsigned vtpr)
>  {
>         *(u32 *)phys_to_virt(vmcs_read(APIC_VIRT_ADDR) + APIC_TASKPRI) =
> vtpr;
> @@ -3846,8 +3951,7 @@ static void vmx_controls_test(void)
>         test_cr3_targets();
>         test_io_bitmaps();
>         test_msr_bitmap();
> -       test_apic_virt_addr();
> -       test_apic_access_addr();
> +       test_apic_ctls();
>         test_tpr_threshold();
>         test_nmi_ctrls();
>  }
> --
> 2.9.5
>



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux