[tip: perf/core] perf/x86/intel: Fix intel_cap handling on hybrid PMUs
"tip-bot2 for Dapeng Mi" <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <178654388168.442315.17212883665190608802.tip-bot2@tip-bot2> |
The following commit has been merged into the perf/core branch of tip: Commit-ID: dd384d661f06e3725aad3a932a53e0ff81fb8805 Gitweb: https://git.kernel.org/tip/dd384d661f06e3725aad3a932a53e0ff81fb8805 Author: Dapeng Mi <[email protected]> AuthorDate: Fri, 17 Jul 2026 16:03:40 +08:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Mon, 10 Aug 2026 15:05:48 +02:00 perf/x86/intel: Fix intel_cap handling on hybrid PMUs intel_cap (IA32_PERF_CAPABILITIES) updates are currently tied to X86_FEATURE_ARCH_PERFMON_EXT, but these are independent feature paths. As a result, hybrid PMU capability state can be updated under the wrong condition. Also, intel_pmu_broken_perf_cap() is too narrow. Per RPL018, the missing PERF_METRICS_AVAILABLE bit affects both Raptor Lake and Meteor Lake parts, not only the currently covered subset. Move intel_cap updates out of the ARCH_PERFMON_EXT-gated path, extend intel_pmu_broken_perf_cap() coverage to both RPL and MTL families, and introduce intel_update_pmu_caps() to centralize PMU capability updates. Signed-off-by: Dapeng Mi <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Thomas Falcon <[email protected]> Reviewed-by: Zide Chen <[email protected]> Link: https://patch.msgid.link/[email protected] --- arch/x86/events/intel/core.c | 40 +++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index c418176..f6ee181 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -6147,8 +6147,14 @@ static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs); static inline bool intel_pmu_broken_perf_cap(void) { - /* The Perf Metric (Bit 15) is always cleared */ - if (boot_cpu_data.x86_vfm == INTEL_METEORLAKE || + /* + * The Perf Metric (Bit 15) is always cleared on P-core of + * RPL and MTL. Details can be found in RPL018 erratum. + */ + if (boot_cpu_data.x86_vfm == INTEL_RAPTORLAKE || + boot_cpu_data.x86_vfm == INTEL_RAPTORLAKE_P || + boot_cpu_data.x86_vfm == INTEL_RAPTORLAKE_S || + boot_cpu_data.x86_vfm == INTEL_METEORLAKE || boot_cpu_data.x86_vfm == INTEL_METEORLAKE_L) return true; @@ -6183,7 +6189,7 @@ static inline void __intel_update_large_pebs_flags(struct pmu *pmu) #define counter_mask(_gp, _fixed) ((_gp) | ((u64)(_fixed) << INTEL_PMC_IDX_FIXED)) -static void update_pmu_cap(struct pmu *pmu) +static void update_pmu_cap_from_perfmonext(struct pmu *pmu) { unsigned int eax, ebx, ecx, edx; union cpuid35_eax eax_0; @@ -6241,10 +6247,24 @@ static void update_pmu_cap(struct pmu *pmu) WARN_ON(x86_pmu.arch_pebs == 1); x86_pmu.arch_pebs = 0; } +} + +static void intel_update_pmu_caps(struct pmu *pmu) +{ + if (this_cpu_has(X86_FEATURE_ARCH_PERFMON_EXT)) + update_pmu_cap_from_perfmonext(pmu); - if (!intel_pmu_broken_perf_cap()) { - /* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */ - rdmsrq(MSR_IA32_PERF_CAPABILITIES, hybrid(pmu, intel_cap).capabilities); + if (is_hybrid() && this_cpu_has(X86_FEATURE_PDCM)) { + rdmsrq(MSR_IA32_PERF_CAPABILITIES, + hybrid(pmu, intel_cap).capabilities); + + /* + * Restore perf_metrics on platforms with broken + * perf_capablities. + */ + if (intel_pmu_broken_perf_cap() && + hybrid_pmu(pmu)->pmu_type == hybrid_big) + hybrid(pmu, intel_cap).perf_metrics = 1; } } @@ -6329,9 +6349,7 @@ static bool init_hybrid_pmu(int cpu) if (!cpumask_empty(&pmu->supported_cpus)) goto end; - if (this_cpu_has(X86_FEATURE_ARCH_PERFMON_EXT)) - update_pmu_cap(&pmu->pmu); - + intel_update_pmu_caps(&pmu->pmu); intel_pmu_check_hybrid_pmus(pmu); if (!check_hw_exists(pmu->cntr_mask, pmu->fixed_cntr_mask)) { @@ -8828,8 +8846,8 @@ __init int intel_pmu_init(void) * from the leaf 0xa. The core specific update will be done later * when a new type is online. */ - if (!is_hybrid() && boot_cpu_has(X86_FEATURE_ARCH_PERFMON_EXT)) - update_pmu_cap(NULL); + if (!is_hybrid()) + intel_update_pmu_caps(NULL); if (x86_pmu.arch_pebs) { static_call_update(intel_pmu_disable_event_ext,