mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
perf/x86: Remove stale fixed counter helper and fix hybrid PMU access
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 32451614da
("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>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Thomas Falcon <thomas.falcon@intel.com>
Reviewed-by: Zide Chen <zide.chen@intel.com>
Link: https://patch.msgid.link/20260717080342.1879573-6-dapeng1.mi@linux.intel.com
This commit is contained in:
parent
85182f902a
commit
3ba87c5bf1
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user