Module Name: src Committed By: maxv Date: Thu Sep 28 17:48:20 UTC 2017
Modified Files: src/sys/arch/amd64/amd64: mptramp.S src/sys/arch/i386/i386: mptramp.S src/sys/arch/x86/x86: cpu.c Log Message: Pack the useful variables at the end of the trampoline page; eliminates a hard-coded dependency on KERNBASE. Note that I cannot test this change on i386 right now, but it seems fine enough. To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/arch/amd64/amd64/mptramp.S cvs rdiff -u -r1.31 -r1.32 src/sys/arch/i386/i386/mptramp.S cvs rdiff -u -r1.135 -r1.136 src/sys/arch/x86/x86/cpu.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/mptramp.S diff -u src/sys/arch/amd64/amd64/mptramp.S:1.24 src/sys/arch/amd64/amd64/mptramp.S:1.25 --- src/sys/arch/amd64/amd64/mptramp.S:1.24 Sat Jul 22 08:01:35 2017 +++ src/sys/arch/amd64/amd64/mptramp.S Thu Sep 28 17:48:20 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mptramp.S,v 1.24 2017/07/22 08:01:35 maxv Exp $ */ +/* $NetBSD: mptramp.S,v 1.25 2017/09/28 17:48:20 maxv Exp $ */ /* * Copyright (c) 2000, 2016 The NetBSD Foundation, Inc. @@ -82,15 +82,21 @@ #include <machine/i82489reg.h> #include <machine/gdt.h> -#define _RELOC(x) ((x) - KERNBASE) -#define RELOC(x) _RELOC(_C_LABEL(x)) - #define _TRMP_LABEL(a) a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE +/* + * A smp_data structure is packed at the end of the trampoline page. The stack + * is right below this structure. + */ +#define SMP_DATA (MP_TRAMPOLINE + PAGE_SIZE - 3 * 4) +#define SMP_DATA_STACK (SMP_DATA + 0 * 4) +#define SMP_DATA_LARGE (SMP_DATA + 0 * 4) +#define SMP_DATA_NOX (SMP_DATA + 1 * 4) +#define SMP_DATA_PDIR (SMP_DATA + 2 * 4) + .global _C_LABEL(cpu_spinup_trampoline) .global _C_LABEL(cpu_spinup_trampoline_end) .global _C_LABEL(cpu_hatch) - .global _C_LABEL(mp_pdirpa) .text .align 4,0x0 @@ -126,8 +132,8 @@ _TRMP_LABEL(mp_startup) movw %ax,%fs movw %ax,%gs - /* bootstrap stack end, with scratch space.. */ - movl $(MP_TRAMPOLINE+PAGE_SIZE-16),%esp + /* bootstrap stack end */ + movl $SMP_DATA_STACK,%esp /* First, reset the PSL. */ pushl $PSL_MBO @@ -136,7 +142,8 @@ _TRMP_LABEL(mp_startup) /* Enable PAE, SSE, and PSE if available */ movl %cr4,%eax orl $(CR4_PAE|CR4_OSFXSR|CR4_OSXMMEXCPT),%eax - movl RELOC(pmap_largepages),%ecx + movl $SMP_DATA_LARGE,%ecx + movl (%ecx),%ecx orl %ecx,%ecx jz no_PSE orl $CR4_PSE,%eax @@ -151,7 +158,8 @@ no_PSE: rdmsr xorl %eax,%eax orl $(EFER_LME|EFER_SCE),%eax - movl RELOC(nox_flag),%ebx + movl $SMP_DATA_NOX,%ebx + movl (%ebx),%ebx cmpl $0,%ebx je no_NOX orl $(EFER_NXE),%eax @@ -159,7 +167,8 @@ no_NOX: wrmsr /* Load %cr3. */ - movl RELOC(mp_pdirpa),%ecx /* guaranteed < 4G */ + movl $SMP_DATA_PDIR,%ecx + movl (%ecx),%ecx /* guaranteed < 4G */ movl %ecx,%cr3 /* load PTD addr into MMU */ /* Enable paging and the rest of it. */ @@ -238,8 +247,3 @@ _C_LABEL(cpu_spinup_trampoline_end): /* call _C_LABEL(cpu_hatch) END(cpu_spinup_trampoline) - .data -LABEL(mp_pdirpa) - .quad 0 -END(mp_pdirpa) - Index: src/sys/arch/i386/i386/mptramp.S diff -u src/sys/arch/i386/i386/mptramp.S:1.31 src/sys/arch/i386/i386/mptramp.S:1.32 --- src/sys/arch/i386/i386/mptramp.S:1.31 Sat Jul 22 08:01:35 2017 +++ src/sys/arch/i386/i386/mptramp.S Thu Sep 28 17:48:20 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mptramp.S,v 1.31 2017/07/22 08:01:35 maxv Exp $ */ +/* $NetBSD: mptramp.S,v 1.32 2017/09/28 17:48:20 maxv Exp $ */ /* * Copyright (c) 2000, 2016 The NetBSD Foundation, Inc. @@ -75,7 +75,7 @@ */ #include <machine/asm.h> -__KERNEL_RCSID(0, "$NetBSD: mptramp.S,v 1.31 2017/07/22 08:01:35 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mptramp.S,v 1.32 2017/09/28 17:48:20 maxv Exp $"); #include "assym.h" #include <machine/specialreg.h> @@ -85,14 +85,21 @@ __KERNEL_RCSID(0, "$NetBSD: mptramp.S,v #include <machine/gdt.h> #define GDTE(a,b) .byte 0xff,0xff,0x0,0x0,0x0,a,b,0x0 -#define _RELOC(x) ((x) - KERNBASE) -#define RELOC(x) _RELOC(_C_LABEL(x)) #define _TRMP_LABEL(a) a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE +/* + * A smp_data structure is packed at the end of the trampoline page. The stack + * is right below this structure. + */ +#define SMP_DATA (MP_TRAMPOLINE + PAGE_SIZE - 3 * 4) +#define SMP_DATA_STACK (SMP_DATA + 0 * 4) +#define SMP_DATA_LARGE (SMP_DATA + 0 * 4) +#define SMP_DATA_NOX (SMP_DATA + 1 * 4) +#define SMP_DATA_PDIR (SMP_DATA + 2 * 4) + .global _C_LABEL(cpu_spinup_trampoline) .global _C_LABEL(cpu_spinup_trampoline_end) - .global _C_LABEL(mp_pdirpa) .text .align 4,0x0 @@ -128,15 +135,16 @@ _TRMP_LABEL(mp_startup) movw %ax,%fs movw %ax,%gs - /* bootstrap stack end, with scratch space.. */ - movl $(MP_TRAMPOLINE+PAGE_SIZE-16),%esp + /* bootstrap stack end */ + movl $SMP_DATA_STACK,%esp /* First, reset the PSL. */ pushl $PSL_MBO popfl /* Enable PSE if available */ - movl RELOC(pmap_largepages),%eax + movl $SMP_DATA_LARGE,%eax + movl (%eax),%eax orl %eax,%eax jz no_PSE movl %cr4,%eax @@ -154,7 +162,8 @@ no_PSE: /* * Set NOX in EFER, if available. */ - movl RELOC(nox_flag),%ebx + movl $SMP_DATA_NOX,%ebx + movl (%ebx),%ebx cmpl $0,%ebx je no_NOX movl $MSR_EFER,%ecx @@ -165,7 +174,8 @@ no_PSE: no_NOX: /* Load %cr3. */ - movl RELOC(mp_pdirpa),%ecx + movl $SMP_DATA_PDIR,%ecx + movl (%ecx),%ecx movl %ecx,%cr3 /* load PTD addr into MMU */ /* Enable paging and the rest of it. */ @@ -230,8 +240,3 @@ mp_cont: call _C_LABEL(cpu_hatch) END(cpu_spinup_trampoline) - .data -LABEL(mp_pdirpa) - .long 0 -END(mp_pdirpa) - Index: src/sys/arch/x86/x86/cpu.c diff -u src/sys/arch/x86/x86/cpu.c:1.135 src/sys/arch/x86/x86/cpu.c:1.136 --- src/sys/arch/x86/x86/cpu.c:1.135 Sun Sep 17 09:04:51 2017 +++ src/sys/arch/x86/x86/cpu.c Thu Sep 28 17:48:20 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.135 2017/09/17 09:04:51 maxv Exp $ */ +/* $NetBSD: cpu.c,v 1.136 2017/09/28 17:48:20 maxv Exp $ */ /* * Copyright (c) 2000-2012 NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.135 2017/09/17 09:04:51 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.136 2017/09/28 17:48:20 maxv Exp $"); #include "opt_ddb.h" #include "opt_mpbios.h" /* for MPDEBUG */ @@ -190,7 +190,7 @@ static void cpu_boot_secondary(struc static void cpu_start_secondary(struct cpu_info *ci); #endif #if NLAPIC > 0 -static void cpu_copy_trampoline(void); +static void cpu_copy_trampoline(paddr_t); #endif /* @@ -205,7 +205,6 @@ cpu_init_first(void) { cpu_info_primary.ci_cpuid = lapic_cpu_number(); - cpu_copy_trampoline(); cmos_data_mapping = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY); if (cmos_data_mapping == 0) @@ -692,11 +691,13 @@ cpu_init_idle_lwps(void) void cpu_start_secondary(struct cpu_info *ci) { - extern paddr_t mp_pdirpa; + paddr_t mp_pdirpa; u_long psl; int i; mp_pdirpa = pmap_init_tmp_pgtbl(mp_trampoline_paddr); + cpu_copy_trampoline(mp_pdirpa); + atomic_or_32(&ci->ci_flags, CPUF_AP); ci->ci_curlwp = ci->ci_data.cpu_idlelwp; if (CPU_STARTUP(ci, mp_trampoline_paddr) != 0) { @@ -903,26 +904,39 @@ cpu_debug_dump(void) #if NLAPIC > 0 static void -cpu_copy_trampoline(void) +cpu_copy_trampoline(paddr_t pdir_pa) { - /* - * Copy boot code. - */ + extern uint32_t nox_flag; extern u_char cpu_spinup_trampoline[]; extern u_char cpu_spinup_trampoline_end[]; - vaddr_t mp_trampoline_vaddr; + struct { + uint32_t large; + uint32_t nox; + uint32_t pdir; + } smp_data; + CTASSERT(sizeof(smp_data) == 3 * 4); + + smp_data.large = (pmap_largepages != 0); + smp_data.nox = nox_flag; + smp_data.pdir = (uint32_t)(pdir_pa & 0xFFFFFFFF); + /* Enter the physical address */ mp_trampoline_vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY); - pmap_kenter_pa(mp_trampoline_vaddr, mp_trampoline_paddr, VM_PROT_READ | VM_PROT_WRITE, 0); pmap_update(pmap_kernel()); + + /* Copy boot code */ memcpy((void *)mp_trampoline_vaddr, cpu_spinup_trampoline, cpu_spinup_trampoline_end - cpu_spinup_trampoline); + /* Copy smp_data at the end */ + memcpy((void *)(mp_trampoline_vaddr + PAGE_SIZE - sizeof(smp_data)), + &smp_data, sizeof(smp_data)); + pmap_kremove(mp_trampoline_vaddr, PAGE_SIZE); pmap_update(pmap_kernel()); uvm_km_free(kernel_map, mp_trampoline_vaddr, PAGE_SIZE, UVM_KMF_VAONLY);