lib: sbi_pmu: Fix xINH bits configuring

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: 1db95da299 ("lib: sbi: sbi_pmu: fixed hw counters start for hart")
Signed-off-by: Shifrin Dmitry <dmitry.shifrin@syntacore.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20251110113140.80561-1-dmitry.shifrin@syntacore.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Shifrin Dmitry
2025-11-10 14:31:40 +03:00
committed by Anup Patel
parent da05980de6
commit c9f856e23f
2 changed files with 35 additions and 7 deletions

View File

@@ -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)

View File

@@ -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)