Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Rishikesh Donadkar" <r-donadkar@ti.com>
Cc: conor+dt@kernel.org, robh@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v13 17/17] media: ti: j721e-csi2rx: Support system suspend using pm_notifier
Date: Wed, 20 May 2026 13:14:56 +0000	[thread overview]
Message-ID: <20260520131456.DD9FE1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260520120022.539913-18-r-donadkar@ti.com>

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

New issues:
- [Critical] PM notifiers modify hardware and V4L2 state without holding the context mutex, allowing concurrent userspace ioctls to corrupt state or restart streams during system suspend.
- [Critical] Replacing `.suspend` / `.resume` callbacks entirely with PM notifiers breaks hybrid sleep (suspend-to-both).
- [High] The DMA drain operation in the suspend path is instantly terminated without waiting for completion, rendering it ineffective.
- [High] The PM notifier is unregistered too late during device unbinding, creating a race window for a Use-After-Free.
- [High] Lockless runtime PM status checks allow concurrent clock gating during MMIO access, risking a synchronous external abort.
- [Medium] DMA drains are unconditionally initiated even for already-stopped contexts, submitting descriptors that will never complete.

Pre-existing issues:
- [High] Calling `pm_runtime_set_suspended()` while runtime PM is active leaks DMA channels and violates PM API contracts.
--

commit cb8a02a3113637917c3f826385776d24c0186002
Author: Jai Luthra <jai.luthra@ideasonboard.com>

media: ti: j721e-csi2rx: Support system suspend using pm_notifier

As this device is the "orchestrator" for the rest of the media
pipeline, we need to stop all on-going streams before system suspend and
enable them back when the system wakes up from sleep.

> diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
> index d68b8d6ffeb19..21388284cbaab 100644
> --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
> +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
[ ... ]
> @@ -1544,6 +1545,124 @@ static int ti_csi2rx_runtime_resume(struct device *dev)
>  	return 0;
>  }
>  
> +static int ti_csi2rx_suspend(struct device *dev)
> +{
> +	struct ti_csi2rx_dev *csi = dev_get_drvdata(dev);
> +	enum ti_csi2rx_dma_state state;
> +	struct ti_csi2rx_ctx *ctx;
> +	struct ti_csi2rx_dma *dma;
> +	unsigned long flags = 0;
> +	int i, ret = 0;
> +
> +	/* If device was not in use we can simply suspend */
> +	if (pm_runtime_status_suspended(dev))
> +		return 0;

[Severity: Critical]
Since PM notifiers like PM_SUSPEND_PREPARE run before userspace tasks are
frozen, is there anything preventing userspace from calling VIDIOC_STREAMON
concurrently?

Because this function does not hold ctx->mutex or set a state flag, could
userspace restart the streams and DMA engine immediately after this suspend
notifier finishes, leaving active DMA transfers to memory when the system
actually enters sleep?

[Severity: High]
Can a concurrent userspace operation trigger a pm_runtime_put() and drop the
usage counter to zero while this PM notifier is executing?

Because the status is checked locklessly here without acquiring a runtime PM
reference, the device could runtime suspend and gate its clocks while this
notifier is actively writing to memory-mapped registers, which might cause a
synchronous external abort.

> +
> +	/*
> +	 * If device is running, assert the pixel reset to cleanly stop any
> +	 * on-going streams before we suspend.
> +	 */
> +	writel(0, csi->shim + SHIM_CNTL);
> +
> +	for (i = 0; i < csi->num_ctx; i++) {
> +		ctx = &csi->ctx[i];
> +		dma = &ctx->dma;
> +
> +		spin_lock_irqsave(&dma->lock, flags);
> +		state = dma->state;
> +		spin_unlock_irqrestore(&dma->lock, flags);
> +
> +		if (state != TI_CSI2RX_DMA_STOPPED) {
> +			/* Disable source */
> +			ret = v4l2_subdev_disable_streams(&csi->subdev,
> +							  TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx,
> +							  BIT(0));
> +			if (ret)
> +				dev_err(csi->dev, "Failed to stop subdev stream\n");
> +		}
> +
> +		/* Stop any on-going streams */
> +		writel(0, csi->shim + SHIM_DMACNTX(ctx->idx));
> +
> +		/* Drain DMA */
> +		ti_csi2rx_drain_dma(ctx);

[Severity: Medium]
Will this unconditionally submit a DMA drain even for contexts that are already
TI_CSI2RX_DMA_STOPPED?

If the DMA stream was already stopped, could this submit a read descriptor that
waits for hardware data that will never arrive?

> +
> +		/* Terminate DMA */
> +		ret = dmaengine_terminate_sync(ctx->dma.chan);

[Severity: High]
Does this instantly terminate the DMA drain operation submitted just above?

Since there is no wait for the drain to complete, the DMA channel is aborted
immediately, which defeats the purpose of draining the FIFO and leaves stale
data in the hardware.

> +		if (ret)
> +			dev_err(csi->dev, "Failed to stop DMA\n");
> +	}
> +
> +	return ret;
> +}
[ ... ]
> +static int ti_csi2rx_pm_notifier(struct notifier_block *nb,
> +				 unsigned long action, void *data)
> +{
> +	struct ti_csi2rx_dev *csi =
> +		container_of(nb, struct ti_csi2rx_dev, pm_notifier);
> +
> +	switch (action) {
> +	case PM_HIBERNATION_PREPARE:
> +	case PM_SUSPEND_PREPARE:
> +	case PM_RESTORE_PREPARE:
> +		ti_csi2rx_suspend(csi->dev);
> +		break;
> +	case PM_POST_SUSPEND:
> +	case PM_POST_HIBERNATION:
> +	case PM_POST_RESTORE:
> +		ti_csi2rx_resume(csi->dev);

[Severity: Critical]
Does replacing the dev_pm_ops suspend and resume callbacks with PM notifiers
break hybrid sleep (suspend-to-both)?

During hybrid sleep, the system creates a hibernation image, triggers the
PM_POST_HIBERNATION notifier which restarts the streams here, and then directly
transitions to S3 suspend without firing the PM_SUSPEND_PREPARE notifier again.

Because there is no suspend callback to notify the driver of the S3
transition, could the device be actively performing DMA to RAM while the system
goes to sleep?

> +		break;
> +	}
> +
> +	return NOTIFY_DONE;
> +}
[ ... ]
> @@ -1644,6 +1777,8 @@ static void ti_csi2rx_remove(struct platform_device *pdev)
>  		ti_csi2rx_cleanup_ctx(&csi->ctx[i]);

[Severity: High]
This is a pre-existing issue, but does calling pm_runtime_set_suspended()
earlier in this function cause ti_csi2rx_cleanup_ctx() to leak DMA channels?

By forcefully setting the status to suspended, ti_csi2rx_cleanup_ctx()
evaluates !pm_runtime_status_suspended(ctx->csi->dev) as false, causing the
driver to skip the dma_release_channel() calls.

>  
>  	ti_csi2rx_cleanup_notifier(csi);
> +	unregister_pm_notifier(&csi->pm_notifier);

[Severity: High]
Is there a race window here that could lead to a use-after-free?

Since unregister_pm_notifier() is called after ti_csi2rx_cleanup_ctx(), which
destroys V4L2 structures and releases DMA channels, if a system suspend is
triggered concurrently during this window, the PM notifier could execute
ti_csi2rx_suspend(). The suspend callback would then dereference ctx->dma.chan
and call dmaengine_terminate_sync() on a freed channel.

> +
>  	ti_csi2rx_cleanup_v4l2(csi);
>  	dma_free_coherent(csi->dev, csi->drain.len, csi->drain.vaddr,
>  			  csi->drain.paddr);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260520120022.539913-1-r-donadkar@ti.com?part=17

      parent reply	other threads:[~2026-05-20 13:14 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-20 12:00 [PATCH v13 00/17] media: cadence,ti: CSI2RX Multistream Support Rishikesh Donadkar
2026-05-20 12:00 ` [PATCH v13 01/17] media: ti: j721e-csi2rx: Remove word size alignment on frame width Rishikesh Donadkar
2026-05-20 12:27   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 02/17] dt-bindings: media: ti,j721e-csi2rx-shim: Support 32 dma chans Rishikesh Donadkar
2026-05-20 12:00 ` [PATCH v13 03/17] media: ti: j721e-csi2rx: separate out device and context Rishikesh Donadkar
2026-05-20 12:37   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 04/17] media: ti: j721e-csi2rx: prepare SHIM code for multiple contexts Rishikesh Donadkar
2026-05-20 12:00 ` [PATCH v13 05/17] media: ti: j721e-csi2rx: allocate DMA channel based on context index Rishikesh Donadkar
2026-05-20 12:32   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 06/17] media: ti: j721e-csi2rx: add a subdev for the core device Rishikesh Donadkar
2026-05-20 12:28   ` Sakari Ailus
2026-05-20 12:49   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 07/17] media: cadence: csi2rx: Move to .enable/disable_streams API Rishikesh Donadkar
2026-05-20 12:39   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 08/17] media: ti: j721e-csi2rx: get number of contexts from device tree Rishikesh Donadkar
2026-05-20 12:45   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 09/17] media: cadence: csi2rx: Add .get_frame_desc op Rishikesh Donadkar
2026-05-20 14:25   ` Jai Luthra
2026-05-20 12:00 ` [PATCH v13 10/17] media: ti: j721e-csi2rx: add support for processing virtual channels Rishikesh Donadkar
2026-05-20 12:44   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 11/17] media: cadence: csi2rx: add multistream support Rishikesh Donadkar
2026-05-20 12:58   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 12/17] media: ti: j721e-csi2rx: " Rishikesh Donadkar
2026-05-20 12:48   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 13/17] media: ti: j721e-csi2rx: Submit all available buffers Rishikesh Donadkar
2026-05-20 12:59   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 14/17] media: ti: j721e-csi2rx: Change the drain architecture for multistream Rishikesh Donadkar
2026-05-20 13:01   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 15/17] media: cadence: csi2rx: Support runtime PM Rishikesh Donadkar
2026-05-20 13:00   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 16/17] media: ti: j721e-csi2rx: Support runtime suspend Rishikesh Donadkar
2026-05-20 13:01   ` sashiko-bot
2026-05-20 12:00 ` [PATCH v13 17/17] media: ti: j721e-csi2rx: Support system suspend using pm_notifier Rishikesh Donadkar
2026-05-20 12:25   ` Sakari Ailus
2026-05-20 13:14   ` sashiko-bot [this message]

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=20260520131456.DD9FE1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=r-donadkar@ti.com \
    --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