From b0d5cff043ad03524b519ce42723fd08540bfafd Mon Sep 17 00:00:00 2001
From: Nick Hudson <skrll@netbsd.org>
Date: Sun, 24 May 2026 14:13:38 +0100
Subject: [PATCH 2/2] aarch64: mi pmap: save a software bit when doing modify
 emulation.

Use only OS_MODEMUL and release OS_MODIFIED. A mapping is deemed modified
if it is marked RW and OS_MODEMUL which only ever happens via emulation.
---
 sys/arch/aarch64/aarch64/pmap_machdep.c | 11 ++++-------
 sys/arch/aarch64/include/pmap_machdep.h | 23 +++++++++++------------
 2 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/sys/arch/aarch64/aarch64/pmap_machdep.c b/sys/arch/aarch64/aarch64/pmap_machdep.c
index 848b8bac1382..9d7627c5e4a0 100644
--- a/sys/arch/aarch64/aarch64/pmap_machdep.c
+++ b/sys/arch/aarch64/aarch64/pmap_machdep.c
@@ -182,16 +182,13 @@ pmap_fault_fixup(pmap_t pm, vaddr_t va, vm_prot_t ftype, bool user)
 
                 /*
 		 * Enable write permissions for the page by setting the Access
-		 * Flag, marking the page as writeable, and modified (using an
-		 * OS bit).
-		 *
-		 * The MODEMUL bit is also removed as its no longer required.
+		 * Flag, marking the page as writeable. The PTE being writeable
+		 * and OS_MODEMUL indicates it's been modified.
 		 */
 		const pt_entry_t npte =
-		    (opte & ~(LX_BLKPAG_AP | LX_BLKPAG_OS_MODEMUL)) |
+		    (opte & ~LX_BLKPAG_AP) |
 		    LX_BLKPAG_AF |
-		    LX_BLKPAG_AP_RW |
-		    LX_BLKPAG_OS_MODIFIED;
+		    LX_BLKPAG_AP_RW;
 		atomic_swap_64(ptep, npte);
 		// tlb_invalidate_addr does dsb(ishst)
 		tlb_invalidate_addr(va, pai->pai_asid);
diff --git a/sys/arch/aarch64/include/pmap_machdep.h b/sys/arch/aarch64/include/pmap_machdep.h
index d1a6309870af..2f92d7159d1d 100644
--- a/sys/arch/aarch64/include/pmap_machdep.h
+++ b/sys/arch/aarch64/include/pmap_machdep.h
@@ -134,11 +134,10 @@ struct pmap_page {
 
 #define	PVLIST_EMPTY_P(pg)	VM_PAGEMD_PVLIST_EMPTY_P(VM_PAGE_TO_MD(pg))
 
-#define	LX_BLKPAG_OS_MODIFIED	LX_BLKPAG_OS_0
-#define	LX_BLKPAG_OS_MODEMUL	LX_BLKPAG_OS_1
+#define	LX_BLKPAG_OS_MODEMUL	LX_BLKPAG_OS_0
 
-#define	PMAP_PTE_OS0	"modified"
-#define	PMAP_PTE_OS1	"modemul"
+#define	PMAP_PTE_OS0	"modemul"
+#define	PMAP_PTE_OS1	"(unused)"
 
 static inline paddr_t
 pmap_l0pa(struct pmap *pm)
@@ -227,7 +226,8 @@ static inline bool
 pte_modified_p(pt_entry_t pte)
 {
 
-	return (pte & LX_BLKPAG_OS_MODIFIED) != 0;
+	return (pte & (LX_BLKPAG_AP | LX_BLKPAG_OS_MODEMUL)) ==
+	    (LX_BLKPAG_AP_RW | LX_BLKPAG_OS_MODEMUL);
 }
 
 static inline bool
@@ -306,12 +306,10 @@ pte_clear_modify(pt_entry_t pte)
 	/*
 	 * See the table in pte_make_enter.
 	 *
-	 * Set the page RO and MODEMUL, and clear MODIFIED.
-	 *
-	 * Don't touch _AF as ref emulation might have completed.
+	 * Set the page RO and MODEMUL, but don't touch _AF as ref
+	 * emulation might have completed.
 	 */
-	CTASSERT(LX_BLKPAG_OS_MODIFIED == __BIT(55));
-	return (pte & ~(LX_BLKPAG_AP | LX_BLKPAG_OS_MODIFIED)) |
+	return (pte & ~LX_BLKPAG_AP) |
 	    LX_BLKPAG_AP_RO |
 	    LX_BLKPAG_OS_MODEMUL;
 }
@@ -554,8 +552,9 @@ extern int kernhist_print_enabled;
 	}
 	/*
 	 * When doing modified emulation mark page as RO and
-	 * LX_BLKPAG_OS_MODEMUL. A write fault will use MODEMUL to
-	 * fixup the pte and mark the page as modified.
+	 * LX_BLKPAG_OS_MODEMUL. A write fault will use the existance of
+	 * OS_MODEMUL to fixup the pte and mark the page as writeable.
+	 * AP_RW and OS_MODEMUL indicates that is was modified.
 	 *
 	 * When not doing modified emulation mark the page as RO or RW.
 	 */
-- 
2.50.1 (Apple Git-155)

