Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
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 2/2] ARM: dma-mapping: flush FROM_DEVICE buffers on legacy backends
Date: Thu, 10 Sep 2026 08:36:20 +0200	[thread overview]
Message-ID: <20260910063620.17768-3-kmehltretter@gmail.com> (raw)
In-Reply-To: <20260910063620.17768-1-kmehltretter@gmail.com>

The legacy write-back cache backends invalidate DMA_FROM_DEVICE buffers
when ownership passes to the device. A plain invalidate can discard dirty
CPU cache lines. If the device writes only part of the buffer, untouched
bytes can expose memory contents older than those present at the handoff.

This was reproduced on the ARM926EJ-S (ARMv5TEJ) in a SAM9X75. A
mapping-only test lost 339,936 to 351,744 of 409,600 CPU-written bytes per
100-iteration run. In a separate usbfs test, a webcam returned short
isochronous packets into a buffer that usbfs had cleared. Across five
boots, the existing kernel exposed 29,403 non-zero bytes among 245,708
unwritten gap bytes to userspace.

With this change, five fresh 100-iteration runs on the same SAM9X75 board
each lost 0 of 409,600 bytes.

Use the existing clean-and-invalidate operation for DMA_FROM_DEVICE at
device handoff. The cache lines remain invalid after the handoff, but dirty
CPU data reaches memory first. Keep the existing no-op ownership-return
hooks. These backends already use the same operation for
DMA_BIDIRECTIONAL.

The XScale 80200 A0/A1 path already uses clean-and-invalidate for this case
and remains unchanged.

Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 arch/arm/mm/cache-fa.S      | 1 -
 arch/arm/mm/cache-v4wb.S    | 1 -
 arch/arm/mm/proc-arm1020.S  | 1 -
 arch/arm/mm/proc-arm1020e.S | 1 -
 arch/arm/mm/proc-arm1022.S  | 1 -
 arch/arm/mm/proc-arm1026.S  | 1 -
 arch/arm/mm/proc-arm920.S   | 1 -
 arch/arm/mm/proc-arm922.S   | 1 -
 arch/arm/mm/proc-arm925.S   | 1 -
 arch/arm/mm/proc-arm926.S   | 1 -
 arch/arm/mm/proc-arm940.S   | 1 -
 arch/arm/mm/proc-arm946.S   | 1 -
 arch/arm/mm/proc-feroceon.S | 2 --
 arch/arm/mm/proc-mohawk.S   | 1 -
 arch/arm/mm/proc-xsc3.S     | 1 -
 arch/arm/mm/proc-xscale.S   | 1 -
 16 files changed, 17 deletions(-)

diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index e1641799569b..1ff3d66fe944 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -232,7 +232,6 @@ SYM_TYPED_FUNC_START(fa_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	fa_dma_clean_range
-	bcs	fa_dma_inv_range
 	b	fa_dma_flush_range
 SYM_FUNC_END(fa_dma_map_area)
 
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index 874fe5310f9a..87036c8bb318 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -244,7 +244,6 @@ SYM_TYPED_FUNC_START(v4wb_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	v4wb_dma_clean_range
-	bcs	v4wb_dma_inv_range
 	b	v4wb_dma_flush_range
 SYM_FUNC_END(v4wb_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 4612a4961e81..c79f3c3e47a0 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -350,7 +350,6 @@ SYM_TYPED_FUNC_START(arm1020_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm1020_dma_clean_range
-	bcs	arm1020_dma_inv_range
 	b	arm1020_dma_flush_range
 SYM_FUNC_END(arm1020_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index b4a8a3a8eda3..a117e26e4763 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -337,7 +337,6 @@ SYM_TYPED_FUNC_START(arm1020e_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm1020e_dma_clean_range
-	bcs	arm1020e_dma_inv_range
 	b	arm1020e_dma_flush_range
 SYM_FUNC_END(arm1020e_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 709870e99e19..63b4992f8ad2 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -336,7 +336,6 @@ SYM_TYPED_FUNC_START(arm1022_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm1022_dma_clean_range
-	bcs	arm1022_dma_inv_range
 	b	arm1022_dma_flush_range
 SYM_FUNC_END(arm1022_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 02f7370a8c5c..c5e50395473b 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -331,7 +331,6 @@ SYM_TYPED_FUNC_START(arm1026_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm1026_dma_clean_range
-	bcs	arm1026_dma_inv_range
 	b	arm1026_dma_flush_range
 SYM_FUNC_END(arm1026_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 0326067c6c75..e30b013432f0 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -299,7 +299,6 @@ SYM_TYPED_FUNC_START(arm920_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm920_dma_clean_range
-	bcs	arm920_dma_inv_range
 	b	arm920_dma_flush_range
 SYM_FUNC_END(arm920_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 3fe6fdf0d325..b1ace8c664e2 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -301,7 +301,6 @@ SYM_TYPED_FUNC_START(arm922_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm922_dma_clean_range
-	bcs	arm922_dma_inv_range
 	b	arm922_dma_flush_range
 SYM_FUNC_END(arm922_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 2d15467e4a08..3d91d16e4af0 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -357,7 +357,6 @@ SYM_TYPED_FUNC_START(arm925_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm925_dma_clean_range
-	bcs	arm925_dma_inv_range
 	b	arm925_dma_flush_range
 SYM_FUNC_END(arm925_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index d94aa8199452..bd335d703590 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -320,7 +320,6 @@ SYM_TYPED_FUNC_START(arm926_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm926_dma_clean_range
-	bcs	arm926_dma_inv_range
 	b	arm926_dma_flush_range
 SYM_FUNC_END(arm926_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 545c076c36d2..ba7158639ab7 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -264,7 +264,6 @@ SYM_TYPED_FUNC_START(arm940_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm940_dma_clean_range
-	bcs	arm940_dma_inv_range
 	b	arm940_dma_flush_range
 SYM_FUNC_END(arm940_dma_map_area)
 
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index f3d4e18c3fba..a135c654b854 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -306,7 +306,6 @@ SYM_TYPED_FUNC_START(arm946_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	arm946_dma_clean_range
-	bcs	arm946_dma_inv_range
 	b	arm946_dma_flush_range
 SYM_FUNC_END(arm946_dma_map_area)
 
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 7f08d06c9625..dbaf01ba7cb5 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -391,7 +391,6 @@ SYM_TYPED_FUNC_START(feroceon_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	feroceon_dma_clean_range
-	bcs	feroceon_dma_inv_range
 	b	feroceon_dma_flush_range
 SYM_FUNC_END(feroceon_dma_map_area)
 
@@ -405,7 +404,6 @@ SYM_TYPED_FUNC_START(feroceon_range_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	feroceon_range_dma_clean_range
-	bcs	feroceon_range_dma_inv_range
 	b	feroceon_range_dma_flush_range
 SYM_FUNC_END(feroceon_range_dma_map_area)
 
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 4669c63e3121..7df85a32f7b5 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -287,7 +287,6 @@ SYM_TYPED_FUNC_START(mohawk_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	mohawk_dma_clean_range
-	bcs	mohawk_dma_inv_range
 	b	mohawk_dma_flush_range
 SYM_FUNC_END(mohawk_dma_map_area)
 
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index fd25634a2ed5..6c5910bcc211 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -332,7 +332,6 @@ SYM_TYPED_FUNC_START(xsc3_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	xsc3_dma_clean_range
-	bcs	xsc3_dma_inv_range
 	b	xsc3_dma_flush_range
 SYM_FUNC_END(xsc3_dma_map_area)
 
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index d8462df8020b..86422559d91e 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -390,7 +390,6 @@ SYM_TYPED_FUNC_START(xscale_dma_map_area)
 	add	r1, r1, r0
 	cmp	r2, #DMA_TO_DEVICE
 	beq	xscale_dma_clean_range
-	bcs	xscale_dma_inv_range
 	b	xscale_dma_flush_range
 SYM_FUNC_END(xscale_dma_map_area)
 
-- 
2.53.0


  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 ` [PATCH 1/2] ARM: dma-mapping: " Karl Mehltretter
2026-09-10  6:36 ` Karl Mehltretter [this message]
2026-09-12  6:55   ` [PATCH 2/2] ARM: dma-mapping: flush FROM_DEVICE buffers on legacy backends 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-3-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