From fc7256b7611d032567f636d9336283e85f22fd6f Mon Sep 17 00:00:00 2001 From: mlarkin Date: Thu, 18 Dec 2014 05:33:48 +0000 Subject: [PATCH] Unmap the MP hatch and ACPI resume trampolines when not in active use. ok deraadt@ --- sys/arch/amd64/amd64/acpi_machdep.c | 27 ++++++++++----- sys/arch/amd64/amd64/cpu.c | 26 ++++++-------- sys/arch/amd64/amd64/hibernate_machdep.c | 9 ++++- sys/arch/amd64/amd64/lapic.c | 6 +--- sys/arch/amd64/amd64/machdep.c | 43 ++++++++++++++++++------ 5 files changed, 71 insertions(+), 40 deletions(-) diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c index 5b3a77c24bd..25b3fbb2b73 100644 --- a/sys/arch/amd64/amd64/acpi_machdep.c +++ b/sys/arch/amd64/amd64/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.66 2014/12/08 07:12:37 mlarkin Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.67 2014/12/18 05:33:48 mlarkin Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * @@ -225,19 +225,22 @@ acpi_attach_machdep(struct acpi_softc *sc) */ KASSERT(acpi_resume_end - acpi_real_mode_resume < PAGE_SIZE); - memcpy((caddr_t)ACPI_TRAMPOLINE, acpi_real_mode_resume, - acpi_resume_end - acpi_real_mode_resume); - + /* Map ACPI tramp code and data pages RW for copy */ + pmap_kenter_pa(ACPI_TRAMPOLINE, ACPI_TRAMPOLINE, + PROT_READ | PROT_WRITE); pmap_kenter_pa(ACPI_TRAMP_DATA, ACPI_TRAMP_DATA, PROT_READ | PROT_WRITE); + + memcpy((caddr_t)ACPI_TRAMPOLINE, acpi_real_mode_resume, + acpi_resume_end - acpi_real_mode_resume); memcpy((caddr_t)ACPI_TRAMP_DATA, acpi_tramp_data_start, acpi_tramp_data_end - acpi_tramp_data_start); - /* Remap trampoline code page RX */ - pmap_kenter_pa(ACPI_TRAMPOLINE, ACPI_TRAMPOLINE, - PROT_READ | PROT_EXEC); - acpi_pdirpa = tramp_pdirpa; + + /* Unmap, will be remapped in acpi_sleep_cpu */ + pmap_kremove(ACPI_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(ACPI_TRAMP_DATA, PAGE_SIZE); } void @@ -300,6 +303,11 @@ acpi_sleep_cpu(struct acpi_softc *sc, int state) if (sc->sc_facs->length > 32 && sc->sc_facs->version >= 1) sc->sc_facs->x_wakeup_vector = 0; + /* Map trampoline and data page */ + pmap_kenter_pa(ACPI_TRAMPOLINE, ACPI_TRAMPOLINE, PROT_READ | PROT_EXEC); + pmap_kenter_pa(ACPI_TRAMP_DATA, ACPI_TRAMP_DATA, + PROT_READ | PROT_WRITE); + /* * Copy the current cpu registers into a safe place for resume. * acpi_savecpu actually returns twice - once in the suspend @@ -341,6 +349,9 @@ acpi_sleep_cpu(struct acpi_softc *sc, int state) if (sc->sc_facs->length > 32 && sc->sc_facs->version >= 1) sc->sc_facs->x_wakeup_vector = 0; + pmap_kremove(ACPI_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(ACPI_TRAMP_DATA, PAGE_SIZE); + return (0); } diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index 48e97982fb8..338b91a45aa 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.74 2014/12/15 01:53:45 tedu Exp $ */ +/* $OpenBSD: cpu.c,v 1.75 2014/12/18 05:33:48 mlarkin Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -219,18 +219,6 @@ void cpu_hatch(void *); void cpu_boot_secondary(struct cpu_info *ci); void cpu_start_secondary(struct cpu_info *ci); void cpu_copy_trampoline(void); - -/* - * Runs once per boot once multiprocessor goo has been detected and - * the local APIC on the boot processor has been mapped. - * - * Called from lapic_boot_init() (from mpbios_scan()). - */ -void -cpu_init_first(void) -{ - cpu_copy_trampoline(); -} #endif int @@ -625,6 +613,9 @@ cpu_start_secondary(struct cpu_info *ci) ci->ci_flags |= CPUF_AP; + pmap_kenter_pa(MP_TRAMPOLINE, MP_TRAMPOLINE, PROT_READ | PROT_EXEC); + pmap_kenter_pa(MP_TRAMP_DATA, MP_TRAMP_DATA, PROT_READ | PROT_WRITE); + CPU_STARTUP(ci); /* @@ -654,6 +645,9 @@ cpu_start_secondary(struct cpu_info *ci) } CPU_START_CLEANUP(ci); + + pmap_kremove(MP_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(MP_TRAMP_DATA, PAGE_SIZE); } void @@ -813,9 +807,9 @@ cpu_copy_trampoline(void) */ mp_pdirpa = tramp_pdirpa; - /* Remap the trampoline RX */ - pmap_kenter_pa(MP_TRAMPOLINE, MP_TRAMPOLINE, - PROT_READ | PROT_EXEC); + /* Unmap, will be remapped in cpu_start_secondary */ + pmap_kremove(MP_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(MP_TRAMP_DATA, PAGE_SIZE); } diff --git a/sys/arch/amd64/amd64/hibernate_machdep.c b/sys/arch/amd64/amd64/hibernate_machdep.c index d65bba37e68..eabc5eb44c1 100644 --- a/sys/arch/amd64/amd64/hibernate_machdep.c +++ b/sys/arch/amd64/amd64/hibernate_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hibernate_machdep.c,v 1.33 2014/12/08 07:12:37 mlarkin Exp $ */ +/* $OpenBSD: hibernate_machdep.c,v 1.34 2014/12/18 05:33:48 mlarkin Exp $ */ /* * Copyright (c) 2012 Mike Larkin @@ -435,6 +435,10 @@ hibernate_quiesce_cpus(void) KASSERT(CPU_IS_PRIMARY(curcpu())); + pmap_kenter_pa(ACPI_TRAMPOLINE, ACPI_TRAMPOLINE, PROT_READ | PROT_EXEC); + pmap_kenter_pa(ACPI_TRAMP_DATA, ACPI_TRAMP_DATA, + PROT_READ | PROT_WRITE); + for (i = 0; i < MAXCPUS; i++) { ci = cpu_info[i]; if (ci == NULL) @@ -450,5 +454,8 @@ hibernate_quiesce_cpus(void) /* Wait a bit for the APs to park themselves */ delay(500000); + + pmap_kremove(ACPI_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(ACPI_TRAMP_DATA, PAGE_SIZE); } #endif /* MULTIPROCESSOR */ diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c index 0488c1f7490..41cf4bf4fc0 100644 --- a/sys/arch/amd64/amd64/lapic.c +++ b/sys/arch/amd64/amd64/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.35 2014/11/20 06:51:41 mlarkin Exp $ */ +/* $OpenBSD: lapic.c,v 1.36 2014/12/18 05:33:48 mlarkin Exp $ */ /* $NetBSD: lapic.c,v 1.2 2003/05/08 01:04:35 fvdl Exp $ */ /*- @@ -112,10 +112,6 @@ lapic_map(paddr_t lapic_base) *pte = lapic_base | PG_RW | PG_V | PG_N | PG_G | pg_nx; invlpg(va); -#ifdef MULTIPROCESSOR - cpu_init_first(); -#endif - lapic_tpr = s; enable_intr(); } diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index dd883326f93..d1a6fdd4276 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.202 2014/12/15 01:53:45 tedu Exp $ */ +/* $OpenBSD: machdep.c,v 1.203 2014/12/18 05:33:48 mlarkin Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -1176,6 +1176,14 @@ void map_tramps(void) { struct pmap *kmp = pmap_kernel(); + extern paddr_t tramp_pdirpa; +#ifdef MULTIPROCESSOR + 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[]; + extern u_int32_t mp_pdirpa; +#endif pmap_kenter_pa(lo32_vaddr, lo32_paddr, PROT_READ | PROT_WRITE); @@ -1193,16 +1201,31 @@ map_tramps(void) pmap_kremove(lo32_vaddr, PAGE_SIZE); #ifdef MULTIPROCESSOR - /* Map trampoline code page RW (to copy code) */ - pmap_kenter_pa((vaddr_t)MP_TRAMPOLINE, /* virtual */ - (paddr_t)MP_TRAMPOLINE, /* physical */ - PROT_READ | PROT_WRITE); /* protection */ -#endif /* MULTIPROCESSOR */ + /* Map MP tramp code and data pages RW for copy */ + pmap_kenter_pa(MP_TRAMPOLINE, MP_TRAMPOLINE, + PROT_READ | PROT_WRITE); + + pmap_kenter_pa(MP_TRAMP_DATA, MP_TRAMP_DATA, + PROT_READ | PROT_WRITE); - /* Map trampoline code page RW (to copy code) */ - pmap_kenter_pa((vaddr_t)ACPI_TRAMPOLINE, /* virtual */ - (paddr_t)ACPI_TRAMPOLINE, /* physical */ - PROT_READ | PROT_WRITE); /* protection */ + 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); + + /* + * We need to patch this after we copy the tramp data, + * the symbol points into the copied tramp data page. + */ + mp_pdirpa = tramp_pdirpa; + + /* Unmap, will be remapped in cpu_start_secondary */ + pmap_kremove(MP_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(MP_TRAMP_DATA, PAGE_SIZE); +#endif /* MULTIPROCESSOR */ } #endif -- 2.20.1