All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Xianwei Zhao" <xianwei.zhao@amlogic.com>
Cc: conor+dt@kernel.org, devicetree@vger.kernel.org,
	linux-amlogic@lists.infradead.org, neil.armstrong@linaro.org,
	robh@kernel.org
Subject: Re: [PATCH v2 2/4] spi: amlogic: spisg: Fix transfer size limit and timeout handling
Date: Thu, 23 Jul 2026 07:02:33 +0000	[thread overview]
Message-ID: <20260723070233.551EC1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260723-a9-spisg-v2-2-9fc39106b7e2@amlogic.com>

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

Pre-existing issues:
- [High] Missing max_transfer_size callback leads to silent truncation of large transfers.
- [High] Incomplete timeout handling leaves interrupts unmasked, allowing a delayed interrupt to prematurely complete a subsequent transfer.
- [High] Immediate DMA buffer unmapping on transfer timeout causes memory corruption if the hardware DMA engine is still active.
--

--- Patch [2]: [PATCH v2 2/4] spi: amlogic: spisg: Fix transfer size limit and timeout handling ---
commit d149d3bcf81987c3bc95c5cc0053e984ee79e15e
Author: Xianwei Zhao <xianwei.zhao@amlogic.com>
Subject: spi: amlogic: spisg: Fix transfer size limit and timeout handling

This commit reduces SPISG_BLOCK_MAX to 0xfffff to avoid programming zero-length
transfers because the CFG_BLOCK_NUM field can only encode 20 bits. It also
fixes a delay calculation overflow and attempts to stop the controller on
transfer timeout by clearing the descriptor list register.

Fixes: cef9991e04ae ("spi: Add Amlogic SPISG driver")

> --- a/drivers/spi/spi-amlogic-spisg.c
> +++ b/drivers/spi/spi-amlogic-spisg.c
> @@ -95,7 +95,7 @@
>  
>  #define SPISG_MAX_REG			0x40
>  
> -#define SPISG_BLOCK_MAX			0x100000
> +#define SPISG_BLOCK_MAX			0xFFFFF

[Severity: High]
This isn't a bug introduced by this patch, but modifying SPISG_BLOCK_MAX
brings up a question about large transfers.

Are large I/O requests being silently truncated?

In aml_spisg_setup_transfer(), the hardware block count is dynamically clamped:

    blocks = min_t(int, blocks, SPISG_BLOCK_MAX);

However, the driver does not provide a ctlr->max_transfer_size callback.
The SPI core assumes SIZE_MAX is supported and won't split large transfers.
The hardware will stop after transferring SPISG_BLOCK_MAX blocks.

Later in aml_spisg_transfer_one_message(), the driver unconditionally reports
success for the full length:

    msg->actual_length = msg->frame_length;

Could this cause silent data corruption for transfers larger than
SPISG_BLOCK_MAX * (bits_per_word / 8) bytes, since the caller is unaware the
transfer was truncated?

[ ... ]

> @@ -565,10 +565,13 @@ static int aml_spisg_transfer_one_message(struct spi_controller *ctlr,
>  	aml_spisg_pending(spisg, descs_paddr, false, true);
>  	if (wait_for_completion_timeout(&spisg->completion,
>  					spi_controller_is_target(spisg->controller) ?
> -					MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(ms)))
> +					MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(ms))) {
>  		ret = spisg->status ? -EIO : 0;
> -	else
> +	} else {
> +		/* stop transfer */
> +		regmap_write(spisg->map, SPISG_REG_DESC_LIST_H, 0);
>  		ret = -ETIMEDOUT;
> +	}

[Severity: High]
This is a pre-existing issue, but does the timeout path safely halt the DMA
engine before unmapping memory?

After writing 0 to SPISG_REG_DESC_LIST_H to abort the transfer, the driver
immediately calls dma_unmap_single() and then aml_spisg_cleanup_transfer()
to unmap the data buffers.

If the hardware DMA engine requires time to flush outstanding AXI transactions
or if the register write is delayed, could the hardware access unmapped pages
or memory reallocated to other components, resulting in memory corruption or
IOMMU faults? Is it necessary to poll the hardware to confirm it has halted
before proceeding?

[Severity: High]
This is also a pre-existing issue, but is there a race condition with
delayed interrupts on a timeout?

If a transfer times out, the driver issues the stop command but does not
mask the controller's interrupt (SPISG_REG_IRQ_ENABLE) or use synchronize_irq()
to ensure the handler is not running.

The interrupt handler aml_spisg_irq() unconditionally calls:

    complete(&spisg->completion);

If a delayed interrupt fires concurrently with a subsequent transfer that has
just called reinit_completion(&spisg->completion), might the new transfer's
wait_for_completion_timeout() return immediately as a false success? This could
cause the driver to unmap DMA buffers while the hardware is still actively
processing the new transfer.

>  
>  	dma_unmap_single(dev, descs_paddr, descs_len, DMA_TO_DEVICE);
>  end:

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260723-a9-spisg-v2-0-9fc39106b7e2@amlogic.com?part=2

WARNING: multiple messages have this Message-ID (diff)
From: sashiko-bot@kernel.org
To: "Xianwei Zhao" <xianwei.zhao@amlogic.com>
Cc: conor+dt@kernel.org, devicetree@vger.kernel.org,
	linux-amlogic@lists.infradead.org, neil.armstrong@linaro.org,
	robh@kernel.org
Subject: Re: [PATCH v2 2/4] spi: amlogic: spisg: Fix transfer size limit and timeout handling
Date: Thu, 23 Jul 2026 07:02:33 +0000	[thread overview]
Message-ID: <20260723070233.551EC1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260723-a9-spisg-v2-2-9fc39106b7e2@amlogic.com>

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

Pre-existing issues:
- [High] Missing max_transfer_size callback leads to silent truncation of large transfers.
- [High] Incomplete timeout handling leaves interrupts unmasked, allowing a delayed interrupt to prematurely complete a subsequent transfer.
- [High] Immediate DMA buffer unmapping on transfer timeout causes memory corruption if the hardware DMA engine is still active.
--

--- Patch [2]: [PATCH v2 2/4] spi: amlogic: spisg: Fix transfer size limit and timeout handling ---
commit d149d3bcf81987c3bc95c5cc0053e984ee79e15e
Author: Xianwei Zhao <xianwei.zhao@amlogic.com>
Subject: spi: amlogic: spisg: Fix transfer size limit and timeout handling

This commit reduces SPISG_BLOCK_MAX to 0xfffff to avoid programming zero-length
transfers because the CFG_BLOCK_NUM field can only encode 20 bits. It also
fixes a delay calculation overflow and attempts to stop the controller on
transfer timeout by clearing the descriptor list register.

Fixes: cef9991e04ae ("spi: Add Amlogic SPISG driver")

> --- a/drivers/spi/spi-amlogic-spisg.c
> +++ b/drivers/spi/spi-amlogic-spisg.c
> @@ -95,7 +95,7 @@
>  
>  #define SPISG_MAX_REG			0x40
>  
> -#define SPISG_BLOCK_MAX			0x100000
> +#define SPISG_BLOCK_MAX			0xFFFFF

[Severity: High]
This isn't a bug introduced by this patch, but modifying SPISG_BLOCK_MAX
brings up a question about large transfers.

Are large I/O requests being silently truncated?

In aml_spisg_setup_transfer(), the hardware block count is dynamically clamped:

    blocks = min_t(int, blocks, SPISG_BLOCK_MAX);

However, the driver does not provide a ctlr->max_transfer_size callback.
The SPI core assumes SIZE_MAX is supported and won't split large transfers.
The hardware will stop after transferring SPISG_BLOCK_MAX blocks.

Later in aml_spisg_transfer_one_message(), the driver unconditionally reports
success for the full length:

    msg->actual_length = msg->frame_length;

Could this cause silent data corruption for transfers larger than
SPISG_BLOCK_MAX * (bits_per_word / 8) bytes, since the caller is unaware the
transfer was truncated?

[ ... ]

> @@ -565,10 +565,13 @@ static int aml_spisg_transfer_one_message(struct spi_controller *ctlr,
>  	aml_spisg_pending(spisg, descs_paddr, false, true);
>  	if (wait_for_completion_timeout(&spisg->completion,
>  					spi_controller_is_target(spisg->controller) ?
> -					MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(ms)))
> +					MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(ms))) {
>  		ret = spisg->status ? -EIO : 0;
> -	else
> +	} else {
> +		/* stop transfer */
> +		regmap_write(spisg->map, SPISG_REG_DESC_LIST_H, 0);
>  		ret = -ETIMEDOUT;
> +	}

[Severity: High]
This is a pre-existing issue, but does the timeout path safely halt the DMA
engine before unmapping memory?

After writing 0 to SPISG_REG_DESC_LIST_H to abort the transfer, the driver
immediately calls dma_unmap_single() and then aml_spisg_cleanup_transfer()
to unmap the data buffers.

If the hardware DMA engine requires time to flush outstanding AXI transactions
or if the register write is delayed, could the hardware access unmapped pages
or memory reallocated to other components, resulting in memory corruption or
IOMMU faults? Is it necessary to poll the hardware to confirm it has halted
before proceeding?

[Severity: High]
This is also a pre-existing issue, but is there a race condition with
delayed interrupts on a timeout?

If a transfer times out, the driver issues the stop command but does not
mask the controller's interrupt (SPISG_REG_IRQ_ENABLE) or use synchronize_irq()
to ensure the handler is not running.

The interrupt handler aml_spisg_irq() unconditionally calls:

    complete(&spisg->completion);

If a delayed interrupt fires concurrently with a subsequent transfer that has
just called reinit_completion(&spisg->completion), might the new transfer's
wait_for_completion_timeout() return immediately as a false success? This could
cause the driver to unmap DMA buffers while the hardware is still actively
processing the new transfer.

>  
>  	dma_unmap_single(dev, descs_paddr, descs_len, DMA_TO_DEVICE);
>  end:

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260723-a9-spisg-v2-0-9fc39106b7e2@amlogic.com?part=2

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

  reply	other threads:[~2026-07-23  7:02 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23  6:43 [PATCH v2 0/4] spi: add support for Amlogic A9 Xianwei Zhao via B4 Relay
2026-07-23  6:43 ` Xianwei Zhao via B4 Relay
2026-07-23  6:43 ` Xianwei Zhao
2026-07-23  6:43 ` [PATCH v2 1/4] spi: dt-bindings: amlogic: spisg: Document A9-specific properties Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao
2026-07-23  6:51   ` sashiko-bot
2026-07-23  6:51     ` sashiko-bot
2026-07-23  6:43 ` [PATCH v2 2/4] spi: amlogic: spisg: Fix transfer size limit and timeout handling Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao
2026-07-23  7:02   ` sashiko-bot [this message]
2026-07-23  7:02     ` sashiko-bot
2026-07-23  6:43 ` [PATCH v2 3/4] spi: amlogic: spisg: Fix the incorrect keep_ss of the last descriptor Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao
2026-07-23  6:54   ` sashiko-bot
2026-07-23  6:54     ` sashiko-bot
2026-07-23  6:43 ` [PATCH v2 4/4] spi: amlogic: spisg: Add support for A9 controller features Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao via B4 Relay
2026-07-23  6:43   ` Xianwei Zhao
2026-07-23  6:56   ` sashiko-bot
2026-07-23  6:56     ` sashiko-bot

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=20260723070233.551EC1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=neil.armstrong@linaro.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=xianwei.zhao@amlogic.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 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.