]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
perf/x86/intel: Ensure LBRs are disabled when a CPU is starting
authorSean Christopherson <seanjc@google.com>
Fri, 31 Jan 2025 01:07:21 +0000 (17:07 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Mar 2025 11:47:16 +0000 (12:47 +0100)
commit c631a2de7ae48d50434bdc205d901423f8577c65 upstream.

Explicitly clear DEBUGCTL.LBR when a CPU is starting, prior to purging the
LBR MSRs themselves, as at least one system has been found to transfer
control to the kernel with LBRs enabled (it's unclear whether it's a BIOS
flaw or a CPU goof).  Because the kernel preserves the original DEBUGCTL,
even when toggling LBRs, leaving DEBUGCTL.LBR as is results in running
with LBRs enabled at all times.

Closes: https://lore.kernel.org/all/c9d8269bff69f6359731d758e3b1135dedd7cc61.camel@redhat.com
Reported-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20250131010721.470503-1-seanjc@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/events/intel/core.c
arch/x86/include/asm/msr-index.h

index 990d5543e3bf22ccd856d5605c2b6516b06a55d5..fb2e81fa62c45647fa4201743ce577d5bcc631c3 100644 (file)
@@ -4078,8 +4078,11 @@ static void intel_pmu_cpu_starting(int cpu)
 
        init_debug_store_on_cpu(cpu);
        /*
-        * Deal with CPUs that don't clear their LBRs on power-up.
+        * Deal with CPUs that don't clear their LBRs on power-up, and that may
+        * even boot with LBRs enabled.
         */
+       if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr)
+               msr_clear_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR_BIT);
        intel_pmu_lbr_reset();
 
        cpuc->lbr_sel = NULL;
index 52a6d43ed2f9478d460574ba9a7678a9dd70d594..7fd03f4ff9ed29d6e8deee29931ff0453142b902 100644 (file)
 #define MSR_IA32_PASID_VALID           BIT_ULL(31)
 
 /* DEBUGCTLMSR bits (others vary by model): */
-#define DEBUGCTLMSR_LBR                        (1UL <<  0) /* last branch recording */
+#define DEBUGCTLMSR_LBR_BIT            0            /* last branch recording */
+#define DEBUGCTLMSR_LBR                        (1UL <<  DEBUGCTLMSR_LBR_BIT)
 #define DEBUGCTLMSR_BTF_SHIFT          1
 #define DEBUGCTLMSR_BTF                        (1UL <<  1) /* single-step on branches */
 #define DEBUGCTLMSR_TR                 (1UL <<  6)