[PATCH v4] lib: sbi: pmu: Return SBI_EINVAL if cidx_mask is 0

Anup Patel anup at brainfault.org
Tue May 20 08:32:47 PDT 2025


On Tue, May 20, 2025 at 6:57 PM James Raphael Tiovalen
<jamestiotio at gmail.com> wrote:
>
> Currently, when configuring a matching programmable HPM counter with
> Sscofpmf being present, cidx_base > 2, and cidx_mask == 0 to monitor
> either the CPU_CYCLES or INSTRUCTIONS hardware event,
> sbi_pmu_ctr_cfg_match will succeed but it will configure the
> corresponding fixed counter instead of the counter specified by the
> cidx_base parameter.
>
> During counter configuration, the following issues may arise:
> - If the SKIP_MATCH flag is set, an out-of-bounds memory read of the
> phs->active_events array would occur, which could lead to undefined
> behavior.
>
> - If the CLEAR_VALUE flag is set, the corresponding fixed counter will
> be reset, which could be considered unexpected behavior.
>
> - If the AUTO_START flag is set, pmu_ctr_start_hw will silently start
> the fixed counter, even though it has already started. From the
> supervisor's perspective, nothing has changed, which could be confusing.
> The supervisor will not see the SBI_ERR_ALREADY_STARTED error code since
> sbi_pmu_ctr_cfg_match does not return the error code of
> pmu_ctr_start_hw.
>
> The only way to detect these issues is to check the ctr_idx return value
> of sbi_pmu_ctr_cfg_match and compare it with cidx_base.
>
> Fix these issues by returning the SBI_ERR_INVALID_PARAM error code if
> the cidx_mask parameter value being passed in is 0 since an invalid
> parameter should not lead to a successful sbi_pmu_ctr_cfg_match but with
> unexpected side effects.
>
> Following a similar rationale, add the validation check to
> sbi_pmu_ctr_start and sbi_pmu_ctr_stop as well since sbi_fls is
> undefined when the mask is 0.
>
> This also aligns OpenSBI's behavior with KVM's.
>
> Signed-off-by: James Raphael Tiovalen <jamestiotio at gmail.com>
> Reviewed-by: Atish Patra <atishp at rivosinc.com>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
>  lib/sbi/sbi_pmu.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
> index 5983a78..6ca4efd 100644
> --- a/lib/sbi/sbi_pmu.c
> +++ b/lib/sbi/sbi_pmu.c
> @@ -206,6 +206,12 @@ static int pmu_ctr_validate(struct sbi_pmu_hart_state *phs,
>         return event_idx_type;
>  }
>
> +static bool pmu_ctr_idx_validate(unsigned long cbase, unsigned long cmask)
> +{
> +       /* Do a basic sanity check of counter base & mask */
> +       return cmask && cbase + sbi_fls(cmask) < total_ctrs;
> +}
> +
>  int sbi_pmu_ctr_fw_read(uint32_t cidx, uint64_t *cval)
>  {
>         int event_idx_type;
> @@ -472,7 +478,7 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
>         int i, cidx;
>         uint64_t edata;
>
> -       if ((cbase + sbi_fls(cmask)) >= total_ctrs)
> +       if (!pmu_ctr_idx_validate(cbase, cmask))
>                 return ret;
>
>         if (flags & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
> @@ -577,8 +583,8 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
>         uint32_t event_code;
>         int i, cidx;
>
> -       if ((cbase + sbi_fls(cmask)) >= total_ctrs)
> -               return SBI_EINVAL;
> +       if (!pmu_ctr_idx_validate(cbase, cmask))
> +               return ret;
>
>         if (flag & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
>                 return SBI_ENO_SHMEM;
> @@ -839,8 +845,7 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
>         int ret, event_type, ctr_idx = SBI_ENOTSUPP;
>         u32 event_code;
>
> -       /* Do a basic sanity check of counter base & mask */
> -       if ((cidx_base + sbi_fls(cidx_mask)) >= total_ctrs)
> +       if (!pmu_ctr_idx_validate(cidx_base, cidx_mask))
>                 return SBI_EINVAL;
>
>         event_type = pmu_event_validate(phs, event_idx, event_data);
> --
> 2.43.0
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi



More information about the opensbi mailing list