Unmap the MP hatch and ACPI resume trampolines when not in active use.
authormlarkin <mlarkin@openbsd.org>
Thu, 18 Dec 2014 05:33:48 +0000 (05:33 +0000)
committermlarkin <mlarkin@openbsd.org>
Thu, 18 Dec 2014 05:33:48 +0000 (05:33 +0000)
ok deraadt@

sys/arch/amd64/amd64/acpi_machdep.c
sys/arch/amd64/amd64/cpu.c
sys/arch/amd64/amd64/hibernate_machdep.c
sys/arch/amd64/amd64/lapic.c
sys/arch/amd64/amd64/machdep.c

index 5b3a77c..25b3fbb 100644 (file)
@@ -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 <tholo@sigmasoft.com>
  *
@@ -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);
 }
 
index 48e9798..338b91a 100644 (file)
@@ -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);
 }
 
 
index d65bba3..eabc5eb 100644 (file)
@@ -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 <mlarkin@openbsd.org>
@@ -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 */
index 0488c1f..41cf4bf 100644 (file)
@@ -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();
 }
index dd88332..d1a6fdd 100644 (file)
@@ -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