git: b9c0003f0fa3 - main - arm64: Initialize x18 for APs earlier during boot
Date: Mon, 13 Nov 2023 15:51:17 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=b9c0003f0fa39ead4bb3953b9118ae6f08e560f8
commit b9c0003f0fa39ead4bb3953b9118ae6f08e560f8
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2023-11-13 15:44:45 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-11-13 15:44:45 +0000
arm64: Initialize x18 for APs earlier during boot
When KMSAN is configured, the instrumentation inserts calls to
__msan_get_context_state() into all function prologues. The
implementation dereferences curthread and thus assumes that x18 points
to the PCPU area. This applies in particular to init_secondary(), which
currently is responsible for initializing x18 for APs.
Move initialization into locore to avoid this problem. No functional
change intended.
Reviewed by: kib, andrew
MFC after: 2 weeks
Sponsored by: Juniper Networks, Inc.
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D42533
---
sys/arm64/arm64/locore.S | 8 ++++++++
sys/arm64/arm64/mp_machdep.c | 14 +++++---------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S
index d55a21e9c55e..d77963d42461 100644
--- a/sys/arm64/arm64/locore.S
+++ b/sys/arm64/arm64/locore.S
@@ -247,6 +247,14 @@ mp_virtdone:
dsb sy
isb
+ /*
+ * Initialize the per-CPU pointer before calling into C code, for the
+ * benefit of kernel sanitizers.
+ */
+ adrp x18, bootpcpu
+ ldr x18, [x18, :lo12:bootpcpu]
+ msr tpidr_el1, x18
+
b init_secondary
END(mpentry)
#endif
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
index 1c9bea2349de..5d598b4189a9 100644
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -134,6 +134,9 @@ void init_secondary(uint64_t);
/* Synchronize AP startup. */
static struct mtx ap_boot_mtx;
+/* Used to initialize the PCPU ahead of calling init_secondary(). */
+void *bootpcpu;
+
/* Stacks for AP initialization, discarded once idle threads are started. */
void *bootstack;
static void *bootstacks[MAXCPU];
@@ -225,15 +228,6 @@ init_secondary(uint64_t cpu)
panic("MPIDR for this CPU is not in pcpu table");
}
- pcpup = cpuid_to_pcpu[cpu];
- /*
- * Set the pcpu pointer with a backup in tpidr_el1 to be
- * loaded when entering the kernel from userland.
- */
- __asm __volatile(
- "mov x18, %0 \n"
- "msr tpidr_el1, %0" :: "r"(pcpup));
-
/*
* Identify current CPU. This is necessary to setup
* affinity registers and to provide support for
@@ -242,6 +236,7 @@ init_secondary(uint64_t cpu)
* We need this before signalling the CPU is ready to
* let the boot CPU use the results.
*/
+ pcpup = cpuid_to_pcpu[cpu];
pcpup->pc_midr = get_midr();
identify_cpu(cpu);
@@ -555,6 +550,7 @@ start_cpu(u_int cpuid, uint64_t target_cpu, int domain, vm_paddr_t release_addr)
pmap_disable_promotion((vm_offset_t)pcpup, size);
pcpu_init(pcpup, cpuid, sizeof(struct pcpu));
pcpup->pc_mpidr = target_cpu & CPU_AFF_MASK;
+ bootpcpu = pcpup;
dpcpu[cpuid - 1] = (void *)(pcpup + 1);
dpcpu_init(dpcpu[cpuid - 1], cpuid);