From: sashiko-bot@kernel.org
To: "Igor Paunovic" <royalnet026@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] accel/rocket: search every core slot when looking up a scheduler
Date: Sat, 05 Sep 2026 15:18:14 +0000 [thread overview]
Message-ID: <20260905151815.3BE7F1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260905150432.7477-1-royalnet026@gmail.com>
Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider:
New issues:
- [Critical] The patch introduces a compilation failure by referencing an undefined struct member `max_cores` in `struct rocket_device`.
Pre-existing issues:
- [Critical] Decrementing `rdev->num_cores` on core removal without array compaction corrupts core tracking, leading to dropped active cores, array overwrites on re-probe, and use-after-free.
- [Critical] Use-after-free of GPU scheduler because reset work is cancelled after scheduler teardown.
- [High] Unbinding a core leaves active clients with dangling scheduler entities, causing jobs to hang forever.
- [High] Missing NULL check for the `scheds` array allocation in `rocket_job_open`.
- [High] Incorrect teardown ordering in `rocket_core_fini` drops IOMMU and PM runtime states while the DRM scheduler and hardware are still active.
- [High] The IOVA allocator allocates up to 40 bits, but the hardware register and UAPI strictly support 32-bit addresses for command buffers.
- [High] The shared IRQ handler reads a hardware register without verifying that the device power domain and clocks are enabled.
- [High] The IRQ handler leaks a reference to the IOMMU group on every completed job.
--
commit 7e2bfdb7bd20f1e79747c6f4d972e6308a291eb7
Author: Igor Paunovic <royalnet026@gmail.com>
accel/rocket: search every core slot when looking up a scheduler
This patch attempts to fix a bug where sched_to_core() fails to find a core
after intermediate cores are unbound. It changes the iteration bound to
search all allocated core slots instead of just up to num_cores.
Closes: https://lore.kernel.org/dri-devel/apwUewaRnoTNXHCt@rock-5b-plus/
> diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
> index 3141f210fcd1b..a6c24dfe0563a 100644
> --- a/drivers/accel/rocket/rocket_job.c
> +++ b/drivers/accel/rocket/rocket_job.c
> @@ -283,7 +283,7 @@ static struct rocket_core *sched_to_core(struct rocket_device *rdev,
> {
> unsigned int core;
>
> - for (core = 0; core < rdev->num_cores; core++) {
> + for (core = 0; core < rdev->max_cores; core++) {
[Severity: Critical]
Does struct rocket_device actually contain the max_cores field? The commit
message mentions this approach, but I can't find max_cores defined in struct
rocket_device. Will this cause a build failure here?
> if (&rdev->cores[core].sched == sched)
> return &rdev->cores[core];
> }
[Severity: Critical]
This isn't a bug introduced by this patch, but when a core is removed in
rocket_remove():
drivers/accel/rocket/rocket_drv.c:rocket_remove() {
...
rdev->num_cores--;
...
}
The active core count is decremented blindly without shifting the remaining
active cores into the resulting gap. Does this corrupt the core tracking,
leaving surviving active cores orphaned and vulnerable to being overwritten
if rocket_probe() reuses the shrunk num_cores as an index?
[Severity: High]
This is a pre-existing issue, but rocket_core_fini() initiates the teardown
of the drm scheduler:
drivers/accel/rocket/rocket_core.c:rocket_core_fini() {
...
rocket_job_fini(core);
...
}
However, the client retains the scheduler entity pointing to this destroyed
scheduler from when it was initialized:
drivers/accel/rocket/rocket_job.c:rocket_job_open() {
...
ret = drm_sched_entity_init(&rocket_priv->sched_entity,
DRM_SCHED_PRIORITY_NORMAL,
scheds,
rdev->num_cores, NULL);
...
}
If a client keeps the DRM file descriptor open while a core is unbound and
submits a job, will those jobs permanently hang waiting for the destroyed
scheduler?
[Severity: High]
This isn't a bug introduced by this patch, but rocket_job_open() allocates
the scheds array:
drivers/accel/rocket/rocket_job.c:rocket_job_open() {
...
struct drm_gpu_scheduler **scheds = kmalloc_objs(*scheds,
rdev->num_cores);
unsigned int core;
int ret;
for (core = 0; core < rdev->num_cores; core++)
scheds[core] = &rdev->cores[core].sched;
...
}
If the allocation fails under memory pressure and returns NULL, won't the
immediate loop dereference lead to a kernel oops?
[Severity: Critical]
This is a pre-existing issue, but when cleaning up a job:
drivers/accel/rocket/rocket_job.c:rocket_job_fini() {
...
drm_sched_fini(&core->sched);
cancel_work_sync(&core->reset.work);
...
}
The scheduler is destroyed before its associated asynchronous reset work is
cancelled. If a job times out concurrently and the reset work executes,
could it result in a use-after-free when attempting to operate on the
already freed scheduler?
[Severity: High]
This is a pre-existing issue, but rocket_core_fini() drops IOMMU and PM
runtime states early:
drivers/accel/rocket/rocket_core.c:rocket_core_fini() {
...
pm_runtime_disable(core->dev);
iommu_group_put(core->iommu_group);
core->iommu_group = NULL;
rocket_job_fini(core);
...
}
Since rocket_job_fini() waits on or cancels the DRM scheduler, does
releasing the IOMMU group and disabling PM runtime beforehand leave active
hardware DMAing into unmapped memory or accessing disabled PM resources?
[Severity: High]
This isn't a bug introduced by this patch, but rocket_ioctl_create_bo()
allocates up to a 40-bit IOVA:
drivers/accel/rocket/rocket_gem.c:rocket_ioctl_create_bo() {
...
args->dma_address = rkt_obj->mm.start;
...
}
Which is later written back to the NPU's hardware register via the 32-bit
regcmd field:
drivers/accel/rocket/rocket_job.c:rocket_job_hw_submit() {
...
rocket_pc_writel(core, BASE_ADDRESS, task->regcmd);
...
}
If the buffer IOVA allocation exceeds the 4GB boundary, does this result in
silent address truncation and subsequent IOMMU faults when the hardware
accesses unintended physical memory?
[Severity: High]
This isn't a bug introduced by this patch, but the shared IRQ handler reads
a hardware register unconditionally:
drivers/accel/rocket/rocket_job.c:rocket_job_irq_handler() {
...
u32 raw_status = rocket_pc_readl(core, INTERRUPT_RAW_STATUS);
...
}
If another device sharing the same IRQF_SHARED interrupt line fires while
the NPU is idle and runtime-suspended, will reading this register without
verifying the device power domain cause a synchronous external abort?
[Severity: High]
This is a pre-existing issue, but the IRQ handler gets an IOMMU group
reference:
drivers/accel/rocket/rocket_job.c:rocket_job_handle_irq() {
...
iommu_detach_group(NULL, iommu_group_get(core->dev));
...
}
Since iommu_group_put() is never called to balance this, does this leak a
reference to the IOMMU group every time an in-flight job completes?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260905150432.7477-1-royalnet026@gmail.com?part=1
next prev parent reply other threads:[~2026-09-05 15:18 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-05 15:04 [PATCH] accel/rocket: search every core slot when looking up a scheduler Igor Paunovic
2026-09-05 15:04 ` Igor Paunovic
2026-09-05 15:18 ` sashiko-bot [this message]
2026-09-05 15:27 ` Igor Paunovic
2026-09-05 15:27 ` Igor Paunovic
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=20260905151815.3BE7F1F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=royalnet026@gmail.com \
--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.