git: 61d0cea4c00f - releng/14.3 - arm64: Workaround the following errata

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 09 Jun 2026 19:18:41 UTC
The branch releng/14.3 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=61d0cea4c00fd48ca9cedfd788a58105948aff78

commit 61d0cea4c00fd48ca9cedfd788a58105948aff78
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2026-05-29 08:31:10 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-06-07 17:48:17 +0000

    arm64: Workaround the following errata
    
     - ARM C1-Premium erratum 4193780
     - ARM C1-Ultra erratum 4193780
     - ARM Cortex-A76 erratum 4193800
     - ARM Cortex-A76AE erratum 4193801
     - ARM Cortex-A77 erratum 4193798
     - ARM Cortex-A78 erratum 4193791
     - ARM Cortex-A78AE erratum 4193793
     - ARM Cortex-A78C erratum 4193794
     - ARM Cortex-A710 erratum 4193788
     - ARM Cortex-X1 erratum 4193791
     - ARM Cortex-X1C erratum 4193792
     - ARM Cortex-X2 erratum 4193788
     - ARM Cortex-X3 erratum 4193786
     - ARM Cortex-X4 erratum 4118414
     - ARM Cortex-X925 erratum 4193781
     - ARM Neoverse-N1 erratum 4193800
     - ARM Neoverse-N2 erratum 4193789
     - ARM Neoverse-V1 erratum 4193790
     - ARM Neoverse-V2 erratum 4193787
     - ARM Neoverse-V3 erratum 4193784
     - ARM Neoverse-V3AE erratum 4193784
    
    These are all variants on an erratum where TLBI+DSB instructions on
    one CPU may incorrectly complete early leading to stores to an updated
    address using an incorrect translation on another CPU.
    
    In all cases the workaround is to add a second TLBI+DSB.
    
    Sponsored by:   Arm Ltd
    
    arm64: Add more CPU MIDR values
    
    Found in Linux and https://github.com/arm-software/data
    
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D50726
    
    (cherry picked from commit 124b5dbf5c09a17251b75f6b96c9ab7b218eee7f)
    (cherry picked from commit 935f00c4ddf6c0e90752e7017e1d8d165e0796a1)
    
    arm64: Add the new C1 CPU IDs
    
    Add the Arm C1-Nano, C1-Pro, C1-Premium, and C1-Ultra CPUs from their
    Technical Reference Manuals.
    
    Sponsored by:   Arm Ltd
    
    (cherry picked from commit 8fee6b9ecc84d3602a461f1cd33df91e50849cdf)
    (cherry picked from commit 25ff471f0bbcf5b489678e9f94877386366dc521)
    
    Approved by:    so
    Security:       FreeBSD-SA-26:31.arm64
    Security:       CVE-2025-10263
---
 sys/arm64/arm64/pmap.c  | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
 sys/arm64/include/cpu.h | 24 ++++++++++++++-
 2 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index a5d037d7b71c..91b4942b4345 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -183,6 +183,8 @@
 #define	PMAP_SAN_PTE_BITS	(ATTR_DEFAULT | ATTR_S1_XN |	\
 	ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | ATTR_S1_AP(ATTR_S1_AP_RW))
 
+static bool __read_mostly pmap_multiple_tlbi = false;
+
 struct pmap_large_md_page {
 	struct rwlock   pv_lock;
 	struct md_page  pv_page;
@@ -1534,6 +1536,71 @@ pmap_init_pv_table(void)
 	}
 }
 
+
+static void
+pmap_init_multiple_tlbi(void *dummy __unused)
+{
+	u_int cpu, midr;
+
+	CPU_FOREACH(cpu) {
+		midr = pcpu_find(cpu)->pc_midr;
+
+		/*
+		 * ARM C1-Premium erratum 4193780
+		 * ARM C1-Ultra erratum 4193780
+		 * ARM Cortex-A76 erratum 4193800
+		 * ARM Cortex-A76AE erratum 4193801
+		 * ARM Cortex-A77 erratum 4193798
+		 * ARM Cortex-A78 erratum 4193791
+		 * ARM Cortex-A78AE erratum 4193793
+		 * ARM Cortex-A78C erratum 4193794
+		 * ARM Cortex-A710 erratum 4193788
+		 * ARM Cortex-X1 erratum 4193791
+		 * ARM Cortex-X1C erratum 4193792
+		 * ARM Cortex-X2 erratum 4193788
+		 * ARM Cortex-X3 erratum 4193786
+		 * ARM Cortex-X4 erratum 4118414
+		 * ARM Cortex-X925 erratum 4193781
+		 * ARM Neoverse-N1 erratum 4193800
+		 * ARM Neoverse-N2 erratum 4193789
+		 * ARM Neoverse-V1 erratum 4193790
+		 * ARM Neoverse-V2 erratum 4193787
+		 * ARM Neoverse-V3 erratum 4193784
+		 * ARM Neoverse-V3AE erratum 4193784
+		 * Present in all revisions
+		 */
+		if (CPU_IMPL(midr) == CPU_IMPL_ARM) {
+			switch(CPU_PART(midr)) {
+			case CPU_PART_C1_PREMIUM:
+			case CPU_PART_C1_ULTRA:
+			case CPU_PART_CORTEX_A76:
+			case CPU_PART_CORTEX_A76AE:
+			case CPU_PART_CORTEX_A77:
+			case CPU_PART_CORTEX_A78:
+			case CPU_PART_CORTEX_A78AE:
+			case CPU_PART_CORTEX_A78C:
+			case CPU_PART_CORTEX_A710:
+			case CPU_PART_CORTEX_X1:
+			case CPU_PART_CORTEX_X1C:
+			case CPU_PART_CORTEX_X2:
+			case CPU_PART_CORTEX_X3:
+			case CPU_PART_CORTEX_X4:
+			case CPU_PART_CORTEX_X925:
+			case CPU_PART_NEOVERSE_N1:
+			case CPU_PART_NEOVERSE_N2:
+			case CPU_PART_NEOVERSE_V1:
+			case CPU_PART_NEOVERSE_V2:
+			case CPU_PART_NEOVERSE_V3:
+			case CPU_PART_NEOVERSE_V3AE:
+				pmap_multiple_tlbi = true;
+				return;
+			}
+		}
+	}
+}
+SYSINIT(pmap_init_multiple_tlbi, SI_SUB_CPU, SI_ORDER_ANY,
+    pmap_init_multiple_tlbi, NULL);
+
 /*
  *	Initialize the pmap module.
  *
@@ -1652,6 +1719,10 @@ pmap_s1_invalidate_page(pmap_t pmap, vm_offset_t va, bool final_only)
 		r |= ASID_TO_OPERAND(COOKIE_TO_ASID(pmap->pm_cookie));
 		pmap_s1_invalidate_user(r, final_only);
 	}
+	if (pmap_multiple_tlbi) {
+		dsb(ish);
+		__asm __volatile("tlbi	vale1is, xzr" ::: "memory");
+	}
 	dsb(ish);
 	isb();
 }
@@ -1699,6 +1770,10 @@ pmap_s1_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
 		for (r = start; r < end; r += TLBI_VA_L3_INCR)
 			pmap_s1_invalidate_user(r, final_only);
 	}
+	if (pmap_multiple_tlbi) {
+		dsb(ish);
+		__asm __volatile("tlbi	vale1is, xzr" ::: "memory");
+	}
 	dsb(ish);
 	isb();
 }
@@ -1740,6 +1815,10 @@ pmap_s1_invalidate_all(pmap_t pmap)
 		r = ASID_TO_OPERAND(COOKIE_TO_ASID(pmap->pm_cookie));
 		__asm __volatile("tlbi aside1is, %0" : : "r" (r));
 	}
+	if (pmap_multiple_tlbi) {
+		dsb(ish);
+		__asm __volatile("tlbi	vale1is, xzr" ::: "memory");
+	}
 	dsb(ish);
 	isb();
 }
diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h
index 0701a75d17f7..dbb92d75dd85 100644
--- a/sys/arm64/include/cpu.h
+++ b/sys/arm64/include/cpu.h
@@ -77,6 +77,7 @@
 #define	CPU_IMPL_CAVIUM		0x43
 #define	CPU_IMPL_DEC		0x44
 #define	CPU_IMPL_FUJITSU	0x46
+#define	CPU_IMPL_HISILICON	0x48
 #define	CPU_IMPL_INFINEON	0x49
 #define	CPU_IMPL_FREESCALE	0x4D
 #define	CPU_IMPL_NVIDIA		0x4E
@@ -86,6 +87,7 @@
 #define	CPU_IMPL_APPLE		0x61
 #define	CPU_IMPL_INTEL		0x69
 #define	CPU_IMPL_AMPERE		0xC0
+#define	CPU_IMPL_MICROSOFT	0x6D
 
 /* ARM Part numbers */
 #define	CPU_PART_FOUNDATION	0xD00
@@ -105,6 +107,7 @@
 #define	CPU_PART_AEM_V8		0xD0F
 #define	CPU_PART_NEOVERSE_V1	0xD40
 #define	CPU_PART_CORTEX_A78	0xD41
+#define	CPU_PART_CORTEX_A78AE	0xD42
 #define	CPU_PART_CORTEX_A65AE	0xD43
 #define	CPU_PART_CORTEX_X1	0xD44
 #define	CPU_PART_CORTEX_A510	0xD46
@@ -117,6 +120,18 @@
 #define	CPU_PART_CORTEX_A715	0xD4D
 #define	CPU_PART_CORTEX_X3	0xD4E
 #define	CPU_PART_NEOVERSE_V2	0xD4F
+#define	CPU_PART_CORTEX_A520	0xD80
+#define	CPU_PART_CORTEX_A720	0xD81
+#define	CPU_PART_CORTEX_X4	0xD82
+#define	CPU_PART_NEOVERSE_V3AE	0xD83
+#define	CPU_PART_NEOVERSE_V3	0xD84
+#define	CPU_PART_CORTEX_X925	0xD85
+#define	CPU_PART_CORTEX_A725	0xD87
+#define	CPU_PART_C1_NANO	0xD8A
+#define	CPU_PART_C1_PRO		0xD8B
+#define	CPU_PART_C1_ULTRA	0xD8C
+#define	CPU_PART_NEOVERSE_N3	0xD8E
+#define	CPU_PART_C1_PREMIUM	0xD90
 
 /* Cavium Part numbers */
 #define	CPU_PART_THUNDERX	0x0A1
@@ -129,9 +144,16 @@
 
 #define	CPU_REV_THUNDERX2_0	0x00
 
-/* APM / Ampere Part Number */
+/* APM (now Ampere) Part number */
 #define CPU_PART_EMAG8180	0x000
 
+/* Ampere Part numbers */
+#define	CPU_PART_AMPERE1	0xAC3
+#define	CPU_PART_AMPERE1A	0xAC4
+
+/* Microsoft Part numbers */
+#define	CPU_PART_AZURE_COBALT_100	0xD49
+
 /* Qualcomm */
 #define	CPU_PART_KRYO400_GOLD	0x804
 #define	CPU_PART_KRYO400_SILVER	0x805