Linux kernel and device drivers for NXP i.MX platforms
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: Frank.Li@oss.nxp.com
Cc: imx@lists.linux.dev, dmaengine@vger.kernel.org, vkoul@kernel.org,
	ntb@lists.linux.dev, Frank.Li@kernel.org
Subject: Re: [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan
Date: Wed, 23 Sep 2026 16:32:53 +0000	[thread overview]
Message-ID: <20260923163254.156D71F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260923-dmaengine_prep_dma_pq-v2-8-32ed65b8a9b4@nxp.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] dmaengine: NULL pointer dereference in mv_xor self-tests due to uninitialized chan_dev
- [High] dmaengine: DMA device mismatch for mapping and unmapping in NTB and mv_xor drivers
--

commit ddb68198d418b187ac31a8ab8dc1644ae5ebab5d
Author: Frank Li <Frank.Li@nxp.com>

dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan

Replace the struct device *dev argument with struct dma_chan *chan so callers
do not need to reach into the dma_device internals to obtain the device
pointer. The implementation now derives the device via
dmaengine_get_dma_device(chan), which correctly handles the per-channel
IOMMU mapping case.

> diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
> index c4e0dce3ca64e..dec01b6264d7a 100644
> --- a/drivers/dma/mv_xor.c
> +++ b/drivers/dma/mv_xor.c
> @@ -794,7 +794,7 @@ static int mv_chan_memcpy_self_test(struct mv_xor_chan *mv_chan)
>  		goto out;
>  	}
>  
> -	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, 2, GFP_KERNEL);
> +	unmap = dmaengine_get_unmap_data(dma_chan, 2, GFP_KERNEL);

[Severity: High]
Does this cause a NULL pointer dereference on initialization?

The driver mv_xor runs self-tests like mv_chan_memcpy_self_test() during
probe before calling dma_async_device_register().

Because this patch changes dmaengine_get_unmap_data() to call
dmaengine_get_dma_device(chan), it unconditionally dereferences
chan->chan_dev. Since chan->chan_dev is allocated inside
dma_async_device_register(), it is NULL when the self-tests run.

Could this also lead to a device mismatch for DMA mapping?

Later in mv_chan_memcpy_self_test(), dma_map_page() still explicitly uses
dma_chan->device->dev instead of tracking with the new unmap device logic:

drivers/dma/mv_xor.c:mv_chan_memcpy_self_test() {
    ...
	src_dma = dma_map_page(dma_chan->device->dev, virt_to_page(src),
			       offset_in_page(src), PAGE_SIZE,
			       DMA_TO_DEVICE);
    ...
}

Mapping memory using one device pointer and unmapping it via a different one
violates the DMA API contract, which can lead to IOMMU faults and memory
leaks on platforms where the channel uses a separate device.

> @@ -927,7 +927,7 @@ mv_chan_xor_self_test(struct mv_xor_chan *mv_chan)
>  		goto out;
>  	}
>  
> -	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, src_count + 1,
> +	unmap = dmaengine_get_unmap_data(dma_chan, src_count + 1,
>  					 GFP_KERNEL);

[Severity: High]
Will this also trigger the same NULL pointer dereference here since it
runs during probe before registration?

It also has the same mapping mismatch issue where dma_map_page() explicitly
calls out dma_chan->device->dev instead of using the new unmap device logic.

[ ... ]

> diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
> index f9caa1a653c5b..e1cb55890d72b 100644
> --- a/drivers/ntb/ntb_transport.c
> +++ b/drivers/ntb/ntb_transport.c
> @@ -1532,7 +1532,7 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset)
>  	if (!is_dma_copy_aligned(device, pay_off, buff_off, len))
>  		goto err;
>  
> -	unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOWAIT);
> +	unmap = dmaengine_get_unmap_data(chan, 2, GFP_NOWAIT);

[Severity: High]
Is there a device mismatch for DMA mapping here as well?

While unmap now uses dmaengine_get_dma_device(chan), ntb_async_rx_submit()
still explicitly maps memory using the parent device:

drivers/ntb/ntb_transport.c:ntb_async_rx_submit() {
    ...
	unmap->addr[0] = dma_map_phys(device->dev, virt_to_phys(offset),
				      len, DMA_TO_DEVICE, 0);
    ...
}

This mismatch between the mapping device and the unmapping device can lead
to IOMMU faults and memory leaks.

> @@ -1872,7 +1872,7 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
>  	if (!is_dma_copy_aligned(device, buff_off, dest_off, len))
>  		goto err;
>  
> -	unmap = dmaengine_get_unmap_data(device->dev, 1, GFP_NOWAIT);
> +	unmap = dmaengine_get_unmap_data(chan, 1, GFP_NOWAIT);

[Severity: High]
Does this suffer from the same mapping mismatch?

The dma_map_phys() call just below this still maps memory using the
parent device (device->dev).

[ ... ]

> diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
> index dfd175f79e8f0..5fea36432ba92 100644
> --- a/drivers/ntb/test/ntb_perf.c
> +++ b/drivers/ntb/test/ntb_perf.c
> @@ -809,7 +809,7 @@ static int perf_copy_chunk(struct perf_thread *pthr,
>  	dst_vaddr = dst;
>  	dst_dma_addr = peer->dma_dst_addr + (dst_vaddr - vbase);
>  
> -	unmap = dmaengine_get_unmap_data(dma_dev, 1, GFP_NOWAIT);
> +	unmap = dmaengine_get_unmap_data(pthr->dma_chan, 1, GFP_NOWAIT);

[Severity: High]
Might this also create a device mismatch for DMA mapping?

In perf_copy_chunk(), dma_dev is locally initialized to
pthr->dma_chan->device->dev, and used for dma_map_page():

drivers/ntb/test/ntb_perf.c:perf_copy_chunk() {
    ...
	unmap->addr[0] = dma_map_page(dma_dev, virt_to_page(src),
		offset_in_page(src), len, DMA_TO_DEVICE);
    ...
}

This maps memory using the parent device but unmaps it using the new
per-channel unmap device logic.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260923-dmaengine_prep_dma_pq-v2-0-32ed65b8a9b4@nxp.com?part=8

  reply	other threads:[~2026-09-23 16:32 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
2026-09-23 16:19 ` [PATCH v2 01/12] async_tx: replace direct ->device_prep*() calls with standard DMA engine API Frank.Li
2026-09-23 16:19 ` [PATCH v2 02/12] async_tx: use dmaengine_get_dma_device() instead of chan->device->dev Frank.Li
2026-09-23 16:19 ` [PATCH v2 03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API Frank.Li
2026-09-23 16:26   ` sashiko-bot
2026-09-23 16:19 ` [PATCH v2 04/12] dmaengine: add dmaengine_is_*_aligned() helpers for DMA consumers Frank.Li
2026-09-23 16:19 ` [PATCH v2 05/12] dmaengine: add dmaengine_get_copy_align() and related alignment getter helpers Frank.Li
2026-09-23 16:19 ` [PATCH v2 06/12] dmaengine: add dmaengine_get_cap_mask() and dmaengine_has_cap() helpers Frank.Li
2026-09-23 16:19 ` [PATCH v2 07/12] dmaengine: add dmaengine_get_max_xor() helper Frank.Li
2026-09-23 16:19 ` [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan Frank.Li
2026-09-23 16:32   ` sashiko-bot [this message]
2026-09-23 16:19 ` [PATCH v2 09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan * Frank.Li
2026-09-23 16:28   ` sashiko-bot
2026-09-23 16:19 ` [PATCH v2 10/12] async_tx: use dmaengine_prep_dma_(pq|pq_val|interrupt|xor) instead of direct callback Frank.Li
2026-09-23 16:19 ` [PATCH v2 11/12] async_tx: convert to dmaengine_is_*_aligned() helpers Frank.Li
2026-09-23 16:19 ` [PATCH v2 12/12] async_tx: replace open-coded cap_mask accesses with dmaengine_has_cap() Frank.Li
2026-10-09 10:14 ` [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Vinod Koul

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=20260923163254.156D71F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=Frank.Li@oss.nxp.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=imx@lists.linux.dev \
    --cc=ntb@lists.linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    /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