Re: [PATCH 0/2] ARM: preserve DMA_FROM_DEVICE buffer contents
From: Arnd Bergmann
Date: Thu Sep 10 2026 - 06:01:36 EST
On Thu, Sep 10, 2026, at 08:36, Karl Mehltretter wrote:
> This series prevents a DMA_FROM_DEVICE map from discarding CPU-written
> buffer contents on non-coherent 32-bit ARM. It is based on
> v7.3-rc1-324-g986c24e0fe44.
>
> ARM currently invalidates these buffers before the device writes them.
> If the device writes only part of a buffer, discarded dirty cache lines
> can expose older memory contents in the untouched bytes. A stock USB
> webcam demonstrated this through usbfs. Short isochronous packets left
> gaps, and usbfs returned non-zero data to userspace from bytes it had
> cleared.
>
> arm64 changed this handoff from invalidate to clean in 2022 with commit
> c50f11c6196f ("arm64: mm: Don't invalidate FROM_DEVICE buffers at start
> of DMA transfer"). Arnd Bergmann's 2023 ARM32 cache-maintenance series
> left DMA_FROM_DEVICE preservation unresolved [1]. This series keeps the
> existing ownership hooks.
Hi Karl,
I think the main problem here is that we remain inconsistent about the
rules across CPU architectures, and changing Arm on its own does not
mean we have a solution if another architecture decides to change it
in the opposite direction at some point.
I see this as a tradeoff that can go either way:
- the current 32-bit Arm approach (also arc, hexagon, microblaze, mips,
nios2, openrisc, powerpc32, sh) is obviously faster as it avoids
the writeback, but it relies on device drivers to ensure no stale
data can leak back into userspace.
- Will's patch changed arm64 (later copied into riscv) to avoid that
risk by adding the overhead out of caution, and avoid having to
audit and fix all drivers.
Clearly the current state is suboptimal, as most drivers are shared
across architectures and should expect a clear interface. Portable
drivers now get extra overhead on arm64/riscv for doing both the
zero-pad and writeback.
If we decide to align with arm64/riscv and take your series, I think
we need two more parts:
- actually measure the performance overhead: you already did the
work to test this on three separate arm implementations but did
not share performance numbers.
Can you quantify how much this costs us on the hardware you used?
- change the remaining architectures the same way: right now, both
variants are common enough across supported embedded systems
on all architectures, but changing over arm32 means that all
only a vanishingly small set of users gets the invalidate-only
version and we're much more likely to miss future driver bugs
when driver writes assume the arm/riscv behavior is universal.
Arnd