All of lore.kernel.org
 help / color / mirror / Atom feed
From: Magnus Lindholm <linmag7@gmail.com>
To: davem@davemloft.net, andreas@gaisler.com
Cc: sparclinux@vger.kernel.org, linux-kernel@vger.kernel.org,
	linmag7@gmail.com, stable@vger.kernel.org
Subject: [PATCH 4/9] sparc32: flush the cache when a kmap_local mapping is installed
Date: Sun,  8 Nov 2026 23:34:14 +0100	[thread overview]
Message-ID: <20261108223516.1125534-5-linmag7@gmail.com> (raw)
In-Reply-To: <20261108223516.1125534-1-linmag7@gmail.com>

sparc32 defines arch_kmap_local_pre_map() as flush_cache_all(), but
generic highmem has never called that hook. The post-conversion flush
correction moved cache maintenance into this uncalled hook, so a new kmap
can be installed while another mapping of the same page still holds dirty
lines at a different colour.

A writer dirties a MAP_SHARED page through its user mapping on one cpu
while a reader pread()s the same offset on another: on an SS-20 with two
RT626 modules all 100 iterations came back stale, 96288 words wrong. With
the flush restored, 0 of 100.

Flush from arch_kmap_local_post_map(), which generic code does call, on
both the map and the scheduler restore paths. Running after the pte is
installed is safe: the address is not handed to the caller until the hook
returns. Route it and the tlb flush through sparc32_kmap_local_post_map()
and sparc32_kmap_local_tlb_flush() so later patches have somewhere for a
cpu-specific policy.

MBus supplies only optional VA[19:12] "super-set" bits to a virtually
indexed cache, so differing colours remain a synonym problem the bus does
not resolve.

Reference: MBus Interface Specification, SPARC International, 1997, "Basic
Assumptions for Level 2", signal VA[19:12] (MAD[53:46]).

Retain global TLB invalidation. Although the slots are CPU-local, remote
translating cache backends can populate entries for them. Local TLB
maintenance requires those remote translating users to be removed first
and belongs in the later HyperSPARC optimization.

Fixes: f99e02372af2 ("sparc/mm/highmem: flush cache and TLB")
Cc: stable@vger.kernel.org
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
 arch/sparc/include/asm/highmem.h | 14 ++++++++++----
 arch/sparc/mm/srmmu.c            | 21 +++++++++++++++++++++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h
index b1b915ac604d..14b03f348823 100644
--- a/arch/sparc/include/asm/highmem.h
+++ b/arch/sparc/include/asm/highmem.h
@@ -26,6 +26,10 @@
 #include <asm/vaddrs.h>
 #include <asm/pgtsrmmu.h>
 
+void sparc32_kmap_local_cache_flush(unsigned long vaddr);
+void sparc32_kmap_local_tlb_flush(unsigned long vaddr);
+void sparc32_kmap_local_post_map(unsigned long vaddr, pte_t pteval);
+
 #define kmap_prot __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE)
 extern pte_t *pkmap_page_table;
 
@@ -48,10 +52,12 @@ extern pte_t *pkmap_page_table;
 #define flush_cache_kmaps()	flush_cache_all()
 
 /* FIXME: Use __flush_*_one(vaddr) instead of flush_*_all() -- Anton */
-#define arch_kmap_local_pre_map(vaddr, pteval)	flush_cache_all()
-#define arch_kmap_local_pre_unmap(vaddr)	flush_cache_all()
-#define arch_kmap_local_post_map(vaddr, pteval)	flush_tlb_all()
-#define arch_kmap_local_post_unmap(vaddr)	flush_tlb_all()
+#define arch_kmap_local_pre_unmap(vaddr) \
+	sparc32_kmap_local_cache_flush(vaddr)
+#define arch_kmap_local_post_map(vaddr, pteval) \
+	sparc32_kmap_local_post_map(vaddr, pteval)
+#define arch_kmap_local_post_unmap(vaddr) \
+	sparc32_kmap_local_tlb_flush(vaddr)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 49d41b33aabf..aa53ec10cd8a 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -88,6 +88,27 @@ static int is_hypersparc;
 
 static int srmmu_cache_pagetables;
 
+void sparc32_kmap_local_cache_flush(unsigned long vaddr)
+{
+	flush_cache_all();
+}
+
+/*
+ * Nothing has touched the new mapping yet, so flushing other aliases of this
+ * page here is as good as doing it before the pte was set.
+ */
+void sparc32_kmap_local_post_map(unsigned long vaddr, pte_t pteval)
+{
+	sparc32_kmap_local_cache_flush(vaddr);
+	sparc32_kmap_local_tlb_flush(vaddr);
+}
+
+void sparc32_kmap_local_tlb_flush(unsigned long vaddr)
+{
+	/* Remote translating cache operations can populate these entries. */
+	flush_tlb_all();
+}
+
 /* these will be initialized in srmmu_nocache_calcsize() */
 static unsigned long srmmu_nocache_size;
 static unsigned long srmmu_nocache_end;
-- 
2.43.0


  parent reply	other threads:[~2026-11-08 22:36 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-08 22:34 [PATCH 0/9] sparc32: repair cache hooks, mappings and TLB tracking Magnus Lindholm
2026-11-08 22:34 ` [PATCH 1/9] sparc32: inspect every PROM CPU cache geometry Magnus Lindholm
2026-11-08 22:34 ` [PATCH 2/9] sparc32: flush the source user alias in copy_user_highpage() Magnus Lindholm
2026-11-08 23:02   ` sashiko-bot
2026-11-08 22:34 ` [PATCH 3/9] sparc32: do not flush a NULL address in flush_dcache_folio Magnus Lindholm
2026-11-08 22:34 ` Magnus Lindholm [this message]
2026-11-08 22:34 ` [PATCH 5/9] sparc32: preset modified and referenced bits in kmap PTEs Magnus Lindholm
2026-11-08 22:34 ` [PATCH 6/9] sparc32: colour-align private file mappings Magnus Lindholm
2026-11-08 22:34 ` [PATCH 7/9] sparc32: implement flush_anon_page Magnus Lindholm
2026-11-08 22:34 ` [PATCH 8/9] sparc32: retain mm_cpumask across TLB shootdowns Magnus Lindholm
2026-11-08 22:34 ` [PATCH 9/9] sparc32: enroll and order CPUs before switching address spaces Magnus Lindholm

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=20261108223516.1125534-5-linmag7@gmail.com \
    --to=linmag7@gmail.com \
    --cc=andreas@gaisler.com \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sparclinux@vger.kernel.org \
    --cc=stable@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.