DF-2675 / pml4dump.c
/* DF-2675: dump present PML4 entries (phys + PT count) of the running kernel */ #include <sys/types.h> #include <err.h> #include <fcntl.h> #include <kvm.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define PMASK 0x000FFFFFFFFFF000ULL int main(void) { kvm_t *kd; struct nlist nl[] = { { "_KPML4phys" }, { NULL } }; uint64_t KPML4, pml4[512], pud[512], pd[512]; int memfd, p4, p3, p2, ptes; kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "pml4dump"); if (!kd) return 1; if (kvm_nlist(kd, nl) != 0 || nl[0].n_value == 0) errx(1, "nlist"); if (kvm_read(kd, nl[0].n_value, &KPML4, 8) != 8) errx(1, "read"); kvm_close(kd); memfd = open("/dev/mem", O_RDONLY); if (memfd < 0) err(1, "/dev/mem"); if (pread(memfd, pml4, 4096, (off_t)KPML4) != 4096) errx(1, "pml4 read"); printf("KPML4phys = %jx\n", (uintmax_t)KPML4); for (p4 = 0; p4 < 512; ++p4) { if (!(pml4[p4] & 1)) continue; ptes = 0; if (pread(memfd, pud, 4096, (off_t)(pml4[p4] & PMASK)) != 4096) continue; for (p3 = 0; p3 < 512; ++p3) { if (!(pud[p3] & 1)) continue; if (pud[p3] & 0x80) { ptes += 262144; continue; } if (pread(memfd, pd, 4096, (off_t)(pud[p3] & PMASK)) != 4096) continue; for (p2 = 0; p2 < 512; ++p2) { if (!(pd[p2] & 1)) continue; if (pd[p2] & 0x80) { ptes += 512; continue; } ptes += 1; } } printf("PML4[%3d] phys=%012jx PTs(+large)=%d KVA=%016llx..%016llx\n", p4, (uintmax_t)(pml4[p4] & PMASK), ptes, (unsigned long long)((uint64_t)p4 << 39), (unsigned long long)(((uint64_t)p4 + 1) << 39) - 1); } return 0; } |