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