diff options
| author | yang.zhang <[email protected]> | 2024-02-01 10:01:26 +0800 |
|---|---|---|
| committer | Anup Patel <[email protected]> | 2024-02-20 16:24:06 +0530 |
| commit | 88273fe19e97e76aa2645add370324840dc7222a (patch) | |
| tree | 5f279b14ce3dc973f560f0b7bb5bb6ed7e302581 | |
| parent | 46c8c6582db1186ed8d474ff59df428e0e6dd89b (diff) | |
lib: sbi_pmu: Before using we should ensure PMU init done
If trap earlier before sbi_pmu_init done, some path would call
sbi_pmu_ctr_incr_fw, then it would go wrong:
1. if phs_ptr_offset is zero, then it get a wrong pmu state ptr
2. if phs_ptr_offset is ok, but we didn't call pmu_set_hart_state_ptr
it would be NULL POINT
Of course, the above situation will not occur at present, but it is
reasonable to check before using.
Signed-off-by: yang.zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
| -rw-r--r-- | lib/sbi/sbi_pmu.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c index 6209ccc9..62a6465a 100644 --- a/lib/sbi/sbi_pmu.c +++ b/lib/sbi/sbi_pmu.c @@ -74,7 +74,7 @@ struct sbi_pmu_hart_state { static unsigned long phs_ptr_offset; #define pmu_get_hart_state_ptr(__scratch) \ - sbi_scratch_read_type((__scratch), void *, phs_ptr_offset) + phs_ptr_offset ? sbi_scratch_read_type((__scratch), void *, phs_ptr_offset) : NULL #define pmu_thishart_state_ptr() \ pmu_get_hart_state_ptr(sbi_scratch_thishart_ptr()) @@ -207,6 +207,9 @@ int sbi_pmu_ctr_fw_read(uint32_t cidx, uint64_t *cval) uint32_t event_code; struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr(); + if (unlikely(!phs)) + return SBI_EINVAL; + event_idx_type = pmu_ctr_validate(phs, cidx, &event_code); if (event_idx_type != SBI_PMU_EVENT_TYPE_FW) return SBI_EINVAL; @@ -432,6 +435,10 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask, unsigned long flags, uint64_t ival) { struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr(); + + if (unlikely(!phs)) + return SBI_EINVAL; + int event_idx_type; uint32_t event_code; int ret = SBI_EINVAL; @@ -535,6 +542,10 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask, unsigned long flag) { struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr(); + + if (unlikely(!phs)) + return SBI_EINVAL; + int ret = SBI_EINVAL; int event_idx_type; uint32_t event_code; @@ -794,6 +805,10 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask, uint64_t event_data) { struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr(); + + if (unlikely(!phs)) + return SBI_EINVAL; + int ret, event_type, ctr_idx = SBI_ENOTSUPP; u32 event_code; @@ -869,6 +884,9 @@ int sbi_pmu_ctr_incr_fw(enum sbi_pmu_fw_event_code_id fw_id) uint64_t *fcounter = NULL; struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr(); + if (unlikely(!phs)) + return 0; + if (likely(!phs->fw_counters_started)) return 0; @@ -961,13 +979,18 @@ void sbi_pmu_set_device(const struct sbi_pmu_device *dev) void sbi_pmu_exit(struct sbi_scratch *scratch) { + struct sbi_pmu_hart_state *phs = pmu_get_hart_state_ptr(scratch); + if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11) csr_write(CSR_MCOUNTINHIBIT, 0xFFFFFFF8); if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10) csr_write(CSR_MCOUNTEREN, -1); - pmu_reset_event_map(pmu_get_hart_state_ptr(scratch)); + if (unlikely(!phs)) + return; + + pmu_reset_event_map(phs); } int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot) |
