The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=aa78ed9258395dac056de77023cc52ebbb9b153d
commit aa78ed9258395dac056de77023cc52ebbb9b153d Author: Konstantin Belousov <k...@freebsd.org> AuthorDate: 2025-07-20 00:57:51 +0000 Commit: Konstantin Belousov <k...@freebsd.org> CommitDate: 2025-07-22 13:59:17 +0000 amd64 sysctl vm.pmap.kernel_maps: rework Iterate over the KVA instead of the pml4 indexes. Otherwise, we would need to iterate of pml5 indexes for LA57 and then either use secondary loop for pml4 entries, or use flat indexes for pml4. It is simpler to have unified loop for both paging modes. Instead of checking pml4 indexes for start of interesting kernel maps, use kva_layout. Again, this makes the printing of heralds independent of the paging mode. Restart the loop iteration when changing address due to canonicalization. This is needed to not miss printing the map herald line. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D51453 --- sys/amd64/amd64/pmap.c | 66 +++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 6fac8318df05..d1d80afccdc7 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -11985,13 +11985,15 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS) { struct pmap_kernel_map_range range; struct sbuf sbuf, *sb; + pml5_entry_t pml5e; pml4_entry_t pml4e; pdp_entry_t *pdp, pdpe; pd_entry_t *pd, pde; pt_entry_t *pt, pte; vm_offset_t sva; vm_paddr_t pa; - int error, i, j, k, l; + int error, j, k, l; + bool first; error = sysctl_wire_old_buffer(req, 0); if (error != 0) @@ -12001,6 +12003,7 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS) /* Sentinel value. */ range.sva = kva_layout.kva_max; + pml5e = 0; /* no UB for la48 */ /* * Iterate over the kernel page tables without holding the kernel pmap @@ -12009,49 +12012,50 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS) * Within the large map, ensure that PDP and PD page addresses are * valid before descending. */ - for (sva = 0, i = pmap_pml4e_index(sva); i < NPML4EPG; i++) { - switch (i) { - case PML4PML4I: - if (!la57) - sbuf_printf(sb, "\nRecursive map:\n"); - break; - case DMPML4I: - if (!la57) - sbuf_printf(sb, "\nDirect map:\n"); - break; + for (first = true, sva = 0; sva != 0 || first; first = false) { + if (sva == kva_layout.rec_pt) + sbuf_printf(sb, "\nRecursive map:\n"); + else if (sva == kva_layout.dmap_low) + sbuf_printf(sb, "\nDirect map:\n"); #ifdef KASAN - case KASANPML4I: + else if (sva == kva_layout.kasan_shadow_low) sbuf_printf(sb, "\nKASAN shadow map:\n"); - break; #endif #ifdef KMSAN - case KMSANSHADPML4I: + else if (sva == kva_layout.kmsan_shadow_low) sbuf_printf(sb, "\nKMSAN shadow map:\n"); - break; - case KMSANORIGPML4I: + else if (sva == kva_layout.kmsan_origin_low) sbuf_printf(sb, "\nKMSAN origin map:\n"); - break; #endif - case KPML4BASE: + else if (sva == kva_layout.km_low) sbuf_printf(sb, "\nKernel map:\n"); - break; - case LMSPML4I: - if (!la57) - sbuf_printf(sb, "\nLarge map:\n"); - break; - } + else if (sva == kva_layout.lm_low) + sbuf_printf(sb, "\nLarge map:\n"); /* Convert to canonical form. */ if (la57) { - if (sva == 1ul << 56) + if (sva == 1ul << 56) { sva |= -1ul << 57; + continue; + } } else { - if (sva == 1ul << 47) + if (sva == 1ul << 47) { sva |= -1ul << 48; + continue; + } } restart: - pml4e = kernel_pml4[i]; + if (la57) { + pml5e = *pmap_pml5e(kernel_pmap, sva); + if ((pml5e & X86_PG_V) == 0) { + sva = rounddown2(sva, NBPML5); + sysctl_kmaps_dump(sb, &range, sva); + sva += NBPML5; + continue; + } + } + pml4e = *pmap_pml4e(kernel_pmap, sva); if ((pml4e & X86_PG_V) == 0) { sva = rounddown2(sva, NBPML4); sysctl_kmaps_dump(sb, &range, sva); @@ -12072,7 +12076,7 @@ restart: pa = pdpe & PG_FRAME; if ((pdpe & PG_PS) != 0) { sva = rounddown2(sva, NBPDP); - sysctl_kmaps_check(sb, &range, sva, 0, + sysctl_kmaps_check(sb, &range, sva, pml5e, pml4e, pdpe, 0, 0); range.pdpes++; sva += NBPDP; @@ -12085,6 +12089,7 @@ restart: * freed. Validate the next-level address * before descending. */ + sva += NBPDP; goto restart; } pd = (pd_entry_t *)PHYS_TO_DMAP(pa); @@ -12101,7 +12106,7 @@ restart: if ((pde & PG_PS) != 0) { sva = rounddown2(sva, NBPDR); sysctl_kmaps_check(sb, &range, sva, - 0, pml4e, pdpe, pde, 0); + pml5e, pml4e, pdpe, pde, 0); range.pdes++; sva += NBPDR; continue; @@ -12113,6 +12118,7 @@ restart: * may be freed. Validate the * next-level address before descending. */ + sva += NBPDR; goto restart; } pt = (pt_entry_t *)PHYS_TO_DMAP(pa); @@ -12126,7 +12132,7 @@ restart: continue; } sysctl_kmaps_check(sb, &range, sva, - 0, pml4e, pdpe, pde, pte); + pml5e, pml4e, pdpe, pde, pte); range.ptes++; } }