public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] mm/arm: pgtable: remove young bit check for pte_valid_user
@ 2026-04-09 12:54 Brian Ruley
  2026-04-09 13:56 ` Will Deacon
  2026-04-09 14:15 ` Russell King (Oracle)
  0 siblings, 2 replies; 7+ messages in thread
From: Brian Ruley @ 2026-04-09 12:54 UTC (permalink / raw)
  To: Russell King, Steve Capper, Will Deacon
  Cc: Brian Ruley, Russell King, linux-arm-kernel, linux-kernel

Fixes cache desync, which can cause undefined instruction,
translation and permission faults under heavy memory use.

This is an old bug introduced in commit 1971188aa196 ("ARM: 7985/1: mm:
implement pte_accessible for faulting mappings"), which included a check
for the young bit of a PTE. The underlying assumption was that old pages
are not cached, therefore, `__sync_icache_dcache' could be skipped
entirely.

However, under extreme memory pressure, page migrations happen
frequently and the assumption of uncached "old" pages does not hold.
Especially for systems that do not have swap, the migrated pages are
unequivocally marked old. This presents a problem, as it is possible
for the original page to be immediately mapped to another VA that
happens to share the same cache index in VIPT I-cache (we found this
bug on Cortex-A9). Without cache invalidation, the CPU will see the
old mapping whose physical page can now be used for a different
purpose, as illustrated below:

                Core                      Physical Memory
  +-------------------------------+     +------------------+
  | TLB                           |     |                  |
  |  VA_A 0xb6e6f -> pfn_q        |     | pfn_q: code      |
  +-------------------------------+     +------------------+
  | I-cache                       |
  |  set[VA_A bits] | tag=pfn_q   |
  +-------------------------------+

migrate (kcompactd):
  1. copy pfn_q --> pfn_r
  2. free pfn_q
  3. pte: VA_a -> pfn_r
  4. pte_mkold(pte) --> !young
  5. ICIALLUIS skipped (because !young)

pfn_src reused (OOM pressure):
  pte: VA_B -> pfn_q (different code)

bug:
                Core                      Physical Memory
  +-------------------------------+     +------------------+
  | TLB (empty)                   |     | pfn_r: old code  |
  +-------------------------------+     | pfn_q: new code  |
  | I-cache                       |     +------------------+
  |  set[VA_A bits] | tag=pfn_q   |<--- wrong instructions
  +-------------------------------+

This was verified on ba16-based board (i.MX6Quad/Dual, Cortex-A9) by
instrumenting the migration code to track recently migrated pages in a
ring buffer and then dumping them in the undefined instruction fault
handler. The bug can be triggered with `stress-ng':

  stress-ng --vm 4 --vm-bytes 2G --vm-method zero-one --verify

Note that the system we tested on has only 2G of memory, so the test
triggered the OOM-killer in our case.

Fixes: 1971188aa196 ("ARM: 7985/1: mm: implement pte_accessible for faulting mappings")
Signed-off-by: Brian Ruley <brian.ruley@gehealthcare.com>
---
 arch/arm/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 6fa9acd6a7f5..e3a5b4a9a65f 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -185,7 +185,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 #define pte_exec(pte)		(pte_isclear((pte), L_PTE_XN))
 
 #define pte_valid_user(pte)	\
-	(pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte))
+	(pte_valid(pte) && pte_isset((pte), L_PTE_USER))
 
 static inline bool pte_access_permitted(pte_t pte, bool write)
 {
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-04-09 16:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-09 12:54 [PATCH] mm/arm: pgtable: remove young bit check for pte_valid_user Brian Ruley
2026-04-09 13:56 ` Will Deacon
2026-04-09 14:21   ` Russell King (Oracle)
2026-04-09 14:43   ` Russell King (Oracle)
2026-04-09 15:17   ` Brian Ruley
2026-04-09 16:00     ` Russell King (Oracle)
2026-04-09 14:15 ` Russell King (Oracle)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox