From: sashiko-bot@kernel.org
To: "Changhuang Liang" <changhuang.liang@starfivetech.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v1 05/11] spi: dw: Introduce enhanced single/dual/quad/octal spi
Date: Thu, 09 Jul 2026 14:23:50 +0000 [thread overview]
Message-ID: <20260709142350.8E16A1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260709055204.138168-6-changhuang.liang@starfivetech.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [Critical] Divide-by-zero in wait cycle calculation causes kernel panic on commands without dummy cycles.
- [Critical] Enhanced memory operations completely fail to perform actual data transfers, causing uninitialized memory reads and silently dropped writes.
- [High] `dw_spi_exec_enh_mem_op` ignores the operation-specific maximum frequency, violating the SPI memory API contract.
- [High] Calculated wait cycles can exceed the 5-bit hardware register limit and are silently truncated to 0, corrupting read timing.
- [High] Unclamped data length for enhanced mode write operations leads to 16-bit hardware register truncation.
--
--- Patch [5]: [PATCH v1 05/11] spi: dw: Introduce enhanced single/dual/quad/octal spi ---
commit 0f1cbd98fc45570180f08cb46b29e531be3e743b
Author: Sudip Mukherjee <sudip.mukherjee@sifive.com>
spi: dw: Introduce enhanced single/dual/quad/octal spi
This commit introduces support for enhanced single/dual/quad/octal SPI modes
in the DesignWare SPI controller driver. It adds a new function to execute
enhanced memory operations and updates the SPI_CTRLR0 register configuration
when these modes are utilized.
> diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
> index 010a665b17b76..58159e8269f53 100644
> --- a/drivers/spi/spi-dw-core.c
> +++ b/drivers/spi/spi-dw-core.c
> @@ -815,6 +815,89 @@ static int dw_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
[ ... ]
> +static int dw_spi_exec_enh_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
> +{
> + struct spi_controller *ctlr = mem->spi->controller;
> + struct dw_spi *dws = spi_controller_get_devdata(ctlr);
> + struct dw_spi_enh_cfg enh_cfg;
> + struct dw_spi_cfg cfg;
> +
> + switch (op->data.buswidth) {
[ ... ]
> + dw_spi_init_enh_mem_buf(dws, op);
> +
> + cfg.dfs = 8;
> + cfg.freq = clamp(mem->spi->max_speed_hz, 0U, dws->max_mem_freq);
[Severity: High]
Does this code ignore the operation-specific maximum frequency?
The spi_mem_op struct specifies op->max_freq which dictates the maximum
safe clock speed for this specific command.
Using mem->spi->max_speed_hz instead might cause operations with stricter
frequency limits to execute at the higher overall bus speed, potentially
leading to hardware timing violations.
> + cfg.ndf = op->data.nbytes;
> + if (op->data.dir == SPI_MEM_DATA_IN)
> + cfg.tmode = DW_SPI_CTRLR0_TMOD_RO;
> + else
> + cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
[Severity: High]
Can enhanced transmit-only mode operations suffer from size truncation?
Enhanced Transmit Only mode uses DW_SPI_CTRLR1 to count frames to transmit,
and this is a 16-bit register.
While dw_spi_adjust_mem_op_size() clamps SPI_MEM_DATA_IN, it does not
clamp SPI_MEM_DATA_OUT operations. If an outbound transfer is large,
such as exactly 65536 bytes, the unclamped length will be truncated when
written to the 16-bit DW_SPI_CTRLR1 register.
> +
> + if (op->data.buswidth == op->addr.buswidth &&
> + op->data.buswidth == op->cmd.buswidth)
> + enh_cfg.trans_t = DW_SPI_ENH_CTRLR0_TRANS_TYPE_TT2;
[ ... ]
> + enh_cfg.addr_l = op->addr.nbytes << 1;
> + if (op->cmd.nbytes == 2)
> + enh_cfg.inst_l = DW_SPI_ENH_CTRLR0_INST_L_INST_L16;
> + else if (op->cmd.nbytes == 1)
> + enh_cfg.inst_l = DW_SPI_ENH_CTRLR0_INST_L_INST_L8;
> + else
> + enh_cfg.inst_l = DW_SPI_ENH_CTRLR0_INST_L_INST_L0;
> +
> + enh_cfg.wait_c = (op->dummy.nbytes * (BITS_PER_BYTE / op->dummy.buswidth));
[Severity: Critical]
Can this cause a divide-by-zero crash if the operation has no dummy phase?
For operations like READ ID or standard read/write without dummies, both
op->dummy.nbytes and op->dummy.buswidth are initialized to 0.
Since there is no check before the division, this will cause a kernel panic
whenever such a command is sent in enhanced mode.
[Severity: High]
Additionally, could this calculation result in a value that exceeds the
hardware register limit?
If op->dummy.nbytes is 4 and op->dummy.buswidth is 1, enh_cfg.wait_c
evaluates to 32.
Later, dw_spi_update_config() applies a 5-bit mask to this value:
cr0 |= FIELD_PREP(DW_SPI_ENH_CTRLR0_WAIT_CYCLE_MASK, enh_cfg->wait_c);
Since 32 requires 6 bits, FIELD_PREP will truncate it to 0, incorrectly
configuring the controller for 0 wait cycles instead of 32.
> +
> + dw_spi_enable_chip(dws, 0);
> +
> + dw_spi_update_config(dws, mem->spi, &cfg, &enh_cfg);
> +
> + dw_spi_enable_chip(dws, 1);
> +
> + return 0;
[Severity: Critical]
Does this function complete without actually performing the SPI data
transfers?
The function enables the SPI chip and then immediately returns 0. It
appears to omit the steps to write the command, address, or data to the
data register, and does not read from the RX FIFO.
Will this cause read operations to return uninitialized buffer memory and
write operations to silently drop all data?
> +}
> +
> /*
> * Initialize the default memory operations if a glue layer hasn't specified
> * custom ones. Direct mapping operations will be preserved anyway since DW SPI
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260709055204.138168-1-changhuang.liang@starfivetech.com?part=5
next prev parent reply other threads:[~2026-07-09 14:23 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-09 5:51 [PATCH v1 00/11] Add support for StarFive JHB100 SFC Changhuang Liang
2026-07-09 5:51 ` [PATCH v1 01/11] spi: dw: Introduce spi_frf and STD_SPI Changhuang Liang
2026-07-09 5:51 ` [PATCH v1 02/11] spi: dw: update NDF while using enhanced spi mode Changhuang Liang
2026-07-09 13:50 ` sashiko-bot
2026-07-09 5:51 ` [PATCH v1 03/11] spi: dw: update SPI_CTRLR0 register Changhuang Liang
2026-07-09 14:00 ` sashiko-bot
2026-07-09 5:51 ` [PATCH v1 04/11] spi: dw: add check for support of enhanced spi Changhuang Liang
2026-07-09 14:13 ` sashiko-bot
2026-07-09 5:51 ` [PATCH v1 05/11] spi: dw: Introduce enhanced single/dual/quad/octal spi Changhuang Liang
2026-07-09 14:23 ` sashiko-bot [this message]
2026-07-09 5:51 ` [PATCH v1 06/11] spi: dw: send cmd and addr to start the spi transfer Changhuang Liang
2026-07-09 14:37 ` sashiko-bot
2026-07-09 5:52 ` [PATCH v1 07/11] spi: dw: use irq handler for enhanced spi Changhuang Liang
2026-07-09 14:50 ` sashiko-bot
2026-07-09 5:52 ` [PATCH v1 08/11] spi: dw: adjust size of mem_op Changhuang Liang
2026-07-09 15:08 ` sashiko-bot
2026-07-09 5:52 ` [PATCH v1 09/11] spi: dw: detect enhanced spi mode Changhuang Liang
2026-07-09 15:20 ` sashiko-bot
2026-07-09 5:52 ` [PATCH v1 10/11] spi: dt-bindings: snps,dw-apb-ssi: Add starfive,jhb100-sfc Changhuang Liang
2026-07-09 17:55 ` Conor Dooley
2026-07-09 5:52 ` [PATCH v1 11/11] spi: dw: Add support for StarFive JHB100 SoC SFC Changhuang Liang
2026-07-09 15:34 ` 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=20260709142350.8E16A1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=changhuang.liang@starfivetech.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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