diff options
| author | Pufan Jin <cyan2254650260@gmail.com> | 2026-10-16 21:08:12 +0800 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-10-23 18:46:26 +0100 |
| commit | dc5ca34f5e8dc10c566ef39aa3b1a201a17ca734 (patch) | |
| tree | da18bd63c4a5fb8d7b07e6f2bc2fbf12ac4d37ac /kernel/cpu | |
| parent | d5acef12e819c1627c8bf6a0325845ab39d8c99d (diff) | |
spi: zynq-qspi: fix address buffer corruption and support 4-byte address
In zynq_qspi_exec_mem_op(), when transmitting address bytes, the driver
iterates over op->addr.nbytes and populates xqspi->txbuf[i]. However,
xqspi->txbuf is never re-assigned before populating the address, meaning
it still points to (u8 *)&op->cmd.opcode from the command phase.
This causes two severe issues:
1. Memory corruption: Writing into xqspi->txbuf writes past the opcode
buffer on the stack (which was passed as const struct spi_mem_op *).
If opcode is zero, xqspi->txbuf is uninitialized.
2. In zynq_qspi_supports_op(), operations with op->addr.nbytes > 3 are
rejected. When paired with SPI NOR flashes larger than 16MB (such as
Winbond W25Q256), spi_nor_spimem_check_read_pp_op() tests 4-byte address
support, which fails and causes spi_nor_select_read() to drop all read
capabilities, failing probe with -EINVAL (-22).
The Zynq-7000 QSPI controller hardware in manual I/O mode natively supports
transmitting 1 to 4 address bytes via its TXD FIFO registers
(ZYNQ_QSPI_TXD_00_00_OFFSET).
Fix this by introducing a local opaddr[4] buffer in zynq_qspi_exec_mem_op()
and explicitly setting xqspi->txbuf = opaddr before populating address
bytes. Also allow up to 4 address bytes in zynq_qspi_supports_op().
Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller")
Cc: stable@vger.kernel.org
Signed-off-by: Pufan Jin <cyan2254650260@gmail.com>
Link: https://patch.msgid.link/20261016130812.282624-1-cyan2254650260@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'kernel/cpu')
0 files changed, 0 insertions, 0 deletions
