Linux Perf Users
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Atish Patra" <atish.patra@linux.dev>
Cc: linux-perf-users@vger.kernel.org, robh@kernel.org,
	conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v6 10/21] RISC-V: perf: Restructure the SBI PMU code
Date: Tue, 09 Jun 2026 06:18:38 +0000	[thread overview]
Message-ID: <20260609061839.70B9B1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260608-counter_delegation-v6-10-285b72ed65a9@meta.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [Critical] NULL pointer dereference when tearing down the PMU on error paths in probe.
- [High] Missing cleanup on error paths in rvpmu_device_probe() leads to Use-After-Free and resource leaks.
- [High] Broadcasting `SCOUNTEREN` updates to all CPUs in `mm_cpumask` leaks counter access to userspace.
--

commit 497e3337649afaedc330eca31dba2dda185d6179
Author: Atish Patra <atishp@rivosinc.com>

    RISC-V: perf: Restructure the SBI PMU code
    
    With Ssccfg/Smcdeleg, supervisor mode can program and access the hpmcounters
    and events directly, without the SBI PMU extension. The SBI PMU extension is
    still required for firmware counters. Restructure the existing SBI PMU code so
    the hpmcounter/event helpers can be shared between the SBI and the counter
    delegation paths that follow.

> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index 385af5e6e6d0d..7f21c16003f04 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c

[ ... ]

> @@ -1305,7 +1349,7 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu)
>  	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
>  }

[Severity: Critical]
This is a pre-existing issue, but does this code cause a NULL pointer
dereference on error paths?

In rvpmu_device_probe(), if an error occurs (such as perf_pmu_register(),
pmu_sbi_snapshot_alloc(), or cpuhp_state_add_instance() failing), the error
path jumps to out_unregister and calls riscv_pmu_destroy().

Because cpuhp_state_add_instance() either was not called yet, or failed and
did not hash the node, pmu->node.pprev is NULL. The function
cpuhp_state_remove_instance() does not check if the node is unhashed and
directly calls hlist_del(). This attempts to write to the previous node
pointer, which crashes the kernel with a NULL pointer dereference.

> -static void pmu_sbi_event_init(struct perf_event *event)
> +static void rvpmu_event_init(struct perf_event *event)

[ ... ]

> @@ -1347,14 +1391,14 @@ static void pmu_sbi_event_mapped(struct perf_event *event, struct mm_struct *mm)
>  	 * that it is possible to do so to avoid any race.
>  	 * And we must notify all cpus here because threads that currently run
>  	 * on other cpus will try to directly access the counter too without
> -	 * calling pmu_sbi_ctr_start.
> +	 * calling rvpmu_sbi_ctr_start.
>  	 */
>  	if (event->hw.flags & PERF_EVENT_FLAG_USER_ACCESS)
>  		on_each_cpu_mask(mm_cpumask(mm),
> -				 pmu_sbi_set_scounteren, (void *)event, 1);
> +				 rvpmu_set_scounteren, (void *)event, 1);
>  }

[Severity: High]
This isn't a bug introduced by this patch, but does broadcasting scounteren
updates to all CPUs leak counter access to userspace?

When a user-accessible event is mapped, rvpmu_set_scounteren is broadcast
across all CPUs where the process has threads running. This enables the
scounteren bit corresponding to event->hw.idx.

However, event->hw.idx is a dynamic, per-CPU hardware counter index allocated
only on the CPU where the event was scheduled. Broadcasting this index across
all CPUs in the mask grants userspace access to that specific hardware
counter slot on CPUs where the event is not running.

Could a thread on another CPU read from that counter slot, potentially leaking
the count of whatever unrelated perf event is active on that counter?

> -static void pmu_sbi_event_unmapped(struct perf_event *event, struct mm_struct *mm)
> +static void rvpmu_event_unmapped(struct perf_event *event, struct mm_struct *mm)

[ ... ]

> @@ -1419,7 +1463,7 @@ static const struct ctl_table sbi_pmu_sysctl_table[] = {
>  	},
>  };
>  
> -static int pmu_sbi_device_probe(struct platform_device *pdev)
> +static int rvpmu_device_probe(struct platform_device *pdev)
>  {
>  	struct riscv_pmu *pmu = NULL;
>  	int ret = -ENODEV;

[Severity: High]
This is a pre-existing issue, but does this probe function correctly clean
up resources on error paths?

If initialization fails after perf_pmu_register(), the code jumps to the
out_unregister label:

out_unregister:
	riscv_pmu_destroy(pmu);

out_free:
	kfree(pmu);
	return ret;

However, riscv_pmu_destroy() does not call perf_pmu_unregister(). This leaves
the core perf subsystem with a dangling pointer to the freed pmu structure,
which can lead to a use-after-free when the perf core attempts to access it.

Additionally, the per-CPU memory allocated for pmu->hw_events and the per-CPU
interrupts requested via request_percpu_irq() are never freed on these error
paths, resulting in resource leaks.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260608-counter_delegation-v6-0-285b72ed65a9@meta.com?part=10

  reply	other threads:[~2026-06-09  6:18 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09  6:01 [PATCH v6 00/21] Add Counter delegation ISA extension support Atish Patra
2026-06-09  6:01 ` [PATCH v6 01/21] RISC-V: Add Sxcsrind ISA extension CSR definitions Atish Patra
2026-06-09  6:01 ` [PATCH v6 02/21] RISC-V: Add Sxcsrind ISA extension definition and parsing Atish Patra
2026-06-09  6:01 ` [PATCH v6 03/21] dt-bindings: riscv: add Sxcsrind ISA extension description Atish Patra
2026-06-09  6:09   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 04/21] RISC-V: Define indirect CSR access helpers Atish Patra
2026-06-09  6:15   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 05/21] RISC-V: Add Smcntrpmf extension parsing Atish Patra
2026-06-09  6:01 ` [PATCH v6 06/21] dt-bindings: riscv: add Smcntrpmf ISA extension description Atish Patra
2026-06-09  6:09   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 07/21] RISC-V: Add Sscfg extension CSR definition Atish Patra
2026-06-09  6:01 ` [PATCH v6 08/21] RISC-V: Add Ssccfg/Smcdeleg ISA extension definition and parsing Atish Patra
2026-06-09  6:14   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 09/21] dt-bindings: riscv: add Counter delegation ISA extensions description Atish Patra
2026-06-09  6:12   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 10/21] RISC-V: perf: Restructure the SBI PMU code Atish Patra
2026-06-09  6:18   ` sashiko-bot [this message]
2026-06-09  6:01 ` [PATCH v6 11/21] RISC-V: perf: Modify the counter discovery mechanism Atish Patra
2026-06-09  6:17   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 12/21] RISC-V: perf: Add a mechanism to defined legacy event encoding Atish Patra
2026-06-09  6:16   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 13/21] RISC-V: perf: Implement supervisor counter delegation support Atish Patra
2026-06-09  6:23   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 14/21] RISC-V: perf: Skip PMU SBI extension when not implemented Atish Patra
2026-06-09  6:33   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 15/21] RISC-V: perf: Use config2/vendor table for event to counter mapping Atish Patra
2026-06-09  6:23   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 16/21] RISC-V: perf: Add legacy event encodings via sysfs Atish Patra
2026-06-09  6:21   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 17/21] RISC-V: perf: Add Qemu virt machine events Atish Patra
2026-06-09  6:22   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 18/21] tools/perf: Support event code for arch standard events Atish Patra
2026-06-09  6:18   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 19/21] tools/perf: Add RISC-V CounterIDMask event field Atish Patra
2026-06-09  6:01 ` [PATCH v6 20/21] TEST(do-not-upstream): fake qemu-virt PMU events for cdeleg counter-mask testing Atish Patra
2026-06-09  6:17   ` sashiko-bot
2026-06-09  6:01 ` [PATCH v6 21/21] TEST(do-not-upstream): fake qemu vendor JSON + mapfile entry for CounterIDMask path Atish Patra
2026-06-09  6:20   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260609061839.70B9B1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=atish.patra@linux.dev \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox