git: 6d7960628f82 - main - arm64 pmap: demote L3C pages in pmap_clear_modify()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 01 Nov 2026 21:00:00 UTC
The branch main has been updated by alc:
URL: https://cgit.FreeBSD.org/src/commit/?id=6d7960628f825f1eec0959d6000a79ca8a4ae927
commit 6d7960628f825f1eec0959d6000a79ca8a4ae927
Author: Alan Cox <alc@FreeBSD.org>
AuthorDate: 2026-11-01 18:25:05 +0000
Commit: Alan Cox <alc@FreeBSD.org>
CommitDate: 2026-11-01 20:56:44 +0000
arm64 pmap: demote L3C pages in pmap_clear_modify()
When pmap_clear_modify() demotes a dirty L2 block mapping, it write
protects the L3 entry that maps "m", so that a subsequent write access
may repromote. However, since fd6cb031f577, the L3 entries created by
pmap_demote_l2_locked() may have ATTR_CONTIGUOUS set, and
pmap_clear_modify() was write protecting one L3 entry within an L3C page
while leaving the page's other L3 entries writeable with ATTR_CONTIGUOUS
still set. A TLB entry that a processor creates from any of those other
L3 entries may translate "m"'s virtual address and permit writes to "m"
without a fault. To fix this issue, as in pmap_remove_write(), demote
the L3C page before write protecting the L3 entry.
Found by: Claude Code (Opus 5.5)
Fixes: fd6cb031f577 "arm64 pmap: Add ATTR_CONTIGUOUS support [Part 1]"
MFC after: 1 week
---
sys/arm64/arm64/pmap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index f27ddd379976..6ed49f051ac5 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -8369,6 +8369,8 @@ restart:
*/
va += VM_PAGE_TO_PHYS(m) - PTE_TO_PHYS(oldl2);
l3 = pmap_l2_to_l3(l2, va);
+ if ((pmap_load(l3) & ATTR_CONTIGUOUS) != 0)
+ (void)pmap_demote_l3c(pmap, l3, va);
oldl3 = pmap_load(l3);
while (!atomic_fcmpset_long(l3, &oldl3,
(oldl3 & ~ATTR_SW_DBM) | ATTR_S1_AP(ATTR_S1_AP_RO)))