[PATCH v4 1/1] RISC-V: Create unique identification for SoC PMU

Anup Patel apatel at ventanamicro.com
Mon Jun 20 05:00:58 PDT 2022


On Sun, Jun 19, 2022 at 4:41 PM Nikita Shubin <nikita.shubin at maquefel.me> wrote:
>
> From: Nikita Shubin <n.shubin at yadro.com>
>
> Provide RISC-V SBI PMU id to distinguish different cores or SoCs via
> "devices/platform/riscv-pmu/id" sysfs entry.
>
> The identification is generated as string of marchid, mimpid, mvendorid
> in hex format separated by coma - "0x70032,0x70032,0x0".
>
> The CSRs are detailed in the RISC-V privileged spec [1].
> [1] https://github.com/riscv/riscv-isa-manual
>
> Inspired-by: João Mário Domingos <joao.mario at tecnico.ulisboa.pt>
> Signed-off-by: Nikita Shubin <n.shubin at yadro.com>

The mvendorid, marchid, and mimpid can be useful to apps other than
perf tool.

I have tried to extend /proc/cpuinfo with this information which can be
parsed by perf tool:
https://lore.kernel.org/all/20220620115549.1529597-1-apatel@ventanamicro.com/

Regards,
Anup

> ---
> v3->v4:
> - use string for pmuid
> - rename pmu_sbi_id_show to id_show
> - fix error print message in id_show
> - fix DEVICE_ATTR to use octal permissions
> ---
>  arch/riscv/kernel/sbi.c        |  3 +++
>  drivers/perf/riscv_pmu_sbi.c   | 41 ++++++++++++++++++++++++++++++++++
>  include/linux/perf/riscv_pmu.h |  1 +
>  3 files changed, 45 insertions(+)
>
> diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
> index 775d3322b422..50dd9b6ecc9e 100644
> --- a/arch/riscv/kernel/sbi.c
> +++ b/arch/riscv/kernel/sbi.c
> @@ -627,16 +627,19 @@ long sbi_get_mvendorid(void)
>  {
>         return __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID);
>  }
> +EXPORT_SYMBOL(sbi_get_mvendorid);
>
>  long sbi_get_marchid(void)
>  {
>         return __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID);
>  }
> +EXPORT_SYMBOL(sbi_get_marchid);
>
>  long sbi_get_mimpid(void)
>  {
>         return __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID);
>  }
> +EXPORT_SYMBOL(sbi_get_mimpid);
>
>  static void sbi_send_cpumask_ipi(const struct cpumask *target)
>  {
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index dca3537a8dcc..be812f855617 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -693,6 +693,28 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde
>         return 0;
>  }
>
> +static ssize_t id_show(struct device *dev,
> +                               struct device_attribute *attr, char *buf)
> +{
> +       int len;
> +       struct riscv_pmu *pmu = container_of(dev_get_drvdata(dev), struct riscv_pmu, pmu);
> +
> +       len = sprintf(buf, "%s\n", pmu->pmuid);
> +       if (len <= 0)
> +               dev_err(dev, "invalid sprintf len: %d\n", len);
> +
> +       return len;
> +}
> +
> +static DEVICE_ATTR(id, 0644, id_show, NULL);
> +
> +static struct attribute *pmu_sbi_attrs[] = {
> +       &dev_attr_id.attr,
> +       NULL
> +};
> +
> +ATTRIBUTE_GROUPS(pmu_sbi);
> +
>  static int pmu_sbi_device_probe(struct platform_device *pdev)
>  {
>         struct riscv_pmu *pmu = NULL;
> @@ -714,6 +736,14 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
>         if (pmu_sbi_get_ctrinfo(num_counters))
>                 goto out_free;
>
> +       /* fill pmuid */
> +       pmu->pmuid = kasprintf(GFP_KERNEL, "0x%lx,0x%lx,0x%lx",
> +                              sbi_get_marchid(),
> +                              sbi_get_mimpid(),
> +                              sbi_get_mvendorid());
> +       if (!pmu->pmuid)
> +               goto out_free_pmuid;
> +
>         ret = pmu_sbi_setup_irqs(pmu, pdev);
>         if (ret < 0) {
>                 pr_info("Perf sampling/filtering is not supported as sscof extension is not available\n");
> @@ -739,8 +769,19 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> +       ret = sysfs_create_group(&pdev->dev.kobj, &pmu_sbi_group);
> +       if (ret) {
> +               dev_err(&pdev->dev, "sysfs creation failed\n");
> +               return ret;
> +       }
> +
> +       pdev->dev.groups = pmu_sbi_groups;
> +       dev_set_drvdata(&pdev->dev, pmu);
> +
>         return 0;
>
> +out_free_pmuid:
> +       kfree(pmu->pmuid);
>  out_free:
>         kfree(pmu);
>         return ret;
> diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h
> index 46f9b6fe306e..cf3557b77fb8 100644
> --- a/include/linux/perf/riscv_pmu.h
> +++ b/include/linux/perf/riscv_pmu.h
> @@ -42,6 +42,7 @@ struct cpu_hw_events {
>  struct riscv_pmu {
>         struct pmu      pmu;
>         char            *name;
> +       char            *pmuid;
>
>         irqreturn_t     (*handle_irq)(int irq_num, void *dev);
>
> --
> 2.35.1
>



More information about the linux-riscv mailing list