drivers/spi/.kunitconfig | 4 + drivers/spi/Kconfig | 13 + drivers/spi/Makefile | 1 + drivers/spi/internals.h | 9 +- drivers/spi/spi.c | 91 ++++--- drivers/spi/tests/Makefile | 3 + drivers/spi/tests/spi-dma-kunit.c | 259 +++++++++++++++++++ tools/testing/kunit/configs/all_tests.config | 1 + tools/testing/kunit/configs/default.config | 1 + 9 files changed, 340 insertions(+), 42 deletions(-) create mode 100644 drivers/spi/.kunitconfig create mode 100644 drivers/spi/tests/Makefile create mode 100644 drivers/spi/tests/spi-dma-kunit.c
A partial DMA mapping failure can leave per-transfer mapping flags set
while cur_{tx,rx}_dma_dev are NULL or still refer to the devices used
for an earlier message. The subsequent cleanup may then unmap a
transfer with a NULL or stale device.
Before commit e289df82344f ("spi: Rework per message DMA mapped flag to
be per transfer"), partial-failure handling was already incomplete, but
__spi_unmap_msg() was gated by cur_msg_mapped, which was set only after
the whole message mapped successfully. Earlier mappings could leak, but
cleanup could not unmap them with an unpublished device. The
per-transfer conversion removed that gate: mapping flags can now remain
set while cur_{tx,rx}_dma_dev are still unpublished, turning the leak
into a NULL- or stale-device unmap regression.
Patch 1 publishes the mapping devices before the loop and unwinds every
failure through __spi_unmap_msg(). It keeps the forward declaration so
it is independently buildable and straightforward to backport. Patch 2
then removes the declaration by moving __spi_unmap_msg() above
__spi_map_msg(). Patch 3 clears the current DMA device pointers once the
message has been unmapped, while leaving them intact during partial-map
unwind and DMA-to-PIO fallback. Patch 4 adds the DMA mapping KUnit suite
as a separate translation unit.
Only patch 1 is a stable candidate; patches 2 through 4 are follow-up
cleanup and test changes for mainline.
Testing:
- Patch 1 builds independently with the x86_64 reproducer configuration.
- The spi_dma KUnit suite passes all four cases on x86_64 and UML.
Moving the DMA device assignments back after the mapping loop makes
both failure-path cases fail.
- The default and all-tests KUnit configurations both select the suite.
- All four reproducer cases complete without an oops when run as the
first message, and map/unmap counts are balanced after a successful
first message.
- After message cleanup, cur_{tx,rx}_dma_dev are NULL.
Changes in v2:
- Explain why e289df82344f changed the partial-failure mode.
- Use plain if (ret) checks in the mapping loop.
- Add separate follow-up patches for the helper relocation and clearing
stale DMA device pointers.
- Build the KUnit tests as a separate translation unit through the local
internal header and <kunit/visibility.h>.
- Rename the Kconfig symbol and suite namespace for the DMA subsuite,
and rename the test file to spi-dma-kunit.c.
- Enable SPI in the default and all-tests KUnit configurations.
v1: https://lore.kernel.org/r/20260805151456.756579-1-jiang_hh2019@163.com
Honghui Jiang (4):
spi: Fix DMA mapping ownership on partial map failure
spi: Move __spi_unmap_msg() before __spi_map_msg()
spi: Clear current DMA devices when unmapping a message
spi: Add KUnit coverage for DMA mapping error paths
drivers/spi/.kunitconfig | 4 +
drivers/spi/Kconfig | 13 +
drivers/spi/Makefile | 1 +
drivers/spi/internals.h | 9 +-
drivers/spi/spi.c | 91 ++++---
drivers/spi/tests/Makefile | 3 +
drivers/spi/tests/spi-dma-kunit.c | 259 +++++++++++++++++++
tools/testing/kunit/configs/all_tests.config | 1 +
tools/testing/kunit/configs/default.config | 1 +
9 files changed, 340 insertions(+), 42 deletions(-)
create mode 100644 drivers/spi/.kunitconfig
create mode 100644 drivers/spi/tests/Makefile
create mode 100644 drivers/spi/tests/spi-dma-kunit.c
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
--
2.43.0
On Fri, 14 Aug 2026 11:14:14 +0800, Honghui Jiang wrote:
> spi: Fix DMA mapping ownership on partial map failure
>
> A partial DMA mapping failure can leave per-transfer mapping flags set
> while cur_{tx,rx}_dma_dev are NULL or still refer to the devices used
> for an earlier message. The subsequent cleanup may then unmap a
> transfer with a NULL or stale device.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-7.3
Thanks!
[1/4] spi: Fix DMA mapping ownership on partial map failure
https://git.kernel.org/broonie/spi/c/367cea239fc9
[2/4] spi: Move __spi_unmap_msg() before __spi_map_msg()
https://git.kernel.org/broonie/spi/c/b82b2dfc93d3
[3/4] spi: Clear current DMA devices when unmapping a message
https://git.kernel.org/broonie/spi/c/af6aaacd42f7
[4/4] spi: Add KUnit coverage for DMA mapping error paths
https://git.kernel.org/broonie/spi/c/9b81a87c5244
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
On Fri, Aug 14, 2026 at 11:14:14AM +0800, Honghui Jiang wrote:
> A partial DMA mapping failure can leave per-transfer mapping flags set
> while cur_{tx,rx}_dma_dev are NULL or still refer to the devices used
> for an earlier message. The subsequent cleanup may then unmap a
> transfer with a NULL or stale device.
>
> Before commit e289df82344f ("spi: Rework per message DMA mapped flag to
> be per transfer"), partial-failure handling was already incomplete, but
> __spi_unmap_msg() was gated by cur_msg_mapped, which was set only after
> the whole message mapped successfully. Earlier mappings could leak, but
> cleanup could not unmap them with an unpublished device. The
> per-transfer conversion removed that gate: mapping flags can now remain
> set while cur_{tx,rx}_dma_dev are still unpublished, turning the leak
> into a NULL- or stale-device unmap regression.
>
> Patch 1 publishes the mapping devices before the loop and unwinds every
> failure through __spi_unmap_msg(). It keeps the forward declaration so
> it is independently buildable and straightforward to backport. Patch 2
> then removes the declaration by moving __spi_unmap_msg() above
> __spi_map_msg(). Patch 3 clears the current DMA device pointers once the
> message has been unmapped, while leaving them intact during partial-map
> unwind and DMA-to-PIO fallback. Patch 4 adds the DMA mapping KUnit suite
> as a separate translation unit.
>
> Only patch 1 is a stable candidate; patches 2 through 4 are follow-up
> cleanup and test changes for mainline.
>
> Testing:
>
> - Patch 1 builds independently with the x86_64 reproducer configuration.
> - The spi_dma KUnit suite passes all four cases on x86_64 and UML.
> Moving the DMA device assignments back after the mapping loop makes
> both failure-path cases fail.
> - The default and all-tests KUnit configurations both select the suite.
> - All four reproducer cases complete without an oops when run as the
> first message, and map/unmap counts are balanced after a successful
> first message.
> - After message cleanup, cur_{tx,rx}_dma_dev are NULL.
Nice series!
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
with a caveat that there is one stray change in the last patch.
Assumed that in v3 it will be dropped.
--
With Best Regards,
Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.