OpenSBI Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox