lkml.org 
[lkml]   [2022]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectRe: [PATCH v3 21/25] KVM: VMX: Move LOAD_IA32_PERF_GLOBAL_CTRL errata handling out of setup_vmcs_config()
    From
    Date
    On Fri, 2022-07-08 at 16:42 +0200, Vitaly Kuznetsov wrote:
    > As a preparation to reusing the result of setup_vmcs_config() for setting
    > up nested VMX control MSRs, move LOAD_IA32_PERF_GLOBAL_CTRL errata handling
    > to vmx_vmexit_ctrl()/vmx_vmentry_ctrl() and print the warning from
    > hardware_setup(). While it seems reasonable to not expose
    > LOAD_IA32_PERF_GLOBAL_CTRL controls to L1 hypervisor on buggy CPUs,
    > such change would inevitably break live migration from older KVMs
    > where the controls are exposed. Keep the status quo for know, L1 hypervisor
    > itself is supposed to take care of the errata.
    >
    > Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
    > ---
    >  arch/x86/kvm/vmx/vmx.c | 62 ++++++++++++++++++++++++++----------------
    >  1 file changed, 38 insertions(+), 24 deletions(-)
    >
    > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
    > index 2dff5b94c535..e462e5b9c0a1 100644
    > --- a/arch/x86/kvm/vmx/vmx.c
    > +++ b/arch/x86/kvm/vmx/vmx.c
    > @@ -2416,6 +2416,31 @@ static bool cpu_has_sgx(void)
    >         return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0));
    >  }
    >  
    > +/*
    > + * Some cpus support VM_{ENTRY,EXIT}_IA32_PERF_GLOBAL_CTRL but they
    > + * can't be used due to errata where VM Exit may incorrectly clear
    > + * IA32_PERF_GLOBAL_CTRL[34:32]. Work around the errata by using the
    > + * MSR load mechanism to switch IA32_PERF_GLOBAL_CTRL.
    > + */
    > +static bool cpu_has_perf_global_ctrl_bug(void)
    > +{
    > +       if (boot_cpu_data.x86 == 0x6) {
    > +               switch (boot_cpu_data.x86_model) {
    > +               case INTEL_FAM6_NEHALEM_EP:     /* AAK155 */
    > +               case INTEL_FAM6_NEHALEM:        /* AAP115 */
    > +               case INTEL_FAM6_WESTMERE:       /* AAT100 */
    > +               case INTEL_FAM6_WESTMERE_EP:    /* BC86,AAY89,BD102 */
    > +               case INTEL_FAM6_NEHALEM_EX:     /* BA97 */
    > +                       return true;
    > +               default:
    > +                       break;
    > +               }
    > +       }
    > +
    > +       return false;
    > +}
    > +
    > +
    >  static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
    >                                       u32 msr, u32 *result)
    Nitpick: Indention is incorrect
    >  {
    > @@ -2572,30 +2597,6 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
    >                 _vmexit_control &= ~x_ctrl;
    >         }
    >  
    > -       /*
    > -        * Some cpus support VM_{ENTRY,EXIT}_IA32_PERF_GLOBAL_CTRL but they
    > -        * can't be used due to an errata where VM Exit may incorrectly clear
    > -        * IA32_PERF_GLOBAL_CTRL[34:32].  Workaround the errata by using the
    > -        * MSR load mechanism to switch IA32_PERF_GLOBAL_CTRL.
    > -        */
    > -       if (boot_cpu_data.x86 == 0x6) {
    > -               switch (boot_cpu_data.x86_model) {
    > -               case INTEL_FAM6_NEHALEM_EP:     /* AAK155 */
    > -               case INTEL_FAM6_NEHALEM:        /* AAP115 */
    > -               case INTEL_FAM6_WESTMERE:       /* AAT100 */
    > -               case INTEL_FAM6_WESTMERE_EP:    /* BC86,AAY89,BD102 */
    > -               case INTEL_FAM6_NEHALEM_EX:     /* BA97 */
    > -                       _vmentry_control &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
    > -                       _vmexit_control &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
    > -                       pr_warn_once("kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
    > -                                       "does not work properly. Using workaround\n");
    > -                       break;
    > -               default:
    > -                       break;
    > -               }
    > -       }
    > -
    > -
    >         rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high);
    >  
    >         /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
    > @@ -4184,6 +4185,10 @@ static u32 vmx_vmentry_ctrl(void)
    >                           VM_ENTRY_LOAD_IA32_EFER |
    >                           VM_ENTRY_IA32E_MODE);
    >  
    > +
    > +       if (cpu_has_perf_global_ctrl_bug())
    > +               vmentry_ctrl &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
    > +
    >         return vmentry_ctrl;
    >  }
    >  
    > @@ -4198,6 +4203,10 @@ static u32 vmx_vmexit_ctrl(void)
    >         if (vmx_pt_mode_is_system())
    >                 vmexit_ctrl &= ~(VM_EXIT_PT_CONCEAL_PIP |
    >                                  VM_EXIT_CLEAR_IA32_RTIT_CTL);
    > +
    > +       if (cpu_has_perf_global_ctrl_bug())
    > +               vmexit_ctrl &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
    > +
    >         /* Loading of EFER and PERF_GLOBAL_CTRL are toggled dynamically */
    >         return vmexit_ctrl &
    >                 ~(VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | VM_EXIT_LOAD_IA32_EFER);
    > @@ -8113,6 +8122,11 @@ static __init int hardware_setup(void)
    >         if (setup_vmcs_config(&vmcs_config, &vmx_capability) < 0)
    >                 return -EIO;
    >  
    > +       if (cpu_has_perf_global_ctrl_bug()) {
    > +               pr_warn_once("kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
    > +                            "does not work properly. Using workaround\n");
    > +       }
    > +
    >         if (boot_cpu_has(X86_FEATURE_NX))
    >                 kvm_enable_efer_bits(EFER_NX);
    >  

    Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>

    Best regards,
    Maxim Levitsky

    \
     
     \ /
      Last update: 2022-07-12 14:00    [W:4.639 / U:0.192 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site