From: Karl Mehltretter <kmehltretter@gmail.com>
To: Russell King <linux@armlinux.org.uk>
Cc: Karl Mehltretter <kmehltretter@gmail.com>,
Hans Ulli Kroll <ulli.kroll@googlemail.com>,
Robin Murphy <robin.murphy@arm.com>,
Marek Szyprowski <m.szyprowski@samsung.com>,
Will Deacon <will@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Christoph Hellwig <hch@lst.de>,
Linus Walleij <linus.walleij@linaro.org>,
Ard Biesheuvel <ardb@kernel.org>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH 1/2] ARM: dma-mapping: preserve DMA_FROM_DEVICE buffer contents
Date: Thu, 10 Sep 2026 08:36:19 +0200 [thread overview]
Message-ID: <20260910063620.17768-2-kmehltretter@gmail.com> (raw)
In-Reply-To: <20260910063620.17768-1-kmehltretter@gmail.com>
The v6, v7 and v7-M cache backends invalidate DMA_FROM_DEVICE buffers
when ownership passes to the device. The common outer-cache path does
the same. On a write-back cache, invalidating a dirty line can discard
CPU-written data. If the device writes only part of the buffer, the
untouched bytes can expose memory contents older than those present at
the handoff.
A mapping-only test on an ARM11 MPCore (ARMv6) system reproduced this
through the v6 path. The existing code lost 402,080 of 409,600
CPU-written bytes over 100 iterations. This change lost none.
Clean the inner and outer cache lines for the buffer at handoff. The
existing completion path still invalidates them before the CPU reads the
buffer. This matches arm64 commit c50f11c6196f ("arm64: mm: Don't
invalidate FROM_DEVICE buffers at start of DMA transfer") and adds no
cache traversal.
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20220606152150.GA31568@willie-the-truck
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
arch/arm/mm/cache-v6.S | 2 --
arch/arm/mm/cache-v7.S | 2 --
arch/arm/mm/cache-v7m.S | 2 --
arch/arm/mm/dma-mapping-nommu.c | 5 +----
arch/arm/mm/dma-mapping.c | 8 +-------
5 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 5ceea8965ea1..149042bac423 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -283,8 +283,6 @@ SYM_FUNC_END(v6_dma_flush_range)
*/
SYM_TYPED_FUNC_START(v6_dma_map_area)
add r1, r1, r0
- teq r2, #DMA_FROM_DEVICE
- beq v6_dma_inv_range
b v6_dma_clean_range
SYM_FUNC_END(v6_dma_map_area)
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 726681fb7d4d..22897f98cc95 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -441,8 +441,6 @@ SYM_FUNC_END(v7_dma_flush_range)
*/
SYM_TYPED_FUNC_START(v7_dma_map_area)
add r1, r1, r0
- teq r2, #DMA_FROM_DEVICE
- beq v7_dma_inv_range
b v7_dma_clean_range
SYM_FUNC_END(v7_dma_map_area)
diff --git a/arch/arm/mm/cache-v7m.S b/arch/arm/mm/cache-v7m.S
index 7f9cfad2ea21..3ea5f047f43e 100644
--- a/arch/arm/mm/cache-v7m.S
+++ b/arch/arm/mm/cache-v7m.S
@@ -432,8 +432,6 @@ SYM_FUNC_END(v7m_dma_flush_range)
*/
SYM_TYPED_FUNC_START(v7m_dma_map_area)
add r1, r1, r0
- teq r2, #DMA_FROM_DEVICE
- beq v7m_dma_inv_range
b v7m_dma_clean_range
SYM_FUNC_END(v7m_dma_map_area)
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index c6a70686507b..a396bbceee73 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -18,10 +18,7 @@ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
{
dmac_map_area(__va(paddr), size, dir);
- if (dir == DMA_FROM_DEVICE)
- outer_inv_range(paddr, paddr + size);
- else
- outer_clean_range(paddr, paddr + size);
+ outer_clean_range(paddr, paddr + size);
}
void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7761099dde9e..e2df8b680bd6 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -681,18 +681,12 @@ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
{
dma_cache_maint_page(paddr, size, dir, dmac_map_area);
- if (dir == DMA_FROM_DEVICE) {
- outer_inv_range(paddr, paddr + size);
- } else {
- outer_clean_range(paddr, paddr + size);
- }
- /* FIXME: non-speculating: flush on bidirectional mappings? */
+ outer_clean_range(paddr, paddr + size);
}
void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
- /* FIXME: non-speculating: not required */
/* in any case, don't bother invalidating if DMA to device */
if (dir != DMA_TO_DEVICE) {
outer_inv_range(paddr, paddr + size);
--
2.53.0
next prev parent reply other threads:[~2026-09-10 6:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 6:36 [PATCH 0/2] ARM: preserve DMA_FROM_DEVICE buffer contents Karl Mehltretter
2026-09-10 6:36 ` Karl Mehltretter [this message]
2026-09-10 6:36 ` [PATCH 2/2] ARM: dma-mapping: flush FROM_DEVICE buffers on legacy backends Karl Mehltretter
2026-09-12 6:55 ` Karl Mehltretter
2026-09-10 6:48 ` [PATCH 0/2] ARM: preserve DMA_FROM_DEVICE buffer contents Karl Mehltretter
2026-09-10 9:14 ` Arnd Bergmann
2026-09-10 10:55 ` Will Deacon
2026-09-10 13:15 ` Arnd Bergmann
2026-09-12 6:59 ` Karl Mehltretter
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=20260910063620.17768-2-kmehltretter@gmail.com \
--to=kmehltretter@gmail.com \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=hch@lst.de \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=m.szyprowski@samsung.com \
--cc=robin.murphy@arm.com \
--cc=stable@vger.kernel.org \
--cc=ulli.kroll@googlemail.com \
--cc=will@kernel.org \
/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