diff options
-rw-r--r-- | sys/arch/amd64/amd64/autoconf.c | 5 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/locore0.S | 8 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 18 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/pmap.c | 39 | ||||
-rw-r--r-- | sys/arch/amd64/include/pmap.h | 4 |
5 files changed, 58 insertions, 16 deletions
diff --git a/sys/arch/amd64/amd64/autoconf.c b/sys/arch/amd64/amd64/autoconf.c index 90e8e423d32..6ae7b28f6d9 100644 --- a/sys/arch/amd64/amd64/autoconf.c +++ b/sys/arch/amd64/amd64/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.52 2018/05/26 18:02:01 guenther Exp $ */ +/* $OpenBSD: autoconf.c,v 1.53 2019/01/11 06:25:06 mlarkin Exp $ */ /* $NetBSD: autoconf.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -118,6 +118,9 @@ cpu_configure(void) { x86_64_proc0_tss_ldt_init(); + pmap_randomize(); + map_tramps(); + if (config_rootfound("mainbus", NULL) == NULL) panic("configure: mainbus not configured"); diff --git a/sys/arch/amd64/amd64/locore0.S b/sys/arch/amd64/amd64/locore0.S index 424488bdb33..f9d07b3c9a1 100644 --- a/sys/arch/amd64/amd64/locore0.S +++ b/sys/arch/amd64/amd64/locore0.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore0.S,v 1.10 2018/12/18 21:11:09 guenther Exp $ */ +/* $OpenBSD: locore0.S,v 1.11 2019/01/11 06:25:06 mlarkin Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -661,7 +661,13 @@ longmode_hi: addq %r8,%rax movq %rax,_C_LABEL(proc0paddr)(%rip) leaq (USPACE-FRAMESIZE)(%rax),%rsp + + /* + * Set proc0's %cr3 to bootstrap page tables. Will be overwritten when + * pmap_randomize is called later. + */ movq %rsi,PCB_CR3(%rax) # pcb->pcb_cr3 + xorq %rbp,%rbp # mark end of frames xorw %ax,%ax diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 4f43c21e256..a044fa50ed0 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.251 2018/11/05 15:13:56 kn Exp $ */ +/* $OpenBSD: machdep.c,v 1.252 2019/01/11 06:25:06 mlarkin Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -1284,11 +1284,11 @@ cpu_init_extents(void) already_done = 1; } -#if defined(MULTIPROCESSOR) || \ - (NACPI > 0 && !defined(SMALL_KERNEL)) void map_tramps(void) { +#if defined(MULTIPROCESSOR) || \ + (NACPI > 0 && !defined(SMALL_KERNEL)) struct pmap *kmp = pmap_kernel(); extern paddr_t tramp_pdirpa; #ifdef MULTIPROCESSOR @@ -1299,20 +1299,19 @@ map_tramps(void) extern u_int32_t mp_pdirpa; #endif - pmap_kenter_pa(lo32_vaddr, lo32_paddr, PROT_READ | PROT_WRITE); - /* * The initial PML4 pointer must be below 4G, so if the * current one isn't, use a "bounce buffer" and save it * for tramps to use. */ if (kmp->pm_pdirpa > 0xffffffff) { + pmap_kenter_pa(lo32_vaddr, lo32_paddr, PROT_READ | PROT_WRITE); memcpy((void *)lo32_vaddr, kmp->pm_pdir, PAGE_SIZE); tramp_pdirpa = lo32_paddr; + pmap_kremove(lo32_vaddr, PAGE_SIZE); } else tramp_pdirpa = kmp->pm_pdirpa; - pmap_kremove(lo32_vaddr, PAGE_SIZE); #ifdef MULTIPROCESSOR /* Map MP tramp code and data pages RW for copy */ @@ -1343,8 +1342,8 @@ map_tramps(void) pmap_kremove(MP_TRAMPOLINE, PAGE_SIZE); pmap_kremove(MP_TRAMP_DATA, PAGE_SIZE); #endif /* MULTIPROCESSOR */ -} #endif +} #define IDTVEC(name) __CONCAT(X, name) typedef void (vector)(void); @@ -1666,11 +1665,6 @@ init_x86_64(paddr_t first_avail) pmap_kenter_pa(idt_vaddr, idt_paddr, PROT_READ | PROT_WRITE); -#if defined(MULTIPROCESSOR) || \ - (NACPI > 0 && !defined(SMALL_KERNEL)) - map_tramps(); -#endif - idt = (struct gate_descriptor *)idt_vaddr; cpu_info_primary.ci_tss = &cpu_info_full_primary.cif_tss; cpu_info_primary.ci_gdt = &cpu_info_full_primary.cif_gdt; diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index efd4b30a761..a0ca0c115b1 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.122 2019/01/06 02:15:40 mlarkin Exp $ */ +/* $OpenBSD: pmap.c,v 1.123 2019/01/11 06:25:06 mlarkin Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -749,6 +749,43 @@ pmap_bootstrap(paddr_t first_avail, paddr_t max_pa) } /* + * pmap_randomize + * + * Randomizes the location of the kernel pmap + */ +void +pmap_randomize(void) +{ + pd_entry_t *pml4va, *oldpml4va; + paddr_t pml4pa; + + pml4va = km_alloc(PAGE_SIZE, &kv_page, &kp_zero, &kd_nowait); + if (pml4va == NULL) + panic("%s: km_alloc failed", __func__); + + /* Copy old PML4 page to new one */ + oldpml4va = pmap_kernel()->pm_pdir; + memcpy(pml4va, oldpml4va, PAGE_SIZE); + + /* Switch to new PML4 */ + pmap_extract(pmap_kernel(), (vaddr_t)pml4va, &pml4pa); + lcr3(pml4pa); + + /* Fixup pmap_kernel and proc0's %cr3 */ + pmap_kernel()->pm_pdirpa = pml4pa; + pmap_kernel()->pm_pdir = pml4va; + proc0.p_addr->u_pcb.pcb_cr3 = pml4pa; + + /* Fixup recursive PTE PML4E slot. We are only changing the PA */ + pml4va[PDIR_SLOT_PTE] = pml4pa | (pml4va[PDIR_SLOT_PTE] & ~PG_FRAME); + + /* Wipe out bootstrap PML4 */ + memset(oldpml4va, 0, PAGE_SIZE); + + tlbflush(); +} + +/* * Pre-allocate PTPs for low memory, so that 1:1 mappings for various * trampoline code can be entered. */ diff --git a/sys/arch/amd64/include/pmap.h b/sys/arch/amd64/include/pmap.h index 20b2d05275e..35584d0a365 100644 --- a/sys/arch/amd64/include/pmap.h +++ b/sys/arch/amd64/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.70 2019/01/06 21:43:19 mlarkin Exp $ */ +/* $OpenBSD: pmap.h,v 1.71 2019/01/11 06:25:06 mlarkin Exp $ */ /* $NetBSD: pmap.h,v 1.1 2003/04/26 18:39:46 fvdl Exp $ */ /* @@ -378,7 +378,9 @@ extern const long nbpd[], nkptpmax[]; * prototypes */ +void map_tramps(void); /* machdep.c */ paddr_t pmap_bootstrap(paddr_t, paddr_t); +void pmap_randomize(void); boolean_t pmap_clear_attrs(struct vm_page *, unsigned long); static void pmap_page_protect(struct vm_page *, vm_prot_t); void pmap_page_remove (struct vm_page *); |