KVM: VMX: Disable LBR virtualization if the CPU doesn't support LBR callstacks
authorSean Christopherson <seanjc@google.com>
Thu, 7 Mar 2024 01:13:44 +0000 (17:13 -0800)
committerSean Christopherson <seanjc@google.com>
Thu, 11 Apr 2024 19:58:48 +0000 (12:58 -0700)
Disable LBR virtualization if the CPU doesn't support callstacks, which
were introduced in HSW (see commit e9d7f7cd97c4 ("perf/x86/intel: Add
basic Haswell LBR call stack support"), as KVM unconditionally configures
the perf LBR event with PERF_SAMPLE_BRANCH_CALL_STACK, i.e. LBR
virtualization always fails on pre-HSW CPUs.

Simply disable LBR support on such CPUs, as it has never worked, i.e.
there is no risk of breaking an existing setup, and figuring out a way
to performantly context switch LBRs on old CPUs is not worth the effort.

Fixes: be635e34c284 ("KVM: vmx/pmu: Expose LBR_FMT in the MSR_IA32_PERF_CAPABILITIES")
Cc: Mingwei Zhang <mizhang@google.com>
Cc: Jim Mattson <jmattson@google.com>
Tested-by: Mingwei Zhang <mizhang@google.com>
Link: https://lore.kernel.org/r/20240307011344.835640-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/vmx/vmx.c

index aca41d3419f9083a8cb2327092ce4fa8d76b9af5..22411f4aff5303db5b27ee737ba1565f91585bd1 100644 (file)
@@ -7877,7 +7877,15 @@ static __init u64 vmx_get_perf_capabilities(void)
 
        if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
                x86_perf_get_lbr(&vmx_lbr_caps);
-               if (vmx_lbr_caps.nr)
+
+               /*
+                * KVM requires LBR callstack support, as the overhead due to
+                * context switching LBRs without said support is too high.
+                * See intel_pmu_create_guest_lbr_event() for more info.
+                */
+               if (!vmx_lbr_caps.has_callstack)
+                       memset(&vmx_lbr_caps, 0, sizeof(vmx_lbr_caps));
+               else if (vmx_lbr_caps.nr)
                        perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
        }