[PATCH v8 13/22] RISC-V: perf: Add a mechanism to defined legacy event encoding
Yicong Yang
yang.yicong at picoheart.com
Tue Jul 7 00:51:09 PDT 2026
On 7/1/26 4:47 PM, Atish Patra wrote:
> From: Atish Patra <atishp at rivosinc.com>
>
> RISC-V ISA doesn't define any standard event encodings or specify
> any event to counter mapping. Thus, event encoding information
> and corresponding counter mapping fot those events needs to be
> provided in the driver for each vendor.
>
> Add a framework to support that. The individual platform events
> will be added later.
>
> Signed-off-by: Atish Patra <atishp at rivosinc.com>
> ---
> drivers/perf/riscv_pmu_sbi.c | 70 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index c20f1e33c65d..2568c6808f5d 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -10,6 +10,7 @@
>
> #define pr_fmt(fmt) "riscv-pmu-sbi: " fmt
>
> +#include <linux/limits.h>
> #include <linux/mod_devicetable.h>
> #include <linux/perf/riscv_pmu.h>
> #include <linux/platform_device.h>
> @@ -379,6 +380,71 @@ static int pmu_sbi_check_event_info(void)
> return result;
> }
>
> +/*
> + * Vendor specific PMU events.
> + */
> +struct riscv_pmu_event {
> + u64 event_id;
> + u32 counter_mask;
could we name it as counterid_mask to match to the PMU format
name (introduced in patch 16/22)?
thanks.
> +};
> +
> +#define HW_OP_UNSUPPORTED U64_MAX
> +#define CACHE_OP_UNSUPPORTED U64_MAX
> +
> +#define PERF_MAP_ALL_UNSUPPORTED \
> + [0 ... PERF_COUNT_HW_MAX - 1] = {HW_OP_UNSUPPORTED, 0x0}
> +
> +#define PERF_CACHE_MAP_ALL_UNSUPPORTED \
> +[0 ... PERF_COUNT_HW_CACHE_MAX - 1] = { \
> + [0 ... PERF_COUNT_HW_CACHE_OP_MAX - 1] = { \
> + [0 ... PERF_COUNT_HW_CACHE_RESULT_MAX - 1] = { \
> + CACHE_OP_UNSUPPORTED, 0x0 \
> + }, \
> + }, \
> +}
> +
> +struct riscv_vendor_pmu_events {
> + unsigned long vendorid;
> + unsigned long archid;
> + unsigned long implid;
> + const struct riscv_pmu_event *hw_event_map;
> + const struct riscv_pmu_event (*cache_event_map)[PERF_COUNT_HW_CACHE_OP_MAX]
> + [PERF_COUNT_HW_CACHE_RESULT_MAX];
> +};
> +
> +#define RISCV_VENDOR_PMU_EVENTS(_vendorid, _archid, _implid, _hw_event_map, _cache_event_map) \
> + { .vendorid = _vendorid, .archid = _archid, .implid = _implid, \
> + .hw_event_map = _hw_event_map, .cache_event_map = _cache_event_map },
> +
> +static struct riscv_vendor_pmu_events pmu_vendor_events_table[] = {
> +};
> +
> +static const struct riscv_pmu_event *current_pmu_hw_event_map;
> +static const struct riscv_pmu_event (*current_pmu_cache_event_map)[PERF_COUNT_HW_CACHE_OP_MAX]
> + [PERF_COUNT_HW_CACHE_RESULT_MAX];
> +
> +static void __init rvpmu_vendor_register_events(void)
> +{
> + int cpu = raw_smp_processor_id();
> + unsigned long vendor_id = riscv_cached_mvendorid(cpu);
> + unsigned long impl_id = riscv_cached_mimpid(cpu);
> + unsigned long arch_id = riscv_cached_marchid(cpu);
> +
> + for (int i = 0; i < ARRAY_SIZE(pmu_vendor_events_table); i++) {
> + if (pmu_vendor_events_table[i].vendorid == vendor_id &&
> + pmu_vendor_events_table[i].implid == impl_id &&
> + pmu_vendor_events_table[i].archid == arch_id) {
> + current_pmu_hw_event_map = pmu_vendor_events_table[i].hw_event_map;
> + current_pmu_cache_event_map = pmu_vendor_events_table[i].cache_event_map;
> + break;
> + }
> + }
> +
> + if (!current_pmu_hw_event_map || !current_pmu_cache_event_map) {
> + pr_info("No default PMU events found\n");
> + }
> +}
> +
> static void rvpmu_sbi_check_event(struct sbi_pmu_event_data *edata)
> {
> struct sbiret ret;
> @@ -1670,8 +1736,10 @@ static int __init rvpmu_devinit(void)
> */
> if (riscv_isa_extension_available(NULL, SSCCFG) &&
> riscv_isa_extension_available(NULL, SMCDELEG) &&
> - riscv_isa_extension_available(NULL, SSCSRIND))
> + riscv_isa_extension_available(NULL, SSCSRIND)) {
> static_branch_enable(&riscv_pmu_cdeleg_available);
> + rvpmu_vendor_register_events();
> + }
>
> if (!(riscv_pmu_sbi_available_boot() || riscv_pmu_cdeleg_available_boot()))
> return 0;
More information about the linux-arm-kernel
mailing list