dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: zhaoguohan@kylinos.cn
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 1/3] accel/ethosu: clean up resources on probe failure
Date: Thu, 16 Jul 2026 08:39:43 +0000	[thread overview]
Message-ID: <20260716083944.14F141F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260716082530.1023538-2-zhaoguohan@kylinos.cn>

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

Pre-existing issues:
- [High] The shared IRQ handler accesses hardware registers directly without ensuring the device is actively powered, leading to potential bus faults or spurious interrupts.
- [High] The runtime suspend callback powers down hardware clocks without synchronizing against in-flight shared IRQ handlers.
- [High] Device removal does not synchronously suspend the hardware, leaking the active state and leaving device clocks permanently enabled.
- [High] Calling `drm_sched_fini()` after `drm_sched_init()` fails causes a kernel panic due to uninitialized waitqueues.
- [High] The driver ignores the return value of `dma_set_mask_and_coherent()`, risking silent DMA address truncation.
- [High] The return value of `ethosu_sram_init()` is ignored, which can lead to the NPU accessing an unallocated or invalid SRAM DMA address.
- [High] The devm-managed shared IRQ handler can outlive the DRM scheduler during probe failure and module removal.
- [High] Driver removal does not stop active hardware jobs.
- [High] The `done_fence` allocation is leaked if `ethosu_ioctl_submit_job()` encounters an error during job initialization.
- [High] Calling `dma_fence_put()` on a fence that skipped initialization causes a refcount underflow warning and leaks memory.
--

--- Patch [1]: [PATCH 1/3] accel/ethosu: clean up resources on probe failure ---
commit 78b823f053992db797e336339fffb6f86bafc10f
Author: GuoHan Zhao <zhaoguohan@kylinos.cn>

accel/ethosu: clean up resources on probe failure

ethosu_job_init() creates a scheduler before ethosu_init() and
drm_dev_register(). Errors from either later step return directly, leaving
the scheduler workqueue allocated. A drm_dev_register() failure also leaves
the optional SRAM allocation behind.

Link: https://sashiko.dev/#/patchset/20260716065219.931088-1-zhaoguohan@kylinos.cn?part=1

> diff --git a/drivers/accel/ethosu/ethosu_drv.c b/drivers/accel/ethosu/ethosu_drv.c
> index ed9c748a54ad5..d1153b15ca3ee 100644
> --- a/drivers/accel/ethosu/ethosu_drv.c
> +++ b/drivers/accel/ethosu/ethosu_drv.c

[ ... ]

> @@ -353,13 +366,21 @@ static int ethosu_probe(struct platform_device *pdev)
>  
>  	ret = ethosu_init(ethosudev);

[Severity: High]
This is a pre-existing issue, but is the return value of ethosu_sram_init()
checked during ethosu_init()?

If the SRAM pool allocation fails, ethosudev->npu_info.sram_size still
reflects the full pool size, but ethosudev->sramphys remains zero. Can this
cause the NPU to attempt access to unmapped or zero physical memory when
a job utilizing SRAM is submitted?

>  	if (ret)
> -		return ret;
> +		goto err_job_fini;
>  
>  	ret = drm_dev_register(&ethosudev->base, 0);

[Severity: High]
This is a pre-existing issue, but does this code ignore the return value of
dma_set_mask_and_coherent() which is called earlier in ethosu_probe()?

If the platform only supports 32-bit DMA and the call fails, the default
32-bit mask is retained. The DRM core and driver might proceed assuming
40-bit DMA is active, handing the NPU physical addresses greater than 4 GB,
which could lead to silent DMA address truncation and memory corruption.

>  	if (ret)
> -		pm_runtime_dont_use_autosuspend(ethosudev->base.dev);
> +		goto err_runtime_suspend;

[ ... ]

> @@ -369,9 +390,7 @@ static void ethosu_remove(struct platform_device *pdev)
>  
>  	drm_dev_unregister(&ethosudev->base);
>  	ethosu_job_fini(ethosudev);

[Severity: High]
This is a pre-existing issue, but does ethosu_remove() fail to synchronously
suspend the hardware?

The driver unregisters the DRM device but never explicitly suspends the
hardware (e.g., via pm_runtime_put_sync_suspend()). Devres cleanup only
calls pm_runtime_disable(), which cancels pending autosuspends but does not
invoke the suspend callback if the device is active. Can this leave the
device hardware and clocks permanently powered on after module unload?

[Severity: High]
This is a pre-existing issue, but can the devm-managed shared IRQ handler
outlive the DRM scheduler here?

The IRQ is requested using devm_request_threaded_irq(). During ethosu_remove()
(and on probe failure), the driver explicitly calls ethosu_job_fini(), which
destroys the DRM scheduler.

Because the IRQ is managed by devm, it remains fully active until the
remove function completes. If an interrupt fires in this window, could
ethosu_job_irq_handler() execute and access the destroyed dev->sched or
dev->in_flight_job structures, leading to a use-after-free?

[Severity: High]
This is a pre-existing issue, but does device removal ensure active hardware
jobs are stopped?

ethosu_remove() destroys the software state but fails to halt the physical
NPU hardware (e.g., via ethosu_reset() or a synchronous suspend).

If an active job is executing during driver unload, will the NPU continue
running and asynchronously write to memory that has already been freed?

> -	if (ethosudev->sram)
> -		gen_pool_free(ethosudev->srampool, (unsigned long)ethosudev->sram,
> -			      ethosudev->npu_info.sram_size);
> +	ethosu_sram_fini(ethosudev);
>  }

[Severity: High]
This is a pre-existing issue, but can the shared IRQ handler access
hardware registers while the device is suspended?

drivers/accel/ethosu/ethosu_job.c:ethosu_job_irq_handler() {
    ...
    u32 status = readl_relaxed(dev->regs + NPU_REG_STATUS);
    ...
}

If the Ethos-U device is suspended via runtime PM and another device on
the same IRQ line triggers an interrupt, ethosu_job_irq_handler() runs
unconditionally. Reading from a powered-down block typically returns
0xffffffff or triggers an external bus fault.

Should the handler use pm_runtime_get_if_active() before accessing
hardware registers to prevent spurious interrupts or kernel panics?

[Severity: High]
This is a pre-existing issue, but does the runtime suspend callback
safely synchronize against in-flight shared IRQ handlers?

drivers/accel/ethosu/ethosu_drv.c:ethosu_device_suspend() {
    ...
    clk_bulk_disable_unprepare(ethosudev->num_clks, ethosudev->clks);
    ...
}

The driver requests an interrupt with IRQF_SHARED. If an interrupt from
a shared device fires concurrently right before the clocks are disabled,
could the irq handler be mid-execution reading registers just as the clocks
are cut?

Should the suspend callback call synchronize_irq() before powering
down hardware clocks?

[Severity: High]
This is a pre-existing issue, but does the error handling path for
drm_sched_init() cause a panic if it fails?

drivers/accel/ethosu/ethosu_job.c:ethosu_job_init() {
    ...
    ret = drm_sched_init(&edev->sched, &args);
    if (ret) {
        dev_err(dev, "Failed to create scheduler: %d\n", ret);
        goto err_sched;
    }
    return 0;

err_sched:
    drm_sched_fini(&edev->sched);
    return ret;
}

If drm_sched_init() fails, it cleans up its own state. The error path
then branches to err_sched and calls drm_sched_fini() on the partially
initialized scheduler.

Because the waitqueue head was either destroyed or never initialized,
its list pointers are NULL. Will drm_sched_fini() invoking
wake_up_all(&sched->job_scheduled) cause an immediate crash?

[Severity: High]
This is a pre-existing issue, but does ethosu_ioctl_submit_job() leak
the done_fence allocation on error paths?

drivers/accel/ethosu/ethosu_job.c:ethosu_ioctl_submit_job() {
    ...
    ejob->done_fence = kzalloc_obj(*ejob->done_fence);
    ...
}

If a subsequent operation fails (e.g., drm_gem_object_lookup returns NULL),
the code branches to out_cleanup_job and calls ethosu_job_err_cleanup().

drivers/accel/ethosu/ethosu_job.c:ethosu_job_err_cleanup() {
    ...
    drm_gem_object_put(job->cmd_bo);
    kfree(job);
}

This cleanup function drops BO references and frees the job object, but
appears to forget freeing the job->done_fence pointer. Could an unprivileged
user repeatedly trigger this leak by passing invalid BO handles?

[Severity: High]
This is a pre-existing issue, but can calling dma_fence_put() on a fence
that skipped initialization cause a refcount underflow?

drivers/accel/ethosu/ethosu_job.c:ethosu_job_run() {
    ...
    if (unlikely(job->base.s_fence->finished.error))
        return NULL;
    ...
}

If a job is aborted before it runs, ethosu_job_run() returns NULL early
and skips calling dma_fence_init() on job->done_fence.

Later, the DRM scheduler destroys the job:

drivers/accel/ethosu/ethosu_job.c:ethosu_job_cleanup() {
    ...
    dma_fence_put(job->done_fence);
    ...
}

Because the fence was only zero-allocated and never initialized, its
refcount is 0. Will kref_put() underflow, print a warning, and abort
the release, permanently leaking the memory?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716082530.1023538-1-zhaoguohan@kylinos.cn?part=1

  reply	other threads:[~2026-07-16  8:39 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-16  8:25 [PATCH 0/3] accel/ethosu: fix probe and job cleanup errors zhaoguohan
2026-07-16  8:25 ` [PATCH 1/3] accel/ethosu: clean up resources on probe failure zhaoguohan
2026-07-16  8:39   ` sashiko-bot [this message]
2026-07-16  8:25 ` [PATCH 2/3] accel/ethosu: propagate SRAM initialization errors zhaoguohan
2026-07-16  8:41   ` sashiko-bot
2026-07-16  8:25 ` [PATCH 3/3] accel/ethosu: fix job completion fence cleanup zhaoguohan
2026-07-16  8:39   ` 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=20260716083944.14F141F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=zhaoguohan@kylinos.cn \
    /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