Date: Sun, 23 Aug 2020 20:43:23 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r364534 - in head/sys: amd64/acpica amd64/amd64 x86/acpica Message-ID: <202008232043.07NKhN2N034718@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sun Aug 23 20:43:23 2020 New Revision: 364534 URL: https://svnweb.freebsd.org/changeset/base/364534 Log: amd64: Handle 5-level paging on wakeup. We can switch into long mode directly with LA57 enabled. Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D25273 Modified: head/sys/amd64/acpica/acpi_wakecode.S head/sys/amd64/amd64/cpu_switch.S head/sys/x86/acpica/acpi_wakeup.c Modified: head/sys/amd64/acpica/acpi_wakecode.S ============================================================================== --- head/sys/amd64/acpica/acpi_wakecode.S Sun Aug 23 20:40:35 2020 (r364533) +++ head/sys/amd64/acpica/acpi_wakecode.S Sun Aug 23 20:43:23 2020 (r364534) @@ -148,10 +148,18 @@ wakeup_32: mov $bootdata32 - bootgdt, %eax mov %ax, %ds - /* Turn on the PAE bit for when paging is enabled */ + /* + * Turn on the PAE bit and optionally the LA57 bit for when paging + * is later enabled. + */ mov %cr4, %eax orl $CR4_PAE, %eax - mov %eax, %cr4 + leal wakeup_pagetables - wakeup_start(%ebx), %ecx + movl (%ecx), %ecx + testl $0x1, %ecx + je 1f + orl $CR4_LA57, %eax +1: mov %eax, %cr4 /* * Enable EFER.LME so that we get long mode when all the prereqs are @@ -174,6 +182,7 @@ wakeup_32: */ leal wakeup_pagetables - wakeup_start(%ebx), %eax movl (%eax), %eax + andl $~0x1, %eax mov %eax, %cr3 /* Modified: head/sys/amd64/amd64/cpu_switch.S ============================================================================== --- head/sys/amd64/amd64/cpu_switch.S Sun Aug 23 20:40:35 2020 (r364533) +++ head/sys/amd64/amd64/cpu_switch.S Sun Aug 23 20:43:23 2020 (r364534) @@ -382,8 +382,11 @@ END(savectx) * Resuming processor state from pcb. */ ENTRY(resumectx) - /* Switch to KPML4phys. */ + /* Switch to KPML5/4phys. */ movq KPML4phys,%rax + movq KPML5phys,%rcx + cmpl $0, la57 + cmovne %rcx, %rax movq %rax,%cr3 /* Force kernel segment registers. */ Modified: head/sys/x86/acpica/acpi_wakeup.c ============================================================================== --- head/sys/x86/acpica/acpi_wakeup.c Sun Aug 23 20:40:35 2020 (r364533) +++ head/sys/x86/acpica/acpi_wakeup.c Sun Aug 23 20:43:23 2020 (r364534) @@ -99,7 +99,7 @@ static void acpi_wakeup_cpus(struct acpi_softc *); #endif #ifdef __amd64__ -#define ACPI_WAKEPAGES 4 +#define ACPI_WAKEPAGES 5 #else #define ACPI_WAKEPAGES 1 #endif @@ -414,8 +414,8 @@ acpi_install_wakeup_handler(struct acpi_softc *sc) static void *wakeaddr; void *wakepages[ACPI_WAKEPAGES]; #ifdef __amd64__ - uint64_t *pt4, *pt3, *pt2; - vm_paddr_t pt4pa, pt3pa, pt2pa; + uint64_t *pt5, *pt4, *pt3, *pt2; + vm_paddr_t pt5pa, pt4pa, pt3pa, pt2pa; int i; #endif @@ -430,6 +430,10 @@ acpi_install_wakeup_handler(struct acpi_softc *sc) sc->acpi_wakephys = vtophys(wakeaddr); #ifdef __amd64__ + if (la57) { + pt5 = wakepages[4]; + pt5pa = vtophys(pt5); + } pt4 = wakepages[1]; pt3 = wakepages[2]; pt2 = wakepages[3]; @@ -448,7 +452,8 @@ acpi_install_wakeup_handler(struct acpi_softc *sc) #ifdef __amd64__ WAKECODE_FIXUP((wakeup_sw64 + 1), uint32_t, sc->acpi_wakephys + wakeup_64); - WAKECODE_FIXUP(wakeup_pagetables, uint32_t, pt4pa); + WAKECODE_FIXUP(wakeup_pagetables, uint32_t, la57 ? (pt5pa | 0x1) : + pt4pa); #endif /* Save pointers to some global data. */ @@ -457,7 +462,12 @@ acpi_install_wakeup_handler(struct acpi_softc *sc) WAKECODE_FIXUP(wakeup_cr3, register_t, pmap_get_kcr3()); #else /* __amd64__ */ /* Create the initial 1GB replicated page tables */ - for (i = 0; i < 512; i++) { + 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 @@ -473,7 +483,7 @@ acpi_install_wakeup_handler(struct acpi_softc *sc) pt3[i] |= PG_V | PG_RW | PG_U; /* The level 2 page slots are mapped with 2MB pages for 1GB. */ - pt2[i] = i * (2 * 1024 * 1024); + pt2[i] = i * NBPDR; pt2[i] |= PG_V | PG_RW | PG_PS | PG_U; } #endif /* !__amd64__ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202008232043.07NKhN2N034718>