* [PATCH] lib: sbi_pmu: Match raw event selector only against raw event map entries
@ 2026-08-03 17:11 David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 0/3] lib: sbi_pmu: SBI v3.0 PMU error code fixes David E. Garcia Porras
0 siblings, 1 reply; 5+ messages in thread
From: David E. Garcia Porras @ 2026-08-03 17:11 UTC (permalink / raw)
To: opensbi; +Cc: Atish Patra, David E. Garcia Porras
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 <david.garcia@aheadcomputing.com>
---
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 a0f6d2fa..4e93dc10 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -1107,6 +1107,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)) {
--
2.43.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 0/3] lib: sbi_pmu: SBI v3.0 PMU error code fixes
2026-08-03 17:11 [PATCH] lib: sbi_pmu: Match raw event selector only against raw event map entries David E. Garcia Porras
@ 2026-08-18 21:00 ` David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 1/3] lib: sbi_pmu: Return invalid param error for reserved event_idx bits David E. Garcia Porras
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: David E. Garcia Porras @ 2026-08-18 21:00 UTC (permalink / raw)
To: opensbi; +Cc: David E. Garcia Porras
This series fixes several places where the PMU extension returns
error codes that do not match the SBI v3.0 specification, chapter 11.
Changes in v2:
- Added patch 3/3: reject reserved flag bits in counter start/stop,
propagate ALREADY_STARTED/ALREADY_STOPPED, and report firmware
events as supported in event_get_info.
- Patches 1/3 and 2/3 are unchanged from their v1 submissions.
This series supersedes the two standalone v1 patches.
David E. Garcia Porras (3):
lib: sbi_pmu: Return invalid param error for reserved event_idx bits
lib: sbi_pmu: Match raw event selector only against raw event map
entries
lib: sbi_pmu: Fix counter and event info error codes as per SBI v3.0
spec
include/sbi/sbi_ecall_interface.h | 14 ++++++++
lib/sbi/sbi_pmu.c | 55 ++++++++++++++++++++++++-------
2 files changed, 57 insertions(+), 12 deletions(-)
--
2.43.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/3] lib: sbi_pmu: Return invalid param error for reserved event_idx bits
2026-08-18 21:00 ` [PATCH v2 0/3] lib: sbi_pmu: SBI v3.0 PMU error code fixes David E. Garcia Porras
@ 2026-08-18 21:00 ` David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 2/3] lib: sbi_pmu: Match raw event selector only against raw event map entries David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 3/3] lib: sbi_pmu: Fix counter and event info error codes as per SBI v3.0 spec David E. Garcia Porras
2 siblings, 0 replies; 5+ messages in thread
From: David E. Garcia Porras @ 2026-08-18 21:00 UTC (permalink / raw)
To: opensbi; +Cc: David E. Garcia Porras
As per section 11.14 of the SBI specification (Function: Get PMU Event
Info, FID #8), Table 47, the event_idx word of an event info entry
only uses BIT[0:19]; BIT[20:31] are reserved for the future purpose
and must be zero. Table 48 further requires the SBI implementation to
return SBI_ERR_INVALID_PARAM if any reserved bit in an event_idx word
is set.
sbi_pmu_event_get_info() does not check the reserved bits, so a
malformed event_idx is silently passed on to pmu_event_validate()
instead of failing the call. Add SBI_PMU_EVENT_IDX_MBZ_MASK covering
the must-be-zero bits and return SBI_ERR_INVALID_PARAM when any of
them are set.
Fixes: e4345842168b ("lib: sbi_pmu: Implement SBI PMU event info function")
Signed-off-by: David E. Garcia Porras <david.garcia@aheadcomputing.com>
---
include/sbi/sbi_ecall_interface.h | 2 ++
lib/sbi/sbi_pmu.c | 3 +++
2 files changed, 5 insertions(+)
diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index acb91a01..bfde25d0 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -271,6 +271,8 @@ struct sbi_pmu_event_info {
#define SBI_PMU_EVENT_IDX_TYPE_OFFSET 16
#define SBI_PMU_EVENT_IDX_TYPE_MASK (0xF << SBI_PMU_EVENT_IDX_TYPE_OFFSET)
#define SBI_PMU_EVENT_IDX_CODE_MASK 0xFFFF
+#define SBI_PMU_EVENT_IDX_MBZ_OFFSET 20
+#define SBI_PMU_EVENT_IDX_MBZ_MASK (0xFFF << SBI_PMU_EVENT_IDX_MBZ_OFFSET)
#define SBI_PMU_EVENT_RAW_IDX 0x20000
#define SBI_PMU_EVENT_RAW_V2_IDX 0x30000
diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
index a0f6d2fa..4558876e 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -1098,6 +1098,9 @@ int sbi_pmu_event_get_info(unsigned long shmem_phys_lo, unsigned long shmem_phys
einfo = (struct sbi_pmu_event_info *)(shmem_phys_lo);
for (i = 0; i < num_events; i++) {
event_idx = einfo[i].event_idx;
+ /* Any must-be-zero event_idx bits set should return INVALID_PARAM per-spec */
+ if (event_idx & SBI_PMU_EVENT_IDX_MBZ_MASK)
+ return SBI_ERR_INVALID_PARAM;
event_type = pmu_event_validate(phs, event_idx, einfo[i].event_data);
if (event_type < 0) {
einfo[i].output = 0;
--
2.43.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] lib: sbi_pmu: Match raw event selector only against raw event map entries
2026-08-18 21:00 ` [PATCH v2 0/3] lib: sbi_pmu: SBI v3.0 PMU error code fixes David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 1/3] lib: sbi_pmu: Return invalid param error for reserved event_idx bits David E. Garcia Porras
@ 2026-08-18 21:00 ` David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 3/3] lib: sbi_pmu: Fix counter and event info error codes as per SBI v3.0 spec David E. Garcia Porras
2 siblings, 0 replies; 5+ messages in thread
From: David E. Garcia Porras @ 2026-08-18 21:00 UTC (permalink / raw)
To: opensbi; +Cc: David E. Garcia Porras
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 <david.garcia@aheadcomputing.com>
---
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)) {
--
2.43.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] lib: sbi_pmu: Fix counter and event info error codes as per SBI v3.0 spec
2026-08-18 21:00 ` [PATCH v2 0/3] lib: sbi_pmu: SBI v3.0 PMU error code fixes David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 1/3] lib: sbi_pmu: Return invalid param error for reserved event_idx bits David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 2/3] lib: sbi_pmu: Match raw event selector only against raw event map entries David E. Garcia Porras
@ 2026-08-18 21:00 ` David E. Garcia Porras
2 siblings, 0 replies; 5+ messages in thread
From: David E. Garcia Porras @ 2026-08-18 21:00 UTC (permalink / raw)
To: opensbi; +Cc: David E. Garcia Porras
Align the PMU extension implementation with the error codes required
by the SBI v3.0 specification, chapter 11:
- sbi_pmu_counter_start and sbi_pmu_counter_stop (secs 11.9-11.10,
tables 39-42): the start_flags/stop_flags bits 2:(XLEN-1) are
reserved and must be zero, so return SBI_ERR_INVALID_PARAM when any
reserved flag bit is set. Introduce SBI_PMU_START_FLAGS_MASK and
SBI_PMU_STOP_FLAGS_MASK for the valid bits of each function.
- sbi_pmu_counter_start and sbi_pmu_counter_stop (tables 40 and 42):
return SBI_ERR_ALREADY_STARTED / SBI_ERR_ALREADY_STOPPED when the
set of counters includes a counter which is already started or
stopped, instead of ignoring the error returned for each counter.
- sbi_pmu_event_get_info (sec 11.14, table 47): the output word must
indicate whether the event is supported, but firmware events were
only matched against the hardware event map and were always
reported as unsupported. Report a validated firmware event as
supported.
Signed-off-by: David E. Garcia Porras <david.garcia@aheadcomputing.com>
---
include/sbi/sbi_ecall_interface.h | 12 ++++++
lib/sbi/sbi_pmu.c | 61 ++++++++++++++++++++-----------
2 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index bfde25d0..fd4e77ca 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -306,10 +306,22 @@ struct sbi_pmu_event_info {
/* Flags defined for counter start function */
#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
#define SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT (1 << 1)
+/* Start flags valid mask */
+#define SBI_PMU_START_FLAGS_MASK \
+ ( \
+ SBI_PMU_START_FLAG_SET_INIT_VALUE | \
+ SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT \
+ )
/* Flags defined for counter stop function */
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT (1 << 1)
+/* Stop flags valid mask */
+#define SBI_PMU_STOP_FLAGS_MASK \
+ ( \
+ SBI_PMU_STOP_FLAG_RESET | \
+ SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT \
+ )
/* SBI function IDs for DBCN extension */
#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
index 676de9aa..0c62bde0 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -574,6 +574,9 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
if (!pmu_ctr_idx_validate(cbase, cmask))
return ret;
+ if (flags & ~SBI_PMU_START_FLAGS_MASK)
+ return SBI_ERR_INVALID_PARAM;
+
if (flags & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
return SBI_ENO_SHMEM;
@@ -592,6 +595,8 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
: 0x0;
ret = pmu_ctr_start_fw(phs, cidx, event_code, edata,
ival, bUpdate);
+ if (ret)
+ return ret;
} else {
if (cidx >= 3) {
struct sbi_pmu_hw_event_config *ev_cfg =
@@ -605,6 +610,8 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
return ret;
}
ret = pmu_ctr_start_hw(cidx, ival, bUpdate);
+ if (ret)
+ return ret;
}
}
@@ -693,6 +700,9 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
if (!pmu_ctr_idx_validate(cbase, cmask))
return ret;
+ if (flag & ~SBI_PMU_STOP_FLAGS_MASK)
+ return SBI_ERR_INVALID_PARAM;
+
if (flag & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
return SBI_ENO_SHMEM;
@@ -708,6 +718,9 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
else
ret = pmu_ctr_stop_hw(cidx);
+ if(ret)
+ return ret;
+
if (cidx > (CSR_INSTRET - CSR_CYCLE) && flag & SBI_PMU_STOP_FLAG_RESET) {
phs->active_events[cidx] = SBI_PMU_EVENT_IDX_INVALID;
pmu_reset_hw_mhpmevent(cidx);
@@ -1105,30 +1118,36 @@ int sbi_pmu_event_get_info(unsigned long shmem_phys_lo, unsigned long shmem_phys
if (event_type < 0) {
einfo[i].output = 0;
} else {
- for (j = 0; j < num_hw_events; j++) {
- temp = &hw_event_map[j];
- /* 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)) {
+ if (event_type == SBI_PMU_EVENT_TYPE_FW) {
+ /* pmu_event_validate() already confirmed this event is valid; counter support is checked later by cfg_match/find_fw. */
+ einfo[i].output = 1;
+ continue;
+ } else {
+ for (j = 0; j < num_hw_events; j++) {
+ temp = &hw_event_map[j];
+ /* 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)) {
+ found = true;
+ break;
+ }
+ } else if (temp->start_idx <= event_idx &&
+ event_idx <= temp->end_idx) {
found = true;
break;
}
- } else if (temp->start_idx <= event_idx &&
- event_idx <= temp->end_idx) {
- found = true;
- break;
}
}
if (found)
--
2.43.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-18 21:01 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03 17:11 [PATCH] lib: sbi_pmu: Match raw event selector only against raw event map entries David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 0/3] lib: sbi_pmu: SBI v3.0 PMU error code fixes David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 1/3] lib: sbi_pmu: Return invalid param error for reserved event_idx bits David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 2/3] lib: sbi_pmu: Match raw event selector only against raw event map entries David E. Garcia Porras
2026-08-18 21:00 ` [PATCH v2 3/3] lib: sbi_pmu: Fix counter and event info error codes as per SBI v3.0 spec David E. Garcia Porras
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.