From d34a39df779aa55a2dd929717a32e48c3a80df66 Mon Sep 17 00:00:00 2001 From: "David E. Garcia Porras" Date: Tue, 18 Aug 2026 15:00:22 -0600 Subject: [PATCH] lib: sbi_pmu: Match raw event selector only against raw event map entries sbi_pmu_event_get_info() walks hw_event_map[] to decide whether a requested event is supported. For SBI_PMU_EVENT_RAW_IDX and SBI_PMU_EVENT_RAW_V2_IDX it compares the requested event_data against temp->select / temp->select_mask without first checking that the map entry being examined is itself a raw event entry. Non-raw hardware event entries are added via sbi_pmu_add_hw_event_counter_map(), leave select and select_mask at zero, hence they satisfy: temp->select == (event_data & temp->select_mask) so the first non-raw entry visited will always match. The issue's observability depends purely on the ordering of hw_event_map[]: if the platform registers its raw events last, every raw event query, including unsupported ones, will be reported as supported. Fix it by checking event_idx against temp->start_idx and temp->end_idx before comparing select/select_mask. Fixes: e4345842168b ("lib: sbi_pmu: Implement SBI PMU event info function") Signed-off-by: David E. Garcia Porras Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20260818210023.466462-3-david.garcia@aheadcomputing.com Signed-off-by: Anup Patel --- lib/sbi/sbi_pmu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c index 4558876e..676de9aa 100644 --- a/lib/sbi/sbi_pmu.c +++ b/lib/sbi/sbi_pmu.c @@ -1110,6 +1110,15 @@ int sbi_pmu_event_get_info(unsigned long shmem_phys_lo, unsigned long shmem_phys /* For raw events, event data is used as the select value */ if (event_idx == SBI_PMU_EVENT_RAW_IDX || event_idx == SBI_PMU_EVENT_RAW_V2_IDX) { + /* + * Only a raw event map entry carries a + * meaningful select/select_mask pair, so + * skip any entry which does not cover the + * raw event index. + */ + if (temp->start_idx > event_idx || + event_idx > temp->end_idx) + continue; /* just match the selector */ if (temp->select == (einfo[i].event_data & temp->select_mask)) {