All of lore.kernel.org
 help / color / mirror / Atom feed
From: Atish Patra <atish.patra@linux.dev>
To: sashiko-reviews@lists.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: Fri, 19 Jun 2026 17:17:16 -0700	[thread overview]
Message-ID: <e16f8195-c718-468d-a8a1-6abe66ea58b4@linux.dev> (raw)
In-Reply-To: <20260609061839.70B9B1F00893@smtp.kernel.org>


On 6/8/26 11:18 PM, sashiko-bot@kernel.org wrote:
> 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.

Good catch. Fixed in v7.

I will have a separate patch for these fixes.

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

It's a valid concern. Though it is very difficult to exploit to leak the 
counter values
through this approach as direct user access for programmable counters is 
a niche use case to begin with.

I think we can toggle the scounteren bit in add/delete path to avoid the 
leak. I will experiment
that idea and send a patch.

>> -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.
Nice catch. Fixed in v7.

  reply	other threads:[~2026-06-20  0:17 UTC|newest]

Thread overview: 75+ 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 ` 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   ` 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   ` 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:01   ` Atish Patra
2026-06-09  6:09   ` sashiko-bot
2026-06-19 23:39     ` Atish Patra
2026-06-09  6:01 ` [PATCH v6 04/21] RISC-V: Define indirect CSR access helpers Atish Patra
2026-06-09  6:01   ` Atish Patra
2026-06-09  6:15   ` sashiko-bot
2026-06-19 23:39     ` Atish Patra
2026-06-09  6:01 ` [PATCH v6 05/21] RISC-V: Add Smcntrpmf extension parsing Atish Patra
2026-06-09  6:01   ` 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:01   ` Atish Patra
2026-06-09  6:09   ` sashiko-bot
2026-06-19 23:40     ` Atish Patra
2026-06-09  6:01 ` [PATCH v6 07/21] RISC-V: Add Sscfg extension CSR definition Atish Patra
2026-06-09  6:01   ` 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:01   ` Atish Patra
2026-06-09  6:14   ` sashiko-bot
2026-06-19 23:44     ` Atish Patra
2026-06-19 23:44       ` Atish Patra
2026-06-09  6:01 ` [PATCH v6 09/21] dt-bindings: riscv: add Counter delegation ISA extensions description Atish Patra
2026-06-09  6:01   ` Atish Patra
2026-06-09  6:12   ` sashiko-bot
2026-06-19 23:49     ` Atish Patra
2026-06-09  6:01 ` [PATCH v6 10/21] RISC-V: perf: Restructure the SBI PMU code Atish Patra
2026-06-09  6:01   ` Atish Patra
2026-06-09  6:18   ` sashiko-bot
2026-06-20  0:17     ` Atish Patra [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:01   ` Atish Patra
2026-06-09  6:17   ` sashiko-bot
2026-06-20  0:31     ` Atish Patra
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:01   ` 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:01   ` Atish Patra
2026-06-09  6:23   ` sashiko-bot
2026-06-20 23:25     ` Atish Patra
2026-06-20 23:25       ` Atish Patra
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:01   ` Atish Patra
2026-06-09  6:33   ` sashiko-bot
2026-06-20 23:15     ` Atish Patra
2026-06-20 23:15       ` Atish Patra
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:01   ` 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:01   ` Atish Patra
2026-06-09  6:21   ` sashiko-bot
2026-06-20  0:35     ` Atish Patra
2026-06-09  6:01 ` [PATCH v6 17/21] RISC-V: perf: Add Qemu virt machine events Atish Patra
2026-06-09  6:01   ` Atish Patra
2026-06-09  6:22   ` sashiko-bot
2026-06-20  0:37     ` Atish Patra
2026-06-09  6:01 ` [PATCH v6 18/21] tools/perf: Support event code for arch standard events Atish Patra
2026-06-09  6:01   ` 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   ` 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:01   ` 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:01   ` Atish Patra
2026-06-09  6:20   ` sashiko-bot
2026-06-20  0:04     ` Atish Patra

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=e16f8195-c718-468d-a8a1-6abe66ea58b4@linux.dev \
    --to=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.