[PATCH] lib: sbi: sbi_pmu: Fix xINH bits configuring

Shifrin Dmitry dmitry.shifrin at syntacore.com
Mon Nov 10 03:31:40 PST 2025


Before this patch sbi_pmu_ctr_start() ignores
flags received in sbi_pmu_ctr_cfg_match() including
inhibit ones.
To prevent it save flags together with event_data
and use them both in sbi_pmu_ctr_start()

Fixes: 1db95da2997b ("lib: sbi: sbi_pmu: fixed hw counters start for hart")

Signed-off-by: Shifrin Dmitry <dmitry.shifrin at syntacore.com>
---
 include/sbi/sbi_ecall_interface.h |  9 +++++++++
 lib/sbi/sbi_pmu.c                 | 33 ++++++++++++++++++++++++-------
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index af7a05af..bdffb0fa 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -291,6 +291,15 @@ struct sbi_pmu_event_info {
 #define SBI_PMU_CFG_FLAG_SET_UINH	(1 << 5)
 #define SBI_PMU_CFG_FLAG_SET_SINH	(1 << 6)
 #define SBI_PMU_CFG_FLAG_SET_MINH	(1 << 7)
+/* Event configuration mask */
+#define SBI_PMU_CFG_EVENT_MASK          \
+	( \
+		SBI_PMU_CFG_FLAG_SET_VUINH | \
+		SBI_PMU_CFG_FLAG_SET_VSINH | \
+		SBI_PMU_CFG_FLAG_SET_UINH  | \
+		SBI_PMU_CFG_FLAG_SET_SINH  | \
+		SBI_PMU_CFG_FLAG_SET_MINH    \
+	)
 
 /* Flags defined for counter start function */
 #define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
index 70c49abc..e24e485d 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -56,6 +56,14 @@ union sbi_pmu_ctr_info {
 #error "Can't handle firmware counters beyond BITS_PER_LONG"
 #endif
 
+/** HW event configuration parameters */
+struct sbi_pmu_hw_event_config {
+	/* event_data value from sbi_pmu_ctr_cfg_match() */
+	uint64_t event_data;
+	/* HW events flags from sbi_pmu_ctr_cfg_match() */
+	uint64_t flags;
+};
+
 /** Per-HART state of the PMU counters */
 struct sbi_pmu_hart_state {
 	/* HART to which this state belongs */
@@ -72,11 +80,12 @@ struct sbi_pmu_hart_state {
 	 * and hence can optimally share the same memory.
 	 */
 	uint64_t fw_counters_data[SBI_PMU_FW_CTR_MAX];
-	/* Data values from sbi_pmu_ctr_cfg_match() command which
-	 * is used for restoring RAW hardware events after
+	/* HW events configuration parameters from
+	 * sbi_pmu_ctr_cfg_match() command which are
+	 * used for restoring RAW hardware events after
 	 * cpu suspending.
 	 */
-	uint64_t hw_counters_data[SBI_PMU_HW_CTR_MAX];
+	struct sbi_pmu_hw_event_config hw_counters_cfg[SBI_PMU_HW_CTR_MAX];
 };
 
 /** Offset of pointer to PMU HART state in scratch space */
@@ -561,9 +570,13 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
 					       ival, bUpdate);
 		} else {
 			if (cidx >= 3) {
+				struct sbi_pmu_hw_event_config *ev_cfg =
+					&phs->hw_counters_cfg[cidx];
+
 				ret = pmu_update_hw_mhpmevent(&hw_event_map[cidx], cidx,
-							0, phs->active_events[cidx],
-							phs->hw_counters_data[cidx]);
+							ev_cfg->flags,
+							phs->active_events[cidx],
+							ev_cfg->event_data);
 				if (ret)
 					return ret;
 			}
@@ -892,8 +905,14 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
 	} else {
 		ctr_idx = pmu_ctr_find_hw(phs, cidx_base, cidx_mask, flags,
 					  event_idx, event_data);
-		if (ctr_idx >= 0)
-			phs->hw_counters_data[ctr_idx] = event_data;
+		if (ctr_idx >= 0) {
+			struct sbi_pmu_hw_event_config *ev_cfg =
+					&phs->hw_counters_cfg[ctr_idx];
+
+			ev_cfg->event_data = event_data;
+			/* Remove flags that are used in match call only */
+			ev_cfg->flags = flags & SBI_PMU_CFG_EVENT_MASK;
+		}
 	}
 
 	if (ctr_idx < 0)
-- 
2.34.1




More information about the opensbi mailing list