diff options
author | Mike Larkin <mlarkin@cvs.openbsd.org> | 2016-05-18 03:45:12 +0000 |
---|---|---|
committer | Mike Larkin <mlarkin@cvs.openbsd.org> | 2016-05-18 03:45:12 +0000 |
commit | 8a76118d0dc228d29251371c26cd0b91301ba059 (patch) | |
tree | a3f6132654fd6519e12c878b137a3a79fafbb721 /sys/arch | |
parent | 87da7172f8982193319bcc5ab7eab1d720a6fb01 (diff) |
Split i386 mp hatch trampoline into code and data pages, and protect each
with proper W^X policy. The same thing was done for amd64 late last year,
catching i386 up now. Diff has been in snaps for a few days with no
reported fallout.
ok deraadt@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/i386/autoconf.c | 5 | ||||
-rw-r--r-- | sys/arch/i386/i386/cpu.c | 14 | ||||
-rw-r--r-- | sys/arch/i386/i386/hibernate_machdep.c | 14 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 6 | ||||
-rw-r--r-- | sys/arch/i386/i386/mptramp.s | 37 | ||||
-rw-r--r-- | sys/arch/i386/include/mpbiosvar.h | 3 |
6 files changed, 55 insertions, 24 deletions
diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c index f638d22364d..2037862de79 100644 --- a/sys/arch/i386/i386/autoconf.c +++ b/sys/arch/i386/i386/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.98 2016/05/16 05:53:27 mlarkin Exp $ */ +/* $OpenBSD: autoconf.c,v 1.99 2016/05/18 03:45:11 mlarkin Exp $ */ /* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */ /*- @@ -140,6 +140,9 @@ cpu_configure(void) pmap_kenter_pa((vaddr_t)MP_TRAMPOLINE, /* virtual */ (paddr_t)MP_TRAMPOLINE, /* physical */ PROT_READ | PROT_WRITE | PROT_EXEC); /* protection */ + pmap_kenter_pa((vaddr_t)MP_TRAMP_DATA, /* virtual */ + (paddr_t)MP_TRAMP_DATA, /* physical */ + PROT_READ | PROT_WRITE); /* protection */ #endif #if NACPI > 0 && !defined(SMALL_KERNEL) diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c index 67a1667043c..1e9147c3900 100644 --- a/sys/arch/i386/i386/cpu.c +++ b/sys/arch/i386/i386/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.76 2016/05/03 08:30:15 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.77 2016/05/18 03:45:11 mlarkin Exp $ */ /* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */ /*- @@ -172,6 +172,8 @@ void replacesmap(void); extern int _stac; extern int _clac; +u_int32_t mp_pdirpa; + void replacesmap(void) { @@ -529,7 +531,6 @@ cpu_boot_secondary(struct cpu_info *ci) struct pcb *pcb; int i; struct pmap *kpm = pmap_kernel(); - extern u_int32_t mp_pdirpa; if (mp_verbose) printf("%s: starting", ci->ci_dev.dv_xname); @@ -608,9 +609,16 @@ cpu_copy_trampoline(void) */ extern u_char cpu_spinup_trampoline[]; extern u_char cpu_spinup_trampoline_end[]; + extern u_char mp_tramp_data_start[]; + extern u_char mp_tramp_data_end[]; - bcopy(cpu_spinup_trampoline, (caddr_t)MP_TRAMPOLINE, + memcpy((caddr_t)MP_TRAMPOLINE, cpu_spinup_trampoline, cpu_spinup_trampoline_end - cpu_spinup_trampoline); + memcpy((caddr_t)MP_TRAMP_DATA, mp_tramp_data_start, + mp_tramp_data_end - mp_tramp_data_start); + + pmap_write_protect(pmap_kernel(), (vaddr_t)MP_TRAMPOLINE, + (vaddr_t)(MP_TRAMPOLINE + NBPG), PROT_READ | PROT_EXEC); } #endif diff --git a/sys/arch/i386/i386/hibernate_machdep.c b/sys/arch/i386/i386/hibernate_machdep.c index 13cc3ffa679..fbb6f05492d 100644 --- a/sys/arch/i386/i386/hibernate_machdep.c +++ b/sys/arch/i386/i386/hibernate_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hibernate_machdep.c,v 1.47 2015/08/21 07:01:38 mlarkin Exp $ */ +/* $OpenBSD: hibernate_machdep.c,v 1.48 2016/05/18 03:45:11 mlarkin Exp $ */ /* * Copyright (c) 2011 Mike Larkin <mlarkin@openbsd.org> @@ -146,6 +146,7 @@ get_hibernate_info_md(union hibernate_info *hiber_info) hiber_info->nranges++; #endif #ifdef MULTIPROCESSOR + /* Record MP trampoline code page */ if (hiber_info->nranges >= VM_PHYSSEG_MAX) return (1); hiber_info->ranges[hiber_info->nranges].base = MP_TRAMPOLINE; @@ -153,7 +154,16 @@ get_hibernate_info_md(union hibernate_info *hiber_info) hiber_info->ranges[hiber_info->nranges].base + PAGE_SIZE; hiber_info->image_size += PAGE_SIZE; hiber_info->nranges++; -#endif + + /* Record MP trampoline data page */ + if (hiber_info->nranges >= VM_PHYSSEG_MAX) + return (1); + hiber_info->ranges[hiber_info->nranges].base = MP_TRAMP_DATA; + hiber_info->ranges[hiber_info->nranges].end = + hiber_info->ranges[hiber_info->nranges].base + PAGE_SIZE; + hiber_info->image_size += PAGE_SIZE; + hiber_info->nranges++; +#endif /* MULTIPROCESSOR */ for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) { /* Skip non-NVS ranges (already processed) */ diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 405af381a89..7c737ba5b5b 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.584 2016/05/10 18:39:45 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.585 2016/05/18 03:45:11 mlarkin Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -3228,6 +3228,10 @@ init386(paddr_t first_avail) /* skip MP trampoline code page */ if (a < MP_TRAMPOLINE + NBPG) a = MP_TRAMPOLINE + NBPG; + + /* skip MP trampoline data page */ + if (a < MP_TRAMP_DATA + NBPG) + a = MP_TRAMP_DATA + NBPG; #endif /* MULTIPROCESSOR */ #if NACPI > 0 && !defined(SMALL_KERNEL) diff --git a/sys/arch/i386/i386/mptramp.s b/sys/arch/i386/i386/mptramp.s index 3a5ca00a797..e63ce1dcdf8 100644 --- a/sys/arch/i386/i386/mptramp.s +++ b/sys/arch/i386/i386/mptramp.s @@ -1,4 +1,4 @@ -/* $OpenBSD: mptramp.s,v 1.17 2015/04/26 09:48:29 kettenis Exp $ */ +/* $OpenBSD: mptramp.s,v 1.18 2016/05/18 03:45:11 mlarkin Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -90,6 +90,9 @@ #define _TRMP_LABEL(a) a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE #define _TRMP_OFFSET(a) a = . - _C_LABEL(cpu_spinup_trampoline) +#define _TRMP_DATA_LABEL(a) a = . - _C_LABEL(mp_tramp_data_start) + \ + MP_TRAMP_DATA +#define _TRMP_DATA_OFFSET(a) a = . - _C_LABEL(mp_tramp_data_start) /* * Debug code to stop aux. processors in various stages based on the @@ -116,15 +119,18 @@ .global _C_LABEL(cpu_spinup_trampoline_end) .global _C_LABEL(cpu_hatch) .global _C_LABEL(mp_pdirpa) + .global _C_LABEL(mp_tramp_data_start) + .global _C_LABEL(mp_tramp_data_end) .global _C_LABEL(gdt), _C_LABEL(local_apic) .text - .align 4,0x0 + .align 4, 0xcc .code16 _C_LABEL(cpu_spinup_trampoline): cli - movw %cs, %ax + movw $(MP_TRAMP_DATA >> 4), %ax movw %ax, %ds + movw %cs, %ax movw %ax, %es movw %ax, %ss data32 addr32 lgdt (gdt_desc) # load flat descriptor table @@ -142,7 +148,7 @@ _TRMP_LABEL(mp_startup) movw %ax, %es movw %ax, %fs movw %ax, %gs - movl $(MP_TRAMPOLINE+NBPG-16),%esp # bootstrap stack end, + movl $(MP_TRAMP_DATA+NBPG-16),%esp # bootstrap stack end, # with scratch space.. #ifdef MPDEBUG @@ -225,14 +231,6 @@ nopae: pushl $mp_cont HALT(0x14) lret - .align 4,0x0 -_TRMP_LABEL(gdt_table) - .word 0x0,0x0,0x0,0x0 # null GDTE - GDTE(0x9f,0xcf) # Kernel text - GDTE(0x93,0xcf) # Kernel data -_TRMP_OFFSET(gdt_desc) - .word 0x17 # limit 3 entries - .long gdt_table # where is gdt _C_LABEL(cpu_spinup_trampoline_end): #end of code copied to MP_TRAMPOLINE mp_cont: @@ -267,13 +265,20 @@ mp_cont: call _C_LABEL(cpu_hatch) /* NOTREACHED */ - .data -_C_LABEL(mp_pdirpa): - .long 0 + .section .rodata +_C_LABEL(mp_tramp_data_start): +_TRMP_DATA_LABEL(gdt_table) + .word 0x0,0x0,0x0,0x0 # null GDTE + GDTE(0x9f,0xcf) # Kernel text + GDTE(0x93,0xcf) # Kernel data +_TRMP_DATA_OFFSET(gdt_desc) + .word 0x17 # limit 3 entries + .long gdt_table # where is gdt #ifdef MPDEBUG .global _C_LABEL(cpu_trace) -_C_LABEL(cpu_trace): +_TRMP_DATA_LABEL(cpu_trace) .long 0x40 .long 0xff .long 0xff #endif +_C_LABEL(mp_tramp_data_end): diff --git a/sys/arch/i386/include/mpbiosvar.h b/sys/arch/i386/include/mpbiosvar.h index d7dfb312d4b..b22fbd823f9 100644 --- a/sys/arch/i386/include/mpbiosvar.h +++ b/sys/arch/i386/include/mpbiosvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mpbiosvar.h,v 1.11 2014/01/05 20:23:57 mlarkin Exp $ */ +/* $OpenBSD: mpbiosvar.h,v 1.12 2016/05/18 03:45:11 mlarkin Exp $ */ /* $NetBSD: mpbiosvar.h,v 1.1.2.3 2000/02/29 13:17:20 sommerfeld Exp $ */ /*- @@ -37,6 +37,7 @@ #define _MACHINE_MPBIOSVAR_H_ #define MP_TRAMPOLINE (16 * PAGE_SIZE) +#define MP_TRAMP_DATA (17 * PAGE_SIZE) #if !defined(_LOCORE) |