<feed xmlns='http://www.w3.org/2005/Atom'>
<title>laptop-kernel/drivers/dma, branch master</title>
<subtitle>Linux kernel tree for laptop</subtitle>
<id>https://git.zx2c4.com/laptop-kernel/atom/drivers/dma?h=master</id>
<link rel='self' href='https://git.zx2c4.com/laptop-kernel/atom/drivers/dma?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/'/>
<updated>2026-09-20T17:45:22Z</updated>
<entry>
<title>Merge tag 'dmaengine-fix-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine</title>
<updated>2026-09-20T17:45:22Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2026-09-20T17:45:22Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=a10a019dd4c7c57bef6b8dda962c8881ad220af2'/>
<id>urn:sha1:a10a019dd4c7c57bef6b8dda962c8881ad220af2</id>
<content type='text'>
Pull dmaengine fixes from Vinod Koul:

 - A couple of fixes in core around dma_chan_put() for kref underflow,
   use-after-free and waiting for rcu readers for dma devices

 - mmp sg length and wrong extended DRCMR base for SpacemiT K3

 - hardware buffer descriptor chain fix for xilinx dma

 - sun6i fixes for status behaviour and dma position registers

 - runtime pm reference leak fix for sprd driver

* tag 'dmaengine-fix-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine:
  dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg()
  dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA
  dmaengine: pxa: fix double counting of the hw descriptors
  dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status
  dmaengine: sun6i: fix non-atomic read of DMA position registers
  dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order
  dmaengine: wait for RCU readers before releasing dma_device
  dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel()
  dmaengine: Fix device kref underflow in dma_chan_put()
  dmaengine: add dma_device_get() helper
  dmaengine: sprd: Fix runtime PM reference leak in probe
  dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn()
  dmaengine: mmp_pdma: fix wrong extended DRCMR base for SpacemiT K3
</content>
</entry>
<entry>
<title>dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg()</title>
<updated>2026-09-15T16:27:40Z</updated>
<author>
<name>Baineng Shou</name>
<email>shoubaineng@gmail.com</email>
</author>
<published>2026-09-10T02:16:52Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=075bc7b1d3dde5ed43fbaabbc1a69f09b7fc3a47'/>
<id>urn:sha1:075bc7b1d3dde5ed43fbaabbc1a69f09b7fc3a47</id>
<content type='text'>
In mmp_pdma_prep_slave_sg(), for_each_sg() iterates the scatterlist
putting each entry into 'sg', but the entry length is read from 'sgl'
(the list head) instead of 'sg' (the current entry):

    for_each_sg(sgl, sg, sg_len, i) {
        addr = sg_dma_address(sg);
        avail = sg_dma_len(sgl);   /* should be 'sg' */

Consequently 'avail' is always the length of the first entry. For
multi-sg lists this causes out-of-bounds reads when a later entry is
shorter than the first, and silent data loss when it is longer.
Single-sg or uniformly-sized lists happen to mask the issue.

Fixes: c8acd6aa6bed3 ("dmaengine: mmp-pdma support")
Signed-off-by: Baineng Shou &lt;shoubaineng@gmail.com&gt;
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Link: https://patch.msgid.link/20260910021652.1296640-1-shoubaineng@gmail.com
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA</title>
<updated>2026-09-10T12:48:41Z</updated>
<author>
<name>Alex Bereza</name>
<email>alex@bereza.email</email>
</author>
<published>2026-08-18T07:36:29Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=7ed1e3070c9b4bbd67d5519e14711038dd53ab13'/>
<id>urn:sha1:7ed1e3070c9b4bbd67d5519e14711038dd53ab13</id>
<content type='text'>
Using the DMA in cyclic mode modifies the hardware buffer descriptor
chain in xilinx_dma_prep_dma_cyclic so that the last descriptor used by
the cyclic transfer points back to the first descriptor, but it never
restores the original descriptor ring. This breaks using non-cyclic mode
after cyclic mode with an error like:

  xilinx-vdma 86000000.dma: Channel 00000000354d5c8d has errors 100, cdr 6de40000 tdr 6de40400

The only way to get out of this error state is to rebuild the hardware
buffer descriptor ring by releasing and re-acquiring the channel.

Fix using non-cyclic mode after cyclic mode by always restoring the
original buffer descriptor ring in the same manner as it is set up by
xilinx_dma_alloc_chan_resources().

Fixes: 23059408b6a3 ("dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario")
Signed-off-by: Alex Bereza &lt;alex@bereza.email&gt;
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Reviewed-by: Suraj Gupta &lt;suraj.gupta2@amd.com&gt;
Link: https://patch.msgid.link/20260817-fix-hw-buf-desc-after-cyclic-mode-v1-1-1fe47e701d6c@bereza.email
Link: https://patch.msgid.link/20260818-fix-hw-buf-desc-after-cyclic-mode-v2-1-530ff44c6a81@bereza.email
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: pxa: fix double counting of the hw descriptors</title>
<updated>2026-09-10T12:39:53Z</updated>
<author>
<name>Sascha Hauer</name>
<email>s.hauer@pengutronix.de</email>
</author>
<published>2026-08-17T20:44:33Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=f6504be006aa4bb4bd26285f410a885c17920d65'/>
<id>urn:sha1:f6504be006aa4bb4bd26285f410a885c17920d65</id>
<content type='text'>
pxad_alloc_desc() was converted from

        kzalloc(struct_size(sw_desc, hw_desc, nb_hw_desc), GFP_NOWAIT)

to kzalloc_flex(), which sets the __counted_by() counter sw_desc-&gt;nb_desc
itself - but only where the compiler has __builtin_counted_by_ref(), so
from gcc 15.1 or clang 22.1 on. The loop below it still increments
nb_desc, which makes it come out doubled there and correct elsewhere.

nb_desc is what pxad_free_desc() iterates over and what
set_updater_desc() indexes from, so set it explicitly and drop the
increment. The error path has to lower it to the number of descriptors
allocated so far, otherwise pxad_free_desc() would free entries that were
never allocated.

Fixes: 69050f8d6d075 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Sascha Hauer &lt;s.hauer@pengutronix.de&gt;
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Link: https://lore.kernel.org/r/20260817-dmaengine-pxa-v1-1-850c215c1196@pengutronix.de
Link: https://patch.msgid.link/20260817-dmaengine-pxa-v2-1-f42ab0569a48@pengutronix.de
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status</title>
<updated>2026-09-10T12:27:46Z</updated>
<author>
<name>Christian Lugnberg</name>
<email>christian.lugnberg@soundtrack.io</email>
</author>
<published>2026-08-17T13:51:23Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=9096bdc8d930147f7c39a493a859acbd3a8485d8'/>
<id>urn:sha1:9096bdc8d930147f7c39a493a859acbd3a8485d8</id>
<content type='text'>
sun6i_dma_tx_status() calls vchan_find_desc() to look up the virtual
descriptor for a given cookie, before checking whether the pointer
vd is NULL:

    vd = vchan_find_desc(&amp;vchan-&gt;vc, cookie);
    txd = to_sun6i_desc(&amp;vd-&gt;tx);   /* vd may be NULL here */

    if (vd) {
        for (lli = txd-&gt;v_lli; ...)

vchan_find_desc() returns NULL when the descriptor has already been
completed or is in-flight on a physical channel and no longer present
in the virtual channel's descriptor list. When vd is NULL,
to_sun6i_desc() is called unconditionally on &amp;vd-&gt;tx before the NULL
check, which is undefined behaviour. Move the call inside the if (vd)
guard to ensure it is only reached with a valid pointer.

    vd = vchan_find_desc(&amp;vchan-&gt;vc, cookie);
    if (vd) {
        struct sun6i_desc *txd = to_sun6i_desc(&amp;vd-&gt;tx);
        for (lli = txd-&gt;v_lli; ...)

Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Christian Lugnberg &lt;christian.lugnberg@soundtrack.io&gt;
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Link: https://patch.msgid.link/20260817135723.12807-3-christian.lugnberg@soundtrack.io
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: sun6i: fix non-atomic read of DMA position registers</title>
<updated>2026-09-10T12:27:46Z</updated>
<author>
<name>Christian Lugnberg</name>
<email>christian.lugnberg@soundtrack.io</email>
</author>
<published>2026-08-17T13:51:22Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=c90b6973daa37f4c283342dff881ae001dea4fe6'/>
<id>urn:sha1:c90b6973daa37f4c283342dff881ae001dea4fe6</id>
<content type='text'>
sun6i_get_chan_size() reads DMA_CHAN_LLI_ADDR and DMA_CHAN_CUR_CNT in two
separate readl() calls with no synchronisation between them:

    pos   = readl(pchan-&gt;base + DMA_CHAN_LLI_ADDR);
    bytes = readl(pchan-&gt;base + DMA_CHAN_CUR_CNT);

DMA_CHAN_LLI_ADDR holds the physical address of the *next* descriptor the
engine will load once the current one completes. DMA_CHAN_CUR_CNT holds the
remaining byte count for the *current* descriptor. If the DMA engine
advances to the next LLI entry between the two reads, pos becomes stale: it
still points to what was the next descriptor at the time of the first read,
but that descriptor is now the current one and CUR_CNT reflects its initial
(full) byte count. The subsequent virtual-chain walk starts one entry too
early and accumulates an extra full period's worth of bytes into the
residue estimate.

Fix this by re-reading DMA_CHAN_LLI_ADDR after DMA_CHAN_CUR_CNT and
retrying if the value changed. This double-read pattern guarantees that
both registers were sampled during the same descriptor interval. The cost
is at most one extra readl() pair per call in the racy case, which occurs
only at descriptor boundaries (~every 2 ms) and is negligible.

Fixes: a90e173f3faf ("dmaengine: sun6i: Add cyclic capability")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Christian Lugnberg &lt;christian.lugnberg@soundtrack.io&gt;
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Link: https://patch.msgid.link/20260817135723.12807-2-christian.lugnberg@soundtrack.io
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order</title>
<updated>2026-09-10T12:21:06Z</updated>
<author>
<name>Alex Bereza</name>
<email>alex@bereza.email</email>
</author>
<published>2026-08-17T09:23:55Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=cee9c863ee68cb27d66745eb03f60e357f4f8ad2'/>
<id>urn:sha1:cee9c863ee68cb27d66745eb03f60e357f4f8ad2</id>
<content type='text'>
xilinx_dma_alloc_chan_resources() builds a static ring of hardware
buffer descriptors once and the driver uses this ring throughout the
lifetime of a channel. This requires the allocation order of hardware
buffer descriptors from chan-&gt;free_seg_list to stay in sync with the
hardware buffer descriptor ring built at channel allocation time by
returning oldest descriptors to chan-&gt;free_seg_list first.

When chan-&gt;pending_list is not empty e.g. during
xilinx_dma_terminate_all() the chan-&gt;free_seg_list and the order of the
static hardware buffer descriptor ring get out of sync. Descriptors age
in this order: pending -&gt; active -&gt; done. So freeing pending_list first
returns the newest buffer descriptors to the chan-&gt;free_seg_list first
and thus breaks the order required by the static hardware buffer
descriptor ring. Then when the channel is reused, after a wrap around of
the free_seg_list the DMA will find a hardware buffer descriptor with a
length field that is still zeroed and stop with something like this:

  xilinx-vdma 86000000.dma: Channel 000000003a21d7b8 has errors 10, cdr 6de4c000 tdr 6de4c000

After this no more descriptors are completed and a consumer potentially
blocks and waits forever. The only way to get out of this error state is
to rebuild the static hardware buffer descriptor ring and the
free_seg_list by releasing and re-acquiring the channel.

Fix the order in which hardware buffer descriptors are returned to
free_seg_list to ensure the mentioned requirement holds.

Fixes: 23059408b6a3 ("dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario")
Signed-off-by: Alex Bereza &lt;alex@bereza.email&gt;
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Reviewed-by: Suraj Gupta &lt;suraj.gupta2@amd.com&gt;
Link: https://patch.msgid.link/20260817-fix-hw-buf-desc-reuse-v1-1-d79827a844c7@bereza.email
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: wait for RCU readers before releasing dma_device</title>
<updated>2026-09-09T12:21:44Z</updated>
<author>
<name>Shivank Garg</name>
<email>shivankg@amd.com</email>
</author>
<published>2026-08-22T19:22:06Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=dc750422170a563c7a81f6e49d36bb02c62ae37f'/>
<id>urn:sha1:dc750422170a563c7a81f6e49d36bb02c62ae37f</id>
<content type='text'>
dma_issue_pending_all() walks the dma_device_list with
list_for_each_entry_rcu() under rcu_read_lock(). dma_device_release()
unlinks the device with list_del_rcu() and then calls
device-&gt;device_release() (which in many drivers, such as plx_dma.c,
directly calls kfree()).

Because there is no grace period between unlinking the device and
freeing it, concurrent RCU readers in dma_issue_pending_all() can
access the device after it has been freed.

The lockless walk originally relied on clients holding a dmaengine
reference to pin the provider module, and therefore the device, for as
long as they might traverse the list. Commit 8ad342a86359 ("dmaengine:
Add reference counting to dma_device struct") decoupled the dma_device
lifetime from the module reference, so the device can now be released
while a reader is still walking the list.

Add synchronize_rcu() before the device is freed, so RCU readers are
guaranteed to have finished. Keep it unconditional: providers that do
not implement device_release() free the device themselves once
dma_async_device_unregister() returns. This call will delay for a grace
period with dma_list_mutex held, which is safe and only teardown path is
delayed.

Fixes: 2ba05622b8b1 ("dmaengine: provide a common 'issue_pending_all' implementation")
Suggested-by: Sashiko &lt;sashiko-bot@kernel.org&gt;
Link: https://sashiko.dev/#/patchset/20260526-dmaengine-kref-fix-v2-0-3df60afac01d@amd.com
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Reviewed-by: Logan Gunthorpe &lt;logang@deltatee.com&gt;
Signed-off-by: Shivank Garg &lt;shivankg@amd.com&gt;
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-4-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel()</title>
<updated>2026-09-09T12:21:44Z</updated>
<author>
<name>Shivank Garg</name>
<email>shivankg@amd.com</email>
</author>
<published>2026-08-22T19:22:05Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=e873c74132f0c5f1452816cd9bb26208f0bba1e1'/>
<id>urn:sha1:e873c74132f0c5f1452816cd9bb26208f0bba1e1</id>
<content type='text'>
When dma_device_put() drops the last reference on chan-&gt;device-&gt;ref,
dma_device_release() runs and may free the dma_device along with its
channels.

dma_chan_put() then still reads chan-&gt;device-&gt;owner via
dma_chan_to_owner() for the trailing module_put(). KASAN catches it:

	slab-use-after-free in dma_chan_put+0x3e6/0x4c0
	Read of size 8 by task insmod/6319
	Freed by task 6319:
	  kfree+0x225/0x470
	  dma_chan_put+0x395/0x4c0
	  dmaengine_put+0xf8/0x160

Cache the module owner in dma_chan_put() before the put so the trailing
module_put() does not need chan-&gt;device.

Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct")
Suggested-by: Sashiko &lt;sashiko-bot@kernel.org&gt;
Link: https://sashiko.dev/#/patchset/20260518-dmaengine-kref-fix-v1-1-4d6125048fb7@amd.com
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Reviewed-by: Logan Gunthorpe &lt;logang@deltatee.com&gt;
Signed-off-by: Shivank Garg &lt;shivankg@amd.com&gt;
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-3-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
<entry>
<title>dmaengine: Fix device kref underflow in dma_chan_put()</title>
<updated>2026-09-09T12:21:44Z</updated>
<author>
<name>Shivank Garg</name>
<email>shivankg@amd.com</email>
</author>
<published>2026-08-22T19:22:04Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=44dab659064eb5c10adb0306510eebe848ed592d'/>
<id>urn:sha1:44dab659064eb5c10adb0306510eebe848ed592d</id>
<content type='text'>
dma_chan_get() takes chan-&gt;device-&gt;ref only on the slow path:

	/* no kref on fast path */
	if (chan-&gt;client_count) {
		__module_get(owner);
		chan-&gt;client_count++;
		return 0;
	}
	if (!try_module_get(owner))
		return -ENODEV;
	if (!dma_device_get(chan-&gt;device)) { // calls kref_get_unless_zero()

dma_chan_put() drops the ref unconditionally, so every fast-path
get/put pair drops one extra device reference.

The bug fires when two conditions hold together: a non-private
provider has a persistent client holding chan-&gt;client_count &gt; 0
and another client cycles dmaengine_get()/dmaengine_put().
When the kref hits zero, the subsequent dma_find_channel() returns
NULL even though the provider module is still loaded.

Fix this by dropping device-&gt;ref only on the last put, matching the
single slow-path get.

Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct")
Reviewed-by: Frank Li &lt;Frank.Li@nxp.com&gt;
Reviewed-by: Logan Gunthorpe &lt;logang@deltatee.com&gt;
Signed-off-by: Shivank Garg &lt;shivankg@amd.com&gt;
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-2-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul &lt;vkoul@kernel.org&gt;
</content>
</entry>
</feed>
