lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAAhSdy1U02MDSGdMy+zCzdF4YENzvvKLnS+uszPpkH_nAPA9yw@mail.gmail.com>
Date: Fri, 18 Jul 2025 10:09:34 +0530
From: Anup Patel <anup@...infault.org>
To: Atish Patra <atishp@...osinc.com>
Cc: Will Deacon <will@...nel.org>, Mark Rutland <mark.rutland@....com>, 
	Paul Walmsley <paul.walmsley@...ive.com>, Palmer Dabbelt <palmer@...belt.com>, 
	Mayuresh Chitale <mchitale@...tanamicro.com>, linux-riscv@...ts.infradead.org, 
	linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org, 
	Palmer Dabbelt <palmer@...osinc.com>, kvm@...r.kernel.org, kvm-riscv@...ts.infradead.org
Subject: Re: [PATCH v3 5/9] drivers/perf: riscv: Export PMU event info function

On Fri, May 23, 2025 at 12:33 AM Atish Patra <atishp@...osinc.com> wrote:
>
> The event mapping function can be used in event info function to find out
> the corresponding SBI PMU event encoding during the get_event_info function
> as well. Refactor and export it so that it can be invoked from kvm and
> internal driver.
>
> Signed-off-by: Atish Patra <atishp@...osinc.com>
> ---
>  drivers/perf/riscv_pmu_sbi.c   | 124 ++++++++++++++++++++++-------------------
>  include/linux/perf/riscv_pmu.h |   2 +
>  2 files changed, 69 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index 33d8348bf68a..f5d3db6dba18 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -100,6 +100,7 @@ static unsigned int riscv_pmu_irq;
>  /* Cache the available counters in a bitmask */
>  static unsigned long cmask;
>
> +static int pmu_event_find_cache(u64 config);
>  struct sbi_pmu_event_data {
>         union {
>                 union {
> @@ -411,6 +412,71 @@ static bool pmu_sbi_ctr_is_fw(int cidx)
>         return (info->type == SBI_PMU_CTR_TYPE_FW) ? true : false;
>  }
>
> +int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig)
> +{
> +       int ret = -ENOENT;
> +
> +       switch (type) {
> +       case PERF_TYPE_HARDWARE:
> +               if (config >= PERF_COUNT_HW_MAX)
> +                       return -EINVAL;
> +               ret = pmu_hw_event_map[config].event_idx;
> +               break;
> +       case PERF_TYPE_HW_CACHE:
> +               ret = pmu_event_find_cache(config);
> +               break;
> +       case PERF_TYPE_RAW:
> +               /*
> +                * As per SBI v0.3 specification,
> +                *  -- the upper 16 bits must be unused for a hardware raw event.
> +                * As per SBI v3.0 specification,
> +                *  -- the upper 8 bits must be unused for a hardware raw event.
> +                * Bits 63:62 are used to distinguish between raw events
> +                * 00 - Hardware raw event
> +                * 10 - SBI firmware events
> +                * 11 - Risc-V platform specific firmware event
> +                */
> +               switch (config >> 62) {
> +               case 0:
> +                       if (sbi_v3_available) {
> +                       /* Return error any bits [56-63] is set  as it is not allowed by the spec */
> +                               if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK)) {
> +                                       if (econfig)
> +                                               *econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
> +                                       ret = RISCV_PMU_RAW_EVENT_V2_IDX;
> +                               }
> +                       /* Return error any bits [48-63] is set  as it is not allowed by the spec */
> +                       } else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK)) {
> +                               if (econfig)
> +                                       *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> +                               ret = RISCV_PMU_RAW_EVENT_IDX;
> +                       }
> +                       break;
> +               case 2:
> +                       ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
> +                       break;
> +               case 3:
> +                       /*
> +                        * For Risc-V platform specific firmware events
> +                        * Event code - 0xFFFF
> +                        * Event data - raw event encoding
> +                        */
> +                       ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
> +                       if (econfig)
> +                               *econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
> +                       break;
> +               default:
> +                       break;
> +               }
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(riscv_pmu_get_event_info);
> +
>  /*
>   * Returns the counter width of a programmable counter and number of hardware
>   * counters. As we don't support heterogeneous CPUs yet, it is okay to just
> @@ -576,7 +642,6 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
>  {
>         u32 type = event->attr.type;
>         u64 config = event->attr.config;
> -       int ret = -ENOENT;
>
>         /*
>          * Ensure we are finished checking standard hardware events for
> @@ -584,62 +649,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
>          */
>         flush_work(&check_std_events_work);
>
> -       switch (type) {
> -       case PERF_TYPE_HARDWARE:
> -               if (config >= PERF_COUNT_HW_MAX)
> -                       return -EINVAL;
> -               ret = pmu_hw_event_map[event->attr.config].event_idx;
> -               break;
> -       case PERF_TYPE_HW_CACHE:
> -               ret = pmu_event_find_cache(config);
> -               break;
> -       case PERF_TYPE_RAW:
> -               /*
> -                * As per SBI v0.3 specification,
> -                *  -- the upper 16 bits must be unused for a hardware raw event.
> -                * As per SBI v3.0 specification,
> -                *  -- the upper 8 bits must be unused for a hardware raw event.
> -                * Bits 63:62 are used to distinguish between raw events
> -                * 00 - Hardware raw event
> -                * 10 - SBI firmware events
> -                * 11 - Risc-V platform specific firmware event
> -                */
> -
> -               switch (config >> 62) {
> -               case 0:
> -                       if (sbi_v3_available) {
> -                       /* Return error any bits [56-63] is set  as it is not allowed by the spec */
> -                               if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK)) {
> -                                       *econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
> -                                       ret = RISCV_PMU_RAW_EVENT_V2_IDX;
> -                               }
> -                       /* Return error any bits [48-63] is set  as it is not allowed by the spec */
> -                       } else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK)) {
> -                               *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> -                               ret = RISCV_PMU_RAW_EVENT_IDX;
> -                       }
> -                       break;
> -               case 2:
> -                       ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
> -                       break;
> -               case 3:
> -                       /*
> -                        * For Risc-V platform specific firmware events
> -                        * Event code - 0xFFFF
> -                        * Event data - raw event encoding
> -                        */
> -                       ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
> -                       *econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
> -                       break;
> -               default:
> -                       break;
> -               }
> -               break;
> -       default:
> -               break;
> -       }
> -
> -       return ret;
> +       return riscv_pmu_get_event_info(type, config, econfig);
>  }
>
>  static void pmu_sbi_snapshot_free(struct riscv_pmu *pmu)
> diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h
> index 701974639ff2..4a5e3209c473 100644
> --- a/include/linux/perf/riscv_pmu.h
> +++ b/include/linux/perf/riscv_pmu.h
> @@ -91,6 +91,8 @@ struct riscv_pmu *riscv_pmu_alloc(void);
>  int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr);
>  #endif
>
> +int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig);
> +
>  #endif /* CONFIG_RISCV_PMU */

We will see compile/link errors for users of riscv_pmu_get_event_info()
if CONFIG_RISCV_PMU_SBI is not defined. Am I missing anything

>
>  #endif /* _RISCV_PMU_H */
>
> --
> 2.43.0
>

Regards,
Anup

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ