diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -247,6 +247,14 @@ 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 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -134,6 +134,9 @@ /* 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 @@ 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 @@ * 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 @@ 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);