From 2a4134c73e58da04b1e95ef1e885ec453f90c3c3 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 6 Jan 2020 15:33:27 -0800 Subject: [PATCH] libkvm - Fix minidump page table processing * libkvm was not properly handling 1GB and 2MB page table entries. These entries need to be masked against PG_PS_FRAME, not PG_FRAME. * Fixes vmstat -m -N kernel -M vmcore output, and probably other output too. --- lib/libkvm/kvm_minidump_x86_64.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/libkvm/kvm_minidump_x86_64.c b/lib/libkvm/kvm_minidump_x86_64.c index 1d8e959579..b69cb6965e 100644 --- a/lib/libkvm/kvm_minidump_x86_64.c +++ b/lib/libkvm/kvm_minidump_x86_64.c @@ -297,6 +297,7 @@ _kvm_minidump_vatop(kvm_t *kd, u_long va, off_t *pa) vm = kd->vmst; offset = va & (PAGE_SIZE - 1); + va -= offset; /* put va on page boundary */ if (va >= vm->kernbase) { switch (vm->pgtable) { @@ -333,9 +334,11 @@ _kvm_minidump_vatop(kvm_t *kd, u_long va, off_t *pa) goto invalid; } if (pte & X86_PG_PS) { /* 1GB pages */ - pte += va & (1024 * 1024 * 1024 - 1); - goto shortcut; + a = (pte & PG_PS_FRAME) + + (va & (1024 * 1024 * 1024 - 1)); + break; } + /* PD page */ ofs = hpt_find(kd, pte & PG_FRAME); if (ofs == -1) { _kvm_err(kd, kd->program, @@ -359,8 +362,9 @@ _kvm_minidump_vatop(kvm_t *kd, u_long va, off_t *pa) goto invalid; } if (pte & X86_PG_PS) { /* 2MB pages */ - pte += va & (2048 * 1024 - 1); - goto shortcut; + a = (pte & PG_PS_FRAME) + + (va & (2048 * 1024 - 1)); + break; } ofs = hpt_find(kd, pte & PG_FRAME); if (ofs == -1) { @@ -383,7 +387,6 @@ _kvm_minidump_vatop(kvm_t *kd, u_long va, off_t *pa) /* * Calculate end page */ -shortcut: a = pte & PG_FRAME; break; default: -- 2.41.0