[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