DMA Engine development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Maoyi Xie" <maoyixie.tju@gmail.com>
Cc: wsa+renesas@sang-engineering.com, vkoul@kernel.org,
	Frank.Li@kernel.org, dmaengine@vger.kernel.org
Subject: Re: [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg()
Date: Thu, 21 May 2026 15:42:05 +0000	[thread overview]
Message-ID: <20260521154205.BCE4E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260521144755.3476353-2-maoyixie.tju@gmail.com>

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

Pre-existing issues:
- [High] Incorrect minor loop byte count calculation causes hardware configuration errors and potential division by zero panic.
- [High] Direct C bitfield assignment to an __iomem pointer causes undefined behavior and potential Machine Check Exceptions.
--

commit 843ae9154206865fe98175ccec56b456c8445f35
Author: Maoyi Xie <maoyixie.tju@gmail.com>

dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg()
    
mpc_dma_prep_slave_sg() reads mchan->free with list_first_entry()
and then tests the returned pointer against NULL. list_first_entry()
never returns NULL. On an empty free list it returns an aliased
pointer derived from the list head, making the recovery path dead code.

> diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
> index 0adc8e01057e1..f5934136efc4c 100644
> --- a/drivers/dma/mpc512x_dma.c
> +++ b/drivers/dma/mpc512x_dma.c
> @@ -706,8 +706,8 @@ mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
>  	for_each_sg(sgl, sg, sg_len, i) {
>  		spin_lock_irqsave(&mchan->lock, iflags);
>  
> -		mdesc = list_first_entry(&mchan->free,
> -						struct mpc_dma_desc, node);
> +		mdesc = list_first_entry_or_null(&mchan->free,
> +						 struct mpc_dma_desc, node);
>  		if (!mdesc) {
>  			spin_unlock_irqrestore(&mchan->lock, iflags);
>  			/* Try to free completed descriptors */

[Severity: High]
This isn't a bug introduced by this patch, but in mpc_dma_prep_slave_sg(),
the minor loop byte count is calculated using the register enum value
tcd->ssize instead of the actual transfer width:

drivers/dma/mpc512x_dma.c:mpc_dma_prep_slave_sg() {
...
		tcd->ssize = buswidth_to_dmatsize(mchan->swidth);
		tcd->dsize = buswidth_to_dmatsize(mchan->dwidth);

		if (mdma->is_mpc8308) {
...
		} else {
			len = sg_dma_len(sg);
			tcd->nbytes = tcd_nunits * tcd->ssize;
			if (!IS_ALIGNED(len, tcd->nbytes))
				goto err_prep;

			iter = len / tcd->nbytes;
...
}

For a 1-byte transfer width, tcd->ssize is 0, causing tcd->nbytes to be 0.
If a client submits a scatterlist with length 0, the IS_ALIGNED(len,
tcd->nbytes) check passes (since 0 & -1 == 0), resulting in a division by
zero kernel panic when calculating iter.

Even for valid lengths, 1-byte transfers always fail the alignment check,
and transfers with other widths receive an incorrect minor loop
configuration, causing functional failures.

Could we update this to use the actual transfer width instead of the enum
value?


[Severity: High]
This is also a pre-existing issue, but in mpc_dma_execute(), a bitfield on
a memory-mapped I/O structure is modified directly via C assignment:

drivers/dma/mpc512x_dma.c:mpc_dma_execute() {
...
	/* Send first descriptor in chain into hardware */
	memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd));

	if (first != prev)
		mdma->tcd[cid].e_sg = 1;
...
}

Since mdma->tcd is an __iomem pointer, does dereferencing it directly with
standard C assignments invoke undefined behavior and circumvent necessary
I/O accessors?

As struct mpc_dma_tcd is marked __packed__, the compiler may generate
byte-sized read-modify-write instructions. On PowerPC architectures, such
non-32-bit accesses to memory-mapped device registers can trigger Machine
Check Exceptions (MCE), leading to system crashes.

Is there a safer way to update this hardware register using appropriate
I/O accessors?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521144755.3476353-1-maoyixie.tju@gmail.com?part=1

  reply	other threads:[~2026-05-21 15:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-21 14:47 [PATCH 0/2] dmaengine: fix dead empty checks in mpc512x and rz-dmac Maoyi Xie
2026-05-21 14:47 ` [PATCH 1/2] dmaengine: mpc512x: fix dead empty check in mpc_dma_prep_slave_sg() Maoyi Xie
2026-05-21 15:42   ` sashiko-bot [this message]
2026-05-21 16:30   ` Frank Li
2026-05-22 15:02   ` [PATCH v2] " Maoyi Xie
2026-05-22 15:23     ` sashiko-bot
2026-05-21 14:47 ` [PATCH 2/2] dmaengine: rz-dmac: fix dead empty check in rz_dmac_chan_get_residue() Maoyi Xie
2026-05-21 16:05   ` sashiko-bot
2026-05-22  8:16   ` Geert Uytterhoeven
2026-05-22  8:37     ` Maoyi Xie

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=20260521154205.BCE4E1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=maoyixie.tju@gmail.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    --cc=wsa+renesas@sang-engineering.com \
    /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