git: 7d7295df9b13 - main - arm64: Add MOPS implementation of pagezero()

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Tue, 10 Feb 2026 15:43:33 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=7d7295df9b13b98ac395b206667e7586c602862b

commit 7d7295df9b13b98ac395b206667e7586c602862b
Author:     Sarah Walker <sarah.walker2@arm.com>
AuthorDate: 2026-01-29 17:43:45 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-02-10 15:39:56 +0000

    arm64: Add MOPS implementation of pagezero()
    
    Reimplement pagezero() as ifunc. As pagezero() is only used in pmap.c,
    move ifunc to that file.
    
    Reviewed by:    andrew
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D54946
---
 sys/arm64/arm64/machdep.c   | 10 ----------
 sys/arm64/arm64/pmap.c      | 22 ++++++++++++++++++++++
 sys/arm64/arm64/support.S   | 12 ++++++++++++
 sys/arm64/include/machdep.h |  1 -
 4 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index ffe9acb0cfa4..2addc5af9568 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -155,13 +155,6 @@ uintptr_t socdev_va __read_mostly;
 vm_paddr_t efi_systbl_phys;
 static struct efi_map_header *efihdr;
 
-/* pagezero_* implementations are provided in support.S */
-void pagezero_simple(void *);
-void pagezero_cache(void *);
-
-/* pagezero_simple is default pagezero */
-void (*pagezero)(void *p) = pagezero_simple;
-
 int (*apei_nmi)(void);
 
 #if defined(PERTHREAD_SSP_WARNING)
@@ -720,9 +713,6 @@ cache_setup(void)
 		/* Same as with above calculations */
 		dczva_line_shift = DCZID_BS_SIZE(dczid_el0);
 		dczva_line_size = sizeof(int) << dczva_line_shift;
-
-		/* Change pagezero function */
-		pagezero = pagezero_cache;
 	}
 }
 
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index e865569ac377..0cfc8ae80d70 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -147,6 +147,8 @@
 
 #include <machine/asan.h>
 #include <machine/cpu_feat.h>
+#include <machine/elf.h>
+#include <machine/ifunc.h>
 #include <machine/machdep.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
@@ -529,6 +531,7 @@ static void *bti_dup_range(void *ctx, void *data);
 static void bti_free_range(void *ctx, void *node);
 static int pmap_bti_copy(pmap_t dst_pmap, pmap_t src_pmap);
 static void pmap_bti_deassign_all(pmap_t pmap);
+static void pagezero(void *);
 
 /*
  * These load the old table data and store the new value.
@@ -10207,3 +10210,22 @@ SYSCTL_OID(_vm_pmap, OID_AUTO, kernel_maps,
     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_SKIP,
     NULL, 0, sysctl_kmaps, "A",
     "Dump kernel address layout");
+
+
+void pagezero_simple(void *);
+void pagezero_cache(void *);
+void pagezero_mops(void *);
+
+DEFINE_IFUNC(static, void, pagezero, (void *))
+{
+	uint32_t dczid_el0;
+
+	dczid_el0 = READ_SPECIALREG(dczid_el0);
+
+	if (elf_hwcap2 & HWCAP2_MOPS)
+		return (pagezero_mops);
+	else if ((dczid_el0 & DCZID_DZP) == 0)
+		return (pagezero_cache);
+	else
+		return (pagezero_simple);
+}
diff --git a/sys/arm64/arm64/support.S b/sys/arm64/arm64/support.S
index bf6fc931e4b0..cee0e3b51aaf 100644
--- a/sys/arm64/arm64/support.S
+++ b/sys/arm64/arm64/support.S
@@ -397,4 +397,16 @@ ENTRY(pagezero_cache)
 
 END(pagezero_cache)
 
+/*
+ * pagezero, MOPS implementation
+ */
+ENTRY(pagezero_mops)
+	mov	x1, #PAGE_SIZE
+	.inst   0x19df0420      /* setp    [x0]!, x1!, xzr  */
+	.inst   0x19df4420      /* setm    [x0]!, x1!, xzr  */
+	.inst   0x19df8420      /* sete    [x0]!, x1!, xzr  */
+	ret
+
+END(pagezero_mops)
+
 GNU_PROPERTY_AARCH64_FEATURE_1_NOTE(GNU_PROPERTY_AARCH64_FEATURE_1_VAL)
diff --git a/sys/arm64/include/machdep.h b/sys/arm64/include/machdep.h
index 4fa80219da42..3606690eb9ba 100644
--- a/sys/arm64/include/machdep.h
+++ b/sys/arm64/include/machdep.h
@@ -54,7 +54,6 @@ vm_offset_t parse_boot_param(struct arm64_bootparams *abp);
 void parse_fdt_bootargs(void);
 #endif
 int memory_mapping_mode(vm_paddr_t pa);
-extern void (*pagezero)(void *);
 
 #ifdef SOCDEV_PA
 /*