summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2020-12-03 17:12:31 +0000
committerMark Johnston <markj@FreeBSD.org>2020-12-03 17:12:31 +0000
commitb957b185946ed5ad96436b50bb118db8c1a24ded (patch)
tree125498308c1e41aa43e9666cf39b931ab6f3c5a9 /lib
parent7be2770a426dc7399b63115b1c2c7d8bebdea06a (diff)
downloadsrc-test-b957b185946ed5ad96436b50bb118db8c1a24ded.tar.gz
src-test-b957b185946ed5ad96436b50bb118db8c1a24ded.zip
Always use 64-bit physical addresses for dump_avail[] in minidumps
As of r365978, minidumps include a copy of dump_avail[]. This is an array of vm_paddr_t ranges. libkvm walks the array assuming that sizeof(vm_paddr_t) is equal to the platform "word size", but that's not correct on some platforms. For instance, i386 uses a 64-bit vm_paddr_t. Fix the problem by always dumping 64-bit addresses. On platforms where vm_paddr_t is 32 bits wide, namely arm and mips (sometimes), translate dump_avail[] to an array of uint64_t ranges. With this change, libkvm no longer needs to maintain a notion of the target word size, so get rid of it. This is a no-op on platforms where sizeof(vm_paddr_t) == 8. Reviewed by: alc, kib Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D27082
Notes
Notes: svn path=/head/; revision=368307
Diffstat (limited to 'lib')
-rw-r--r--lib/libkvm/kvm_minidump_aarch64.c3
-rw-r--r--lib/libkvm/kvm_minidump_amd64.c3
-rw-r--r--lib/libkvm/kvm_minidump_arm.c3
-rw-r--r--lib/libkvm/kvm_minidump_i386.c3
-rw-r--r--lib/libkvm/kvm_minidump_mips.c3
-rw-r--r--lib/libkvm/kvm_minidump_powerpc64.c3
-rw-r--r--lib/libkvm/kvm_minidump_riscv.c3
-rw-r--r--lib/libkvm/kvm_private.c22
-rw-r--r--lib/libkvm/kvm_private.h3
9 files changed, 12 insertions, 34 deletions
diff --git a/lib/libkvm/kvm_minidump_aarch64.c b/lib/libkvm/kvm_minidump_aarch64.c
index d962a3647b412..7fd4219fbf214 100644
--- a/lib/libkvm/kvm_minidump_aarch64.c
+++ b/lib/libkvm/kvm_minidump_aarch64.c
@@ -127,8 +127,7 @@ _aarch64_minidump_initvtop(kvm_t *kd)
sparse_off = off + aarch64_round_page(vmst->hdr.bitmapsize) +
aarch64_round_page(vmst->hdr.pmapsize);
if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off,
- vmst->hdr.bitmapsize, off, sparse_off, AARCH64_PAGE_SIZE,
- sizeof(uint64_t)) == -1) {
+ vmst->hdr.bitmapsize, off, sparse_off, AARCH64_PAGE_SIZE) == -1) {
return (-1);
}
off += aarch64_round_page(vmst->hdr.bitmapsize);
diff --git a/lib/libkvm/kvm_minidump_amd64.c b/lib/libkvm/kvm_minidump_amd64.c
index 6d9086bce8c69..d69925e474461 100644
--- a/lib/libkvm/kvm_minidump_amd64.c
+++ b/lib/libkvm/kvm_minidump_amd64.c
@@ -169,8 +169,7 @@ _amd64_minidump_initvtop(kvm_t *kd)
sparse_off = off + amd64_round_page(vmst->hdr.bitmapsize) +
amd64_round_page(vmst->hdr.pmapsize);
if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off,
- vmst->hdr.bitmapsize, off, sparse_off, AMD64_PAGE_SIZE,
- sizeof(uint64_t)) == -1) {
+ vmst->hdr.bitmapsize, off, sparse_off, AMD64_PAGE_SIZE) == -1) {
return (-1);
}
off += amd64_round_page(vmst->hdr.bitmapsize);
diff --git a/lib/libkvm/kvm_minidump_arm.c b/lib/libkvm/kvm_minidump_arm.c
index e76889c5eb8f0..82b83c10c7991 100644
--- a/lib/libkvm/kvm_minidump_arm.c
+++ b/lib/libkvm/kvm_minidump_arm.c
@@ -135,8 +135,7 @@ _arm_minidump_initvtop(kvm_t *kd)
sparse_off = off + arm_round_page(vmst->hdr.bitmapsize) +
arm_round_page(vmst->hdr.ptesize);
if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off,
- vmst->hdr.bitmapsize, off, sparse_off, ARM_PAGE_SIZE,
- sizeof(uint32_t)) == -1) {
+ vmst->hdr.bitmapsize, off, sparse_off, ARM_PAGE_SIZE) == -1) {
return (-1);
}
off += arm_round_page(vmst->hdr.bitmapsize);
diff --git a/lib/libkvm/kvm_minidump_i386.c b/lib/libkvm/kvm_minidump_i386.c
index 8349c997bdc23..4f077ca1739a1 100644
--- a/lib/libkvm/kvm_minidump_i386.c
+++ b/lib/libkvm/kvm_minidump_i386.c
@@ -131,8 +131,7 @@ _i386_minidump_initvtop(kvm_t *kd)
sparse_off = off + i386_round_page(vmst->hdr.bitmapsize) +
i386_round_page(vmst->hdr.ptesize);
if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off,
- vmst->hdr.bitmapsize, off, sparse_off, I386_PAGE_SIZE,
- sizeof(uint32_t)) == -1) {
+ vmst->hdr.bitmapsize, off, sparse_off, I386_PAGE_SIZE) == -1) {
return (-1);
}
off += i386_round_page(vmst->hdr.bitmapsize);
diff --git a/lib/libkvm/kvm_minidump_mips.c b/lib/libkvm/kvm_minidump_mips.c
index 4a0774733fc5f..dda6f35518723 100644
--- a/lib/libkvm/kvm_minidump_mips.c
+++ b/lib/libkvm/kvm_minidump_mips.c
@@ -136,8 +136,7 @@ _mips_minidump_initvtop(kvm_t *kd)
sparse_off = off + mips_round_page(vmst->hdr.bitmapsize) +
mips_round_page(vmst->hdr.ptesize);
if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off,
- vmst->hdr.bitmapsize, off, sparse_off, MIPS_PAGE_SIZE,
- sizeof(uint32_t)) == -1) {
+ vmst->hdr.bitmapsize, off, sparse_off, MIPS_PAGE_SIZE) == -1) {
return (-1);
}
off += mips_round_page(vmst->hdr.bitmapsize);
diff --git a/lib/libkvm/kvm_minidump_powerpc64.c b/lib/libkvm/kvm_minidump_powerpc64.c
index 30ba967a06282..24def29a7c830 100644
--- a/lib/libkvm/kvm_minidump_powerpc64.c
+++ b/lib/libkvm/kvm_minidump_powerpc64.c
@@ -155,8 +155,7 @@ _powerpc64_minidump_initvtop(kvm_t *kd)
/* build physical address lookup table for sparse pages */
if (_kvm_pt_init(kd, hdr->dumpavailsize, dump_avail_off,
- hdr->bitmapsize, bitmap_off, sparse_off, PPC64_PAGE_SIZE,
- sizeof(uint64_t)) == -1)
+ hdr->bitmapsize, bitmap_off, sparse_off, PPC64_PAGE_SIZE) == -1)
goto failed;
if (_kvm_pmap_init(kd, hdr->pmapsize, pmap_off) == -1)
diff --git a/lib/libkvm/kvm_minidump_riscv.c b/lib/libkvm/kvm_minidump_riscv.c
index 05d713d4b2213..4b825afe27d97 100644
--- a/lib/libkvm/kvm_minidump_riscv.c
+++ b/lib/libkvm/kvm_minidump_riscv.c
@@ -128,8 +128,7 @@ _riscv_minidump_initvtop(kvm_t *kd)
sparse_off = off + riscv_round_page(vmst->hdr.bitmapsize) +
riscv_round_page(vmst->hdr.pmapsize);
if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off,
- vmst->hdr.bitmapsize, off, sparse_off, RISCV_PAGE_SIZE,
- sizeof(uint64_t)) == -1) {
+ vmst->hdr.bitmapsize, off, sparse_off, RISCV_PAGE_SIZE) == -1) {
return (-1);
}
off += riscv_round_page(vmst->hdr.bitmapsize);
diff --git a/lib/libkvm/kvm_private.c b/lib/libkvm/kvm_private.c
index 9424502adfad5..d853d16431018 100644
--- a/lib/libkvm/kvm_private.c
+++ b/lib/libkvm/kvm_private.c
@@ -291,8 +291,7 @@ _kvm_map_get(kvm_t *kd, u_long pa, unsigned int page_size)
int
_kvm_pt_init(kvm_t *kd, size_t dump_avail_size, off_t dump_avail_off,
- size_t map_len, off_t map_off, off_t sparse_off, int page_size,
- int word_size)
+ size_t map_len, off_t map_off, off_t sparse_off, int page_size)
{
uint64_t *addr;
uint32_t *popcount_bin;
@@ -311,14 +310,8 @@ _kvm_pt_init(kvm_t *kd, size_t dump_avail_size, off_t dump_avail_off,
* last_pa. Create an implied dump_avail that
* expresses this.
*/
- kd->dump_avail = calloc(4, word_size);
- if (word_size == sizeof(uint32_t)) {
- ((uint32_t *)kd->dump_avail)[1] = _kvm32toh(kd,
- map_len * 8 * page_size);
- } else {
- kd->dump_avail[1] = _kvm64toh(kd,
- map_len * 8 * page_size);
- }
+ kd->dump_avail = calloc(4, sizeof(uint64_t));
+ kd->dump_avail[1] = _kvm64toh(kd, map_len * 8 * page_size);
}
/*
@@ -375,7 +368,6 @@ _kvm_pt_init(kvm_t *kd, size_t dump_avail_size, off_t dump_avail_off,
kd->pt_sparse_off = sparse_off;
kd->pt_sparse_size = (uint64_t)*popcount_bin * page_size;
kd->pt_page_size = page_size;
- kd->pt_word_size = word_size;
/*
* Map the sparse page array. This is useful for performing point
@@ -419,13 +411,7 @@ _kvm_pmap_init(kvm_t *kd, uint32_t pmap_size, off_t pmap_off)
static inline uint64_t
dump_avail_n(kvm_t *kd, long i)
{
- uint32_t *d32;
-
- if (kd->pt_word_size == sizeof(uint32_t)) {
- d32 = (uint32_t *)kd->dump_avail;
- return (_kvm32toh(kd, d32[i]));
- } else
- return (_kvm64toh(kd, kd->dump_avail[i]));
+ return (_kvm64toh(kd, kd->dump_avail[i]));
}
uint64_t
diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h
index 5a8ea524d0a90..d4ec1ff1837b3 100644
--- a/lib/libkvm/kvm_private.h
+++ b/lib/libkvm/kvm_private.h
@@ -112,7 +112,6 @@ struct __kvm {
uint64_t pt_sparse_size;
uint32_t *pt_popcounts;
unsigned int pt_page_size;
- unsigned int pt_word_size;
/* Page & sparse map structures. */
void *page_map;
@@ -190,7 +189,7 @@ kvaddr_t _kvm_dpcpu_validaddr(kvm_t *, kvaddr_t);
int _kvm_probe_elf_kernel(kvm_t *, int, int);
int _kvm_is_minidump(kvm_t *);
int _kvm_read_core_phdrs(kvm_t *, size_t *, GElf_Phdr **);
-int _kvm_pt_init(kvm_t *, size_t, off_t, size_t, off_t, off_t, int, int);
+int _kvm_pt_init(kvm_t *, size_t, off_t, size_t, off_t, off_t, int);
off_t _kvm_pt_find(kvm_t *, uint64_t, unsigned int);
int _kvm_visit_cb(kvm_t *, kvm_walk_pages_cb_t *, void *, u_long,
u_long, u_long, vm_prot_t, size_t, unsigned int);