[<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