From: Dapeng Mi <dapeng1.mi@linux.intel.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
Zide Chen <zide.chen@intel.com>,
Falcon Thomas <thomas.falcon@intel.com>,
Dapeng Mi <dapeng1.mi@intel.com>,
Xudong Hao <xudong.hao@intel.com>,
Dapeng Mi <dapeng1.mi@linux.intel.com>
Subject: [Patch v2 5/7] perf/x86: Remove stale fixed counter helper and fix hybrid PMU access
Date: Mon, 13 Jul 2026 16:27:32 +0800 [thread overview]
Message-ID: <20260713082734.3162099-6-dapeng1.mi@linux.intel.com> (raw)
In-Reply-To: <20260713082734.3162099-1-dapeng1.mi@linux.intel.com>
On hybrid systems, init_hw_perf_events() can call check_hw_exists() with
the global PMU pointer after perf_is_hybrid is set. In that case,
fixed_counter_disabled() uses hybrid() on a non-hybrid PMU object, so the
intel_ctrl access is taken from the wrong layout and can read out of
bounds.
fixed_counter_disabled() was added in commit 32451614da2a
("perf/x86/intel: Support CPUID 10.ECX to disable fixed counters"), when
fixed counters were tracked via num_fixed_counters. Today fixed counters
are represented by fixed_cntr_mask, so this helper is obsolete.
Remove fixed_counter_disabled() and its callers, and rely directly on the
fixed-counter bitmask. With the helper gone, check_hw_exists() no longer
needs a PMU argument, so drop that parameter as well. This removes the
invalid hybrid access and closes the out-of-bounds read risk.
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/core.c | 8 ++------
arch/x86/events/intel/core.c | 4 +---
arch/x86/events/perf_event.h | 9 +--------
3 files changed, 4 insertions(+), 17 deletions(-)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index a02f303a9151..143a6e735d9e 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -265,7 +265,7 @@ static void release_pmc_hardware(void) {}
#endif
-bool check_hw_exists(struct pmu *pmu, unsigned long *cntr_mask,
+bool check_hw_exists(unsigned long *cntr_mask,
unsigned long *fixed_cntr_mask)
{
u64 val, val_fail = -1, val_new= ~0;
@@ -297,8 +297,6 @@ bool check_hw_exists(struct pmu *pmu, unsigned long *cntr_mask,
if (ret)
goto msr_fail;
for_each_set_bit(i, fixed_cntr_mask, X86_PMC_IDX_MAX) {
- if (fixed_counter_disabled(i, pmu))
- continue;
if (val & (0x03ULL << i*4)) {
bios_fail = 1;
val_fail = val;
@@ -1618,8 +1616,6 @@ void perf_event_print_debug(void)
cpu, idx, prev_left);
}
for_each_set_bit(idx, fixed_cntr_mask, X86_PMC_IDX_MAX) {
- if (fixed_counter_disabled(idx, cpuc->pmu))
- continue;
rdmsrq(x86_pmu_fixed_ctr_addr(idx), pmc_count);
pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
@@ -2180,7 +2176,7 @@ static int __init init_hw_perf_events(void)
pmu_check_apic();
/* sanity check that the hardware exists or is emulated */
- if (!check_hw_exists(&pmu, x86_pmu.cntr_mask, x86_pmu.fixed_cntr_mask))
+ if (!check_hw_exists(x86_pmu.cntr_mask, x86_pmu.fixed_cntr_mask))
goto out_bad_pmu;
pr_cont("%s PMU driver.\n", x86_pmu.name);
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index b47d2f00ac13..c418176065f6 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3713,8 +3713,6 @@ static void intel_pmu_reset(void)
wrmsrq_safe(x86_pmu_event_addr(idx), 0ull);
}
for_each_set_bit(idx, fixed_cntr_mask, INTEL_PMC_MAX_FIXED) {
- if (fixed_counter_disabled(idx, cpuc->pmu))
- continue;
wrmsrq_safe(x86_pmu_fixed_ctr_addr(idx), 0ull);
}
@@ -6336,7 +6334,7 @@ static bool init_hybrid_pmu(int cpu)
intel_pmu_check_hybrid_pmus(pmu);
- if (!check_hw_exists(&pmu->pmu, pmu->cntr_mask, pmu->fixed_cntr_mask)) {
+ if (!check_hw_exists(pmu->cntr_mask, pmu->fixed_cntr_mask)) {
cpuc->pmu = NULL;
return false;
}
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 01ae287cde16..cc9cfaae4f01 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1243,7 +1243,7 @@ static inline int x86_pmu_rdpmc_index(int index)
return x86_pmu.rdpmc_index ? x86_pmu.rdpmc_index(index) : index;
}
-bool check_hw_exists(struct pmu *pmu, unsigned long *cntr_mask,
+bool check_hw_exists(unsigned long *cntr_mask,
unsigned long *fixed_cntr_mask);
int x86_add_exclusive(unsigned int what);
@@ -1456,13 +1456,6 @@ ssize_t events_hybrid_sysfs_show(struct device *dev,
struct device_attribute *attr,
char *page);
-static inline bool fixed_counter_disabled(int i, struct pmu *pmu)
-{
- u64 intel_ctrl = hybrid(pmu, intel_ctrl);
-
- return !(intel_ctrl >> (i + INTEL_PMC_IDX_FIXED));
-}
-
#ifdef CONFIG_CPU_SUP_AMD
int amd_pmu_init(void);
--
2.34.1
next prev parent reply other threads:[~2026-07-13 8:33 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-13 8:27 [Patch v2 0/7] perf/x86: Miscellaneous PMU bug fixes and optimizations Dapeng Mi
2026-07-13 8:27 ` [Patch v2 1/7] perf/x86: Unregister PMI handler on PMU init failure Dapeng Mi
2026-07-13 8:27 ` [Patch v2 2/7] perf/x86: Free hybrid state " Dapeng Mi
2026-07-13 8:27 ` [Patch v2 3/7] perf/x86: Guard intel_pmu_cpu_dead() against invalid hybrid PMU casts Dapeng Mi
2026-07-13 8:59 ` sashiko-bot
2026-07-13 8:27 ` [Patch v2 4/7] perf/x86/intel: Unwind cpuc state if PEBS buffer setup fails Dapeng Mi
2026-07-13 8:27 ` Dapeng Mi [this message]
2026-07-13 8:27 ` [Patch v2 6/7] perf/x86/intel: Fix intel_cap handling on hybrid PMUs Dapeng Mi
2026-07-13 8:27 ` [Patch v2 7/7] perf/x86: Optimize ACR handling in match_prev_assignment() Dapeng Mi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260713082734.3162099-6-dapeng1.mi@linux.intel.com \
--to=dapeng1.mi@linux.intel.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=dapeng1.mi@intel.com \
--cc=irogers@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=thomas.falcon@intel.com \
--cc=xudong.hao@intel.com \
--cc=zide.chen@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.