The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=db2ba218d9fe6a541a4f537a641cce95f952fd98

commit db2ba218d9fe6a541a4f537a641cce95f952fd98
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-09-11 18:36:38 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-09-13 16:52:13 +0000

    amd64 acpi_wakeup: map 1:1 whole low 4G for the trampoline page table
    
    This is required since kernel text might be physically located
    anywhere below 4G.
    
    PR:     258432
    Reported by:    Taku YAMAMOTO <t...@tackymt.homeip.net>
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D31916
---
 sys/x86/acpica/acpi_wakeup.c | 77 +++++++++++++++++++++++++++-----------------
 1 file changed, 48 insertions(+), 29 deletions(-)

diff --git a/sys/x86/acpica/acpi_wakeup.c b/sys/x86/acpica/acpi_wakeup.c
index 17946ede45d0..68e0892a31e6 100644
--- a/sys/x86/acpica/acpi_wakeup.c
+++ b/sys/x86/acpica/acpi_wakeup.c
@@ -99,7 +99,7 @@ static void           acpi_wakeup_cpus(struct acpi_softc *);
 #endif
 
 #ifdef __amd64__
-#define        ACPI_WAKEPAGES  5
+#define        ACPI_WAKEPAGES  8
 #else
 #define        ACPI_WAKEPAGES  1
 #endif
@@ -426,8 +426,8 @@ acpi_install_wakeup_handler(struct acpi_softc *sc)
        static void *wakeaddr;
        void *wakepages[ACPI_WAKEPAGES];
 #ifdef __amd64__
-       uint64_t *pt5, *pt4, *pt3, *pt2;
-       vm_paddr_t pt5pa, pt4pa, pt3pa, pt2pa;
+       uint64_t *pt5, *pt4, *pt3, *pt2_0, *pt2_1, *pt2_2, *pt2_3;
+       vm_paddr_t pt5pa, pt4pa, pt3pa, pt2_0pa, pt2_1pa, pt2_2pa, pt2_3pa;
        int i;
 #endif
 
@@ -443,15 +443,21 @@ acpi_install_wakeup_handler(struct acpi_softc *sc)
 
 #ifdef __amd64__
        if (la57) {
-               pt5 = wakepages[4];
+               pt5 = wakepages[7];
                pt5pa = vtophys(pt5);
        }
        pt4 = wakepages[1];
        pt3 = wakepages[2];
-       pt2 = wakepages[3];
+       pt2_0 = wakepages[3];
+       pt2_1 = wakepages[4];
+       pt2_2 = wakepages[5];
+       pt2_3 = wakepages[6];
        pt4pa = vtophys(pt4);
        pt3pa = vtophys(pt3);
-       pt2pa = vtophys(pt2);
+       pt2_0pa = vtophys(pt2_0);
+       pt2_1pa = vtophys(pt2_1);
+       pt2_2pa = vtophys(pt2_2);
+       pt2_3pa = vtophys(pt2_3);
 #endif
 
        bcopy(wakecode, (void *)sc->acpi_wakeaddr, sizeof(wakecode));
@@ -473,31 +479,44 @@ acpi_install_wakeup_handler(struct acpi_softc *sc)
 #ifndef __amd64__
        WAKECODE_FIXUP(wakeup_cr3, register_t, pmap_get_kcr3());
 #else /* __amd64__ */
-       /* Create the initial 1GB replicated page tables */
-       for (i = 0; i < NPTEPG; i++) {
-               if (la57) {
-                       pt5[i] = (uint64_t)pt4pa;
-                       pt5[i] |= PG_V | PG_RW | PG_U;
-               }
-
-               /*
-                * Each slot of the level 4 pages points
-                * to the same level 3 page
-                */
-               pt4[i] = (uint64_t)pt3pa;
-               pt4[i] |= PG_V | PG_RW | PG_U;
-
-               /*
-                * Each slot of the level 3 pages points
-                * to the same level 2 page
-                */
-               pt3[i] = (uint64_t)pt2pa;
-               pt3[i] |= PG_V | PG_RW | PG_U;
+       /* Create 1:1 mapping for the low 4G */
+       if (la57) {
+               bcopy(kernel_pmap->pm_pmltop, pt5, PAGE_SIZE);
+               pt5[0] = (uint64_t)pt4pa;
+               pt5[0] |= PG_V | PG_RW | PG_U;
+       } else {
+               bcopy(kernel_pmap->pm_pmltop, pt4, PAGE_SIZE);
+       }
 
-               /* The level 2 page slots are mapped with 2MB pages for 1GB. */
-               pt2[i] = i * NBPDR;
-               pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+       pt4[0] = (uint64_t)pt3pa;
+       pt4[0] |= PG_V | PG_RW | PG_U;
+
+       pt3[0] = (uint64_t)pt2_0pa;
+       pt3[0] |= PG_V | PG_RW | PG_U;
+       pt3[1] = (uint64_t)pt2_1pa;
+       pt3[1] |= PG_V | PG_RW | PG_U;
+       pt3[2] = (uint64_t)pt2_2pa;
+       pt3[2] |= PG_V | PG_RW | PG_U;
+       pt3[3] = (uint64_t)pt2_3pa;
+       pt3[3] |= PG_V | PG_RW | PG_U;
+
+       for (i = 0; i < NPDEPG; i++) {
+               pt2_0[i] = (pd_entry_t)i * NBPDR;
+               pt2_0[i] |= PG_V | PG_RW | PG_PS | PG_U;
+       }
+       for (i = 0; i < NPDEPG; i++) {
+               pt2_1[i] = (pd_entry_t)NBPDP + i * NBPDR;
+               pt2_1[i] |= PG_V | PG_RW | PG_PS | PG_U;
        }
+       for (i = 0; i < NPDEPG; i++) {
+               pt2_2[i] = (pd_entry_t)2 * NBPDP + i * NBPDR;
+               pt2_2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+       }
+       for (i = 0; i < NPDEPG; i++) {
+               pt2_3[i] = (pd_entry_t)3 * NBPDP + i * NBPDR;
+               pt2_3[i] |= PG_V | PG_RW | PG_PS | PG_U;
+       }
+
 #endif /* !__amd64__ */
 
        if (bootverbose)
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to