[PATCH 0/2] ARM: preserve DMA_FROM_DEVICE buffer contents

Arnd Bergmann arnd at arndb.de
Thu Sep 10 02:14:28 PDT 2026


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



More information about the linux-arm-kernel mailing list