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);