All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "CL Wang" <cl634@andestech.com>
Cc: dmaengine@vger.kernel.org, vkoul@kernel.org, robh@kernel.org,
	Frank.Li@kernel.org, conor+dt@kernel.org,
	devicetree@vger.kernel.org
Subject: Re: [PATCH v7 2/2] dmaengine: atcdmac300: Add driver for Andes ATCDMAC300 DMA controller
Date: Wed, 16 Sep 2026 14:01:19 +0000	[thread overview]
Message-ID: <20260916140120.3112D1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260916134258.2178081-3-cl634@andestech.com>

Thank you for your contribution! Sashiko AI review found 8 potential issue(s) to consider:
- [High] dmaengine: atcdmac300: UAF on driver unbind due to devres lifecycle mismatch
- [High] dmaengine: atcdmac300: permanent controller halt if suspend times out
- [High] dmaengine: atcdmac300: NULL pointer dereference mixing cyclic and non-cyclic transfers
- [High] dmaengine: atcdmac300: cross-transfer corruption on simultaneous TC and ERR interrupts
- [Medium] dmaengine: atcdmac300: memory leak of unsubmitted descriptors
- [Medium] dmaengine: atcdmac300: silent truncation of DT req_num exceeding 15
- [Medium] dmaengine: atcdmac300: transfers queued during suspend are stranded on resume
- [Low] dmaengine: atcdmac300: missing endianness conversions for DMA descriptors
--

commit 94fd62b6d9e6afc2cf50f8dff89eedcdc57f24c9
Author: CL Wang <cl634@andestech.com>
Subject: dmaengine: atcdmac300: Add driver for Andes ATCDMAC300 DMA controller

This patch adds support for the Andes ATCDMAC300 DMA controller. It provides
scatter-gather, cyclic, and slave transfer capabilities.

> diff --git a/drivers/dma/atcdmac300.c b/drivers/dma/atcdmac300.c
> index 0000000000000..e0a8a980e2fe8
> --- /dev/null
> +++ b/drivers/dma/atcdmac300.c
[ ... ]
> @@ -82,9 +82,6 @@ static struct atcdmac_desc *atcdmac_alloc_desc(struct dma_chan *chan,
>  		INIT_LIST_HEAD(&desc->desc_node);
>  		INIT_LIST_HEAD(&desc->tx_list);
>  		dma_async_tx_descriptor_init(&desc->txd, chan);
>  		desc->txd.flags = DMA_CTRL_ACK;
>  		desc->txd.tx_submit = atcdmac_tx_submit;
>  		desc->txd.phys = phys;
>  	}

[Severity: Medium]
The desc_free callback is omitted from the transaction descriptor here.
If a client prepares a descriptor but aborts and frees it before
submission, the DMA engine core won't be able to free it.

[ ... ]
> @@ -494,11 +494,11 @@ static irqreturn_t atcdmac_irq_thread(int irq, void *dev_id)
>  	for (i = 0; i < dmac->num_ch; i++) {
>  		dmac_chan = &dmac->chan[i];
>  
>  		if (test_and_clear_bit(ATCDMAC_STA_TC, &dmac_chan->status)) {
>  			atcdmac_advance_work(dmac_chan);
>  			handled = true;
>  		}
>  
>  		if (test_and_clear_bit(ATCDMAC_STA_ERR, &dmac_chan->status)) {
>  			atcdmac_handle_error(dmac_chan);
>  			handled = true;
>  		}

[Severity: High]
The lack of mutual exclusivity allows both conditions to execute if both
status bits are asserted simultaneously by the hardware. In this case,
atcdmac_advance_work() would complete the current descriptor and start the
next one, followed immediately by atcdmac_handle_error() wrongly aborting
the newly started, innocent descriptor. Should these checks be mutually
exclusive?

[ ... ]
> @@ -911,10 +911,8 @@ atcdmac_prep_dma_cyclic(struct dma_chan *chan,
>  		if (!desc)
>  			goto err_desc_get;
>  		atcdmac_chain_desc(&first, &prev, desc, true);
>  	}
>  
>  	first->txd.flags = flags;
>  	dmac_chan->cyclic = true;

[Severity: High]
This modifies the channel-wide state during descriptor preparation.
If a client prepares a cyclic transfer, does not submit it, and
subsequently prepares and submits a non-cyclic transfer, this global
flag remains set. When the non-cyclic transfer completes, could this
cause atcdmac_advance_work() to treat it as cyclic and attempt to
dereference dma_desc->at->next in atcdmac_start_next_trans(), leading
to a kernel panic?

[ ... ]
> @@ -1144,10 +1144,8 @@ static void atcdmac_free_chan_resources(struct dma_chan *chan)
>  	spin_lock_irqsave(&dmac_chan->lock, flags);
>  	list_for_each_entry_safe(desc,
>  				 desc_next,
>  				 &dmac_chan->free_list,
>  				 desc_node) {
>  		list_del(&desc->desc_node);
>  		dma_pool_free(dmac->dma_desc_pool, desc, desc->txd.phys);
>  	}

[Severity: Medium]
This loop only frees descriptors currently sitting in the free_list.
Combined with the missing desc_free callback above, does this mean any
prepared but unsubmitted descriptors are permanently leaked and never
returned to the dma_desc_pool?

[ ... ]
> @@ -1189,8 +1189,8 @@ static struct dma_chan *atcdmac_dma_xlate_handler(struct of_phandle_args *dmac,
>  	if (!chan)
>  		return NULL;
>  
>  	dmac_chan = atcdmac_chan_to_dmac_chan(chan);
>  	dmac_chan->dev_chan = true;
>  	dmac_chan->req_num = dmac->args[0] & 0xff;

[Severity: Medium]
The request number is extracted and masked to 8 bits. However, the hardware
request selection registers (SRC_REQ_SEL_MASK, DST_REQ_SEL_MASK) are only
4 bits wide. Since FIELD_PREP silently truncates values, a device tree
req_num of 16 will be programmed into hardware as 0 without warning.
Should this value be explicitly validated against the 4-bit maximum?

[ ... ]
> @@ -1305,9 +1305,9 @@ static int atcdmac_init_ioremap_and_regmap(struct platform_device *pdev,
>  	regmap_read(regmap, REG_CFG, &val);
>  	num_ch = val & CH_NUM;
>  	size = sizeof(*dmac) + num_ch * sizeof(struct atcdmac_chan);
>  	dmac = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
>  	if (!dmac)
>  		return -ENOMEM;

[Severity: High]
The DMA controller structure is allocated using devres, tying its
lifetime to the device binding rather than the dma_device refcount.
If a client driver still holds a channel reference when the device is
unbound, could this lead to a use-after-free when the client later
releases the channel and atcdmac_free_chan_resources() accesses the
freed dmac structure?

[ ... ]
> @@ -1543,9 +1543,8 @@ static int atcdmac_resume(struct device *dev)
>  	list_for_each_entry_safe(chan,
>  				 chan_next,
>  				 &dmac->dma_device.channels,
>  				 device_node) {
>  		dmac_chan = atcdmac_chan_to_dmac_chan(chan);
>  		spin_lock_irqsave(&dmac_chan->lock, flags);
>  		if (!list_empty(&dmac_chan->active_list))
>  			atcdmac_start_next_trans(dmac_chan);

[Severity: Medium]
This condition actively prevents queue_list items from being serviced if
the active_list is empty during resume. Since transfers submitted during
suspend are placed into queue_list (because stop_mask prevents them from
starting), won't they remain stranded indefinitely unless issue_pending
is also called here?

[ ... ]
> @@ -1568,9 +1568,9 @@ static int atcdmac_suspend(struct device *dev)
>  	synchronize_irq(dmac->irq);
>  
>  	ret = atcdmac_wait_chan_idle(dmac,
>  				     chan_mask,
>  				     ATCDMAC_CHAN_TIMEOUT_US * dmac->num_ch);
>  
>  	return ret;
>  }

[Severity: High]
If atcdmac_wait_chan_idle() times out, the function returns the error code
without reverting dmac->stop_mask back to 0. Since the PM core would abort
the system suspend and resume normal operations, wouldn't this permanently
prevent any new transfers from starting?

> diff --git a/drivers/dma/atcdmac300.h b/drivers/dma/atcdmac300.h
> index 0000000000000..3d2d07effc26d
> --- /dev/null
> +++ b/drivers/dma/atcdmac300.h
[ ... ]
> @@ -148,10 +148,10 @@ enum dma_sta {
>   * @ll_ptr_hi: Linked List Pointer Register (high 32-bit).
>   */
>  struct atcdmac_regs {
>  	unsigned int ctrl;
>  	unsigned int trans_size;

[Severity: Low]
The hardware descriptor layout uses native unsigned int instead of
explicitly sized __le32 types. When these fields are populated in
atcdmac_build_desc(), values are assigned directly without cpu_to_le32().
Does this lack of endianness conversion break portability if this driver
is ever used on a big-endian system?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260916134258.2178081-1-cl634@andestech.com?part=2

  reply	other threads:[~2026-09-16 14:01 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16 13:42 [PATCH v7 0/2] dmaengine: atcdmac300: Add Andes ATCDMAC300 DMA driver CL Wang
2026-09-16 13:42 ` [PATCH v7 1/2] dt-bindings: dmaengine: Add support for ATCDMAC300 DMA engine CL Wang
2026-09-16 13:42 ` [PATCH v7 2/2] dmaengine: atcdmac300: Add driver for Andes ATCDMAC300 DMA controller CL Wang
2026-09-16 14:01   ` sashiko-bot [this message]
2026-09-16 15:50     ` Frank Li
2026-09-22  7:56       ` CL Wang

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=20260916140120.3112D1F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=cl634@andestech.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=robh@kernel.org \
    --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 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.