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...

Reply via email to