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

From: Anup Patel
Date: Mon Jun 20 2022 - 08:01:16 EST


On Sun, Jun 19, 2022 at 4:41 PM Nikita Shubin <nikita.shubin@xxxxxxxxxxx> wrote:
>
> From: Nikita Shubin <n.shubin@xxxxxxxxx>
>
> 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@xxxxxxxxxxxxxxxxxx>
> Signed-off-by: Nikita Shubin <n.shubin@xxxxxxxxx>

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@xxxxxxxxxxxxxxxx/

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
>