Index: sys/amd64/amd64/mp_machdep.c =================================================================== --- sys/amd64/amd64/mp_machdep.c +++ sys/amd64/amd64/mp_machdep.c @@ -197,10 +197,8 @@ /* Update microcode before doing anything else. */ ucode_load_ap(cpu); - /* Get per-cpu data and save */ - pc = &__pcpu[cpu]; - - /* prime data page for it to use */ + /* Initialize the PCPU area. */ + pc = bootpcpu; pcpu_init(pc, cpu, sizeof(struct pcpu)); dpcpu_init(dpcpu, cpu); pc->pc_apic_id = cpu_apic_ids[cpu]; @@ -262,8 +260,8 @@ lgdt(&ap_gdt); /* does magic intra-segment return */ wrmsr(MSR_FSBASE, 0); /* User value */ - wrmsr(MSR_GSBASE, (u_int64_t)pc); - wrmsr(MSR_KGSBASE, (u_int64_t)pc); /* XXX User value while we're in the kernel */ + wrmsr(MSR_GSBASE, (uint64_t)pc); + wrmsr(MSR_KGSBASE, 0); /* User value */ fix_cpuid(); lidt(&r_idt); @@ -431,6 +429,7 @@ dpcpu = (void *)kmem_malloc_domainset(DOMAINSET_PREF(domain), DPCPU_SIZE, M_WAITOK | M_ZERO); + bootpcpu = &__pcpu[cpu]; bootSTK = (char *)bootstacks[cpu] + kstack_pages * PAGE_SIZE - 8; bootAP = cpu; Index: sys/amd64/amd64/mpboot.S =================================================================== --- sys/amd64/amd64/mpboot.S +++ sys/amd64/amd64/mpboot.S @@ -260,4 +260,19 @@ .p2align 4,0 entry_64: movq bootSTK, %rsp + +#ifdef KMSAN + /* + * Initialize the segment register used for the PCPU area. The PCPU + * area will be initialized by init_secondary(), but it should be + * accessible before that to support sanitizer instrumentation which + * accesses per-CPU variables. + */ + movl $MSR_GSBASE, %ecx + movq bootpcpu, %rax + movq %rax, %rdx + shrq $32, %rdx + wrmsr +#endif + jmp init_secondary Index: sys/x86/include/x86_smp.h =================================================================== --- sys/x86/include/x86_smp.h +++ sys/x86/include/x86_smp.h @@ -28,9 +28,10 @@ extern int boot_cpu_id; extern struct pcb stoppcbs[]; extern int cpu_apic_ids[]; -extern int bootAP; extern void *dpcpu; +extern int bootAP; extern char *bootSTK; +extern void *bootpcpu; extern void *bootstacks[]; extern unsigned int boot_address; extern unsigned int bootMP_size; Index: sys/x86/x86/mp_x86.c =================================================================== --- sys/x86/x86/mp_x86.c +++ sys/x86/x86/mp_x86.c @@ -92,6 +92,7 @@ int boot_cpu_id = -1; /* designated BSP */ /* AP uses this during bootstrap. Do not staticize. */ +void *bootpcpu; char *bootSTK; int bootAP;