The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=31afa16f92df9ed2cee96b8ee56449ea60a9ccf1
commit 31afa16f92df9ed2cee96b8ee56449ea60a9ccf1 Author: Konstantin Belousov <k...@freebsd.org> AuthorDate: 2025-07-16 23:55:49 +0000 Commit: Konstantin Belousov <k...@freebsd.org> CommitDate: 2025-07-20 00:25:45 +0000 amd64 pmap: for LA57 move large map out of kernel pml4 slot and allow it to consume up to 32 pml5 slots (32 x 2048 TB), same as DMAP. Reviewed by: alc, markj Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D51364 --- sys/amd64/amd64/pmap.c | 42 ++++++++++++++++++++++++++++++------------ sys/amd64/include/pmap.h | 7 ++++++- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index a7d17db19a3e..0850b326bc3a 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -497,8 +497,8 @@ struct kva_layout_s kva_layout_la57 = { .kva_min = KV5ADDR(NPML5EPG / 2, 0, 0, 0, 0), /* == rec_pt */ .dmap_low = KV5ADDR(DMPML5I, 0, 0, 0, 0), .dmap_high = KV5ADDR(DMPML5I + NDMPML5E, 0, 0, 0, 0), - .lm_low = KV4ADDR(LMSPML4I, 0, 0, 0), - .lm_high = KV4ADDR(LMEPML4I + 1, 0, 0, 0), + .lm_low = KV5ADDR(LMSPML5I, 0, 0, 0, 0), + .lm_high = KV5ADDR(LMEPML5I + 1, 0, 0, 0, 0), .km_low = KV4ADDR(KPML4BASE, 0, 0, 0), .km_high = KV4ADDR(KPML4BASE + NKPML4E - 1, NPDPEPG - 1, NPDEPG - 1, NPTEPG - 1), @@ -2626,6 +2626,15 @@ pmap_init(void) printf("pmap: cannot create large map\n"); lm_ents = 0; } + if (la57) { + for (i = 0; i < howmany((vm_offset_t)NBPML4 * + lm_ents, NBPML5); i++) { + m = pmap_large_map_getptp_unlocked(); + kernel_pmap->pm_pmltop[LMSPML5I + i] = X86_PG_V | + X86_PG_RW | X86_PG_A | X86_PG_M | + pg_nx | VM_PAGE_TO_PHYS(m); + } + } for (i = 0; i < lm_ents; i++) { m = pmap_large_map_getptp_unlocked(); pml4e = pmap_pml4e(kernel_pmap, kva_layout.lm_low + @@ -10768,19 +10777,28 @@ pmap_large_map_getptp(void) static pdp_entry_t * pmap_large_map_pdpe(vm_offset_t va) { + pml4_entry_t *pm4; vm_pindex_t pml4_idx; vm_paddr_t mphys; - pml4_idx = pmap_pml4e_index(va); - KASSERT(LMSPML4I <= pml4_idx && pml4_idx < LMSPML4I + lm_ents, - ("pmap_large_map_pdpe: va %#jx out of range idx %#jx LMSPML4I " - "%#jx lm_ents %d", - (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); - KASSERT((kernel_pml4[pml4_idx] & X86_PG_V) != 0, - ("pmap_large_map_pdpe: invalid pml4 for va %#jx idx %#jx " - "LMSPML4I %#jx lm_ents %d", - (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); - mphys = kernel_pml4[pml4_idx] & PG_FRAME; + KASSERT(va >= kva_layout.lm_low && va < kva_layout.lm_low + + (vm_offset_t)NBPML4 * lm_ents, ("va %#lx not in large map", va)); + if (la57) { + pm4 = pmap_pml4e(kernel_pmap, va); + mphys = *pm4 & PG_FRAME; + } else { + pml4_idx = pmap_pml4e_index(va); + + KASSERT(LMSPML4I <= pml4_idx && pml4_idx < LMSPML4I + lm_ents, + ("pmap_large_map_pdpe: va %#jx out of range idx %#jx " + "LMSPML4I %#jx lm_ents %d", + (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); + KASSERT((kernel_pml4[pml4_idx] & X86_PG_V) != 0, + ("pmap_large_map_pdpe: invalid pml4 for va %#jx idx %#jx " + "LMSPML4I %#jx lm_ents %d", + (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); + mphys = kernel_pml4[pml4_idx] & PG_FRAME; + } return ((pdp_entry_t *)PHYS_TO_DMAP(mphys) + pmap_pdpe_index(va)); } diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index 08e96027a5ed..a0ca97f2d5a0 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -202,9 +202,14 @@ #define KMSANSHADPML4I (KPML4BASE - NKMSANSHADPML4E) #define KMSANORIGPML4I (DMPML4I - NKMSANORIGPML4E) -/* Large map: index of the first and max last pml4 entry */ +/* + * Large map: index of the first and max last pml4/la48 and pml5/la57 + * entry. + */ #define LMSPML4I (PML4PML4I + 1) #define LMEPML4I (KASANPML4I - 1) +#define LMSPML5I (DMPML5I + NDMPML5E) +#define LMEPML5I (LMSPML5I + 32 - 1) /* 32 slots for large map */ /* * XXX doesn't really belong here I guess...