Page MenuHomeFreeBSD

D26131.1784971880.diff
No OneTemporary

Size
23 KB
Referenced Files
None
Subscribers
None

D26131.1784971880.diff

Index: lib/libkvm/kvm_minidump_aarch64.c
===================================================================
--- lib/libkvm/kvm_minidump_aarch64.c
+++ lib/libkvm/kvm_minidump_aarch64.c
@@ -121,8 +121,8 @@
/* build physical address lookup table for sparse pages */
sparse_off = off + aarch64_round_page(vmst->hdr.bitmapsize) +
aarch64_round_page(vmst->hdr.pmapsize);
- if (_kvm_pt_init(kd, vmst->hdr.bitmapsize, off, sparse_off,
- AARCH64_PAGE_SIZE, sizeof(uint64_t)) == -1) {
+ if (_kvm_pt_init(kd, sizeof(vmst->hdr), vmst->hdr.bitmapsize, off,
+ sparse_off, AARCH64_PAGE_SIZE, sizeof(uint64_t)) == -1) {
return (-1);
}
off += aarch64_round_page(vmst->hdr.bitmapsize);
@@ -257,7 +257,7 @@
}
while (_kvm_bitmap_next(&bm, &bmindex)) {
- pa = bmindex * AARCH64_PAGE_SIZE;
+ pa = _kvm_bit_id_pa(kd, bmindex, AARCH64_PAGE_SIZE);
dva = vm->hdr.dmapbase + pa;
if (vm->hdr.dmapend < (dva + AARCH64_PAGE_SIZE))
break;
Index: lib/libkvm/kvm_minidump_amd64.c
===================================================================
--- lib/libkvm/kvm_minidump_amd64.c
+++ lib/libkvm/kvm_minidump_amd64.c
@@ -163,8 +163,8 @@
sparse_off = off + amd64_round_page(vmst->hdr.bitmapsize) +
amd64_round_page(vmst->hdr.pmapsize);
- if (_kvm_pt_init(kd, vmst->hdr.bitmapsize, off, sparse_off,
- AMD64_PAGE_SIZE, sizeof(uint64_t)) == -1) {
+ if (_kvm_pt_init(kd, sizeof(vmst->hdr), vmst->hdr.bitmapsize, off,
+ sparse_off, AMD64_PAGE_SIZE, sizeof(uint64_t)) == -1) {
return (-1);
}
off += amd64_round_page(vmst->hdr.bitmapsize);
@@ -372,7 +372,7 @@
pa = (pde & AMD64_PG_PS_FRAME) +
((va & AMD64_PDRMASK) ^ VA_OFF(vm, va));
dva = vm->hdr.dmapbase + pa;
- _kvm_bitmap_set(&bm, pa, AMD64_PAGE_SIZE);
+ _kvm_bitmap_set(&bm, _kvm_pa_bit_id(kd, pa, AMD64_PAGE_SIZE));
if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva,
_amd64_entry_to_prot(pde), AMD64_NBPDR, pgsz)) {
goto out;
@@ -392,7 +392,8 @@
pa = pte & AMD64_PG_FRAME;
dva = vm->hdr.dmapbase + pa;
if ((pte & AMD64_PG_V) != 0) {
- _kvm_bitmap_set(&bm, pa, AMD64_PAGE_SIZE);
+ _kvm_bitmap_set(&bm,
+ _kvm_pa_bit_id(kd, pa, AMD64_PAGE_SIZE));
if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva,
_amd64_entry_to_prot(pte), pgsz, 0)) {
goto out;
@@ -403,7 +404,7 @@
}
while (_kvm_bitmap_next(&bm, &bmindex)) {
- pa = bmindex * AMD64_PAGE_SIZE;
+ pa = _kvm_bit_id_pa(kd, bmindex, AMD64_PAGE_SIZE);
dva = vm->hdr.dmapbase + pa;
if (vm->hdr.dmapend < (dva + pgsz))
break;
Index: lib/libkvm/kvm_minidump_arm.c
===================================================================
--- lib/libkvm/kvm_minidump_arm.c
+++ lib/libkvm/kvm_minidump_arm.c
@@ -129,8 +129,8 @@
sparse_off = off + arm_round_page(vmst->hdr.bitmapsize) +
arm_round_page(vmst->hdr.ptesize);
- if (_kvm_pt_init(kd, vmst->hdr.bitmapsize, off, sparse_off,
- ARM_PAGE_SIZE, sizeof(uint32_t)) == -1) {
+ if (_kvm_pt_init(kd, sizeof(vmst->hdr), vmst->hdr.bitmapsize, off,
+ sparse_off, ARM_PAGE_SIZE, sizeof(uint32_t)) == -1) {
return (-1);
}
off += arm_round_page(vmst->hdr.bitmapsize);
Index: lib/libkvm/kvm_minidump_i386.c
===================================================================
--- lib/libkvm/kvm_minidump_i386.c
+++ lib/libkvm/kvm_minidump_i386.c
@@ -125,8 +125,8 @@
sparse_off = off + i386_round_page(vmst->hdr.bitmapsize) +
i386_round_page(vmst->hdr.ptesize);
- if (_kvm_pt_init(kd, vmst->hdr.bitmapsize, off, sparse_off,
- I386_PAGE_SIZE, sizeof(uint32_t)) == -1) {
+ if (_kvm_pt_init(kd, sizeof(vmst->hdr), vmst->hdr.bitmapsize, off,
+ sparse_off, I386_PAGE_SIZE, sizeof(uint32_t)) == -1) {
return (-1);
}
off += i386_round_page(vmst->hdr.bitmapsize);
Index: lib/libkvm/kvm_minidump_mips.c
===================================================================
--- lib/libkvm/kvm_minidump_mips.c
+++ lib/libkvm/kvm_minidump_mips.c
@@ -130,8 +130,8 @@
sparse_off = off + mips_round_page(vmst->hdr.bitmapsize) +
mips_round_page(vmst->hdr.ptesize);
- if (_kvm_pt_init(kd, vmst->hdr.bitmapsize, off, sparse_off,
- MIPS_PAGE_SIZE, sizeof(uint32_t)) == -1) {
+ if (_kvm_pt_init(kd, sizeof(vmst->hdr), vmst->hdr.bitmapsize, off,
+ sparse_off, MIPS_PAGE_SIZE, sizeof(uint32_t)) == -1) {
return (-1);
}
off += mips_round_page(vmst->hdr.bitmapsize);
Index: lib/libkvm/kvm_minidump_powerpc64.c
===================================================================
--- lib/libkvm/kvm_minidump_powerpc64.c
+++ lib/libkvm/kvm_minidump_powerpc64.c
@@ -151,8 +151,8 @@
(uintmax_t)pmap_off, (uintmax_t)sparse_off);
/* build physical address lookup table for sparse pages */
- if (_kvm_pt_init(kd, hdr->bitmapsize, bitmap_off, sparse_off,
- PPC64_PAGE_SIZE, sizeof(uint64_t)) == -1)
+ if (_kvm_pt_init(kd, sizeof(*hdr), hdr->bitmapsize, bitmap_off,
+ sparse_off, PPC64_PAGE_SIZE, sizeof(uint64_t)) == -1)
goto failed;
if (_kvm_pmap_init(kd, hdr->pmapsize, pmap_off) == -1)
Index: lib/libkvm/kvm_minidump_riscv.c
===================================================================
--- lib/libkvm/kvm_minidump_riscv.c
+++ lib/libkvm/kvm_minidump_riscv.c
@@ -122,8 +122,8 @@
/* build physical address lookup table for sparse pages */
sparse_off = off + riscv_round_page(vmst->hdr.bitmapsize) +
riscv_round_page(vmst->hdr.pmapsize);
- if (_kvm_pt_init(kd, vmst->hdr.bitmapsize, off, sparse_off,
- RISCV_PAGE_SIZE, sizeof(uint64_t)) == -1) {
+ if (_kvm_pt_init(kd, sizeof(vmst->hdr), vmst->hdr.bitmapsize, off,
+ sparse_off, RISCV_PAGE_SIZE, sizeof(uint64_t)) == -1) {
return (-1);
}
off += riscv_round_page(vmst->hdr.bitmapsize);
@@ -258,7 +258,7 @@
}
while (_kvm_bitmap_next(&bm, &bmindex)) {
- pa = bmindex * RISCV_PAGE_SIZE;
+ pa = _kvm_bit_id_pa(kd, bmindex, RISCV_PAGE_SIZE);
dva = vm->hdr.dmapbase + pa;
if (vm->hdr.dmapend < (dva + RISCV_PAGE_SIZE))
break;
Index: lib/libkvm/kvm_private.h
===================================================================
--- lib/libkvm/kvm_private.h
+++ lib/libkvm/kvm_private.h
@@ -106,6 +106,8 @@
/* Page table lookup structures. */
uint64_t *pt_map;
size_t pt_map_size;
+ kpaddr_t *dump_avail;
+ size_t dump_avail_size;
off_t pt_sparse_off;
uint64_t pt_sparse_size;
uint32_t *pt_popcounts;
@@ -152,8 +154,11 @@
return (be64toh(val));
}
+uint64_t _kvm_pa_bit_id(kvm_t *kd, uint64_t pa, unsigned int page_size);
+uint64_t _kvm_bit_id_pa(kvm_t *kd, uint64_t bit_id, unsigned int page_size);
+
int _kvm_bitmap_init(struct kvm_bitmap *, u_long, u_long *);
-void _kvm_bitmap_set(struct kvm_bitmap *, u_long, unsigned int);
+void _kvm_bitmap_set(struct kvm_bitmap *, u_long);
int _kvm_bitmap_next(struct kvm_bitmap *, u_long *);
void _kvm_bitmap_deinit(struct kvm_bitmap *);
@@ -173,7 +178,7 @@
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, off_t, int, int);
+int _kvm_pt_init(kvm_t *, off_t, size_t, off_t, off_t, int, 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);
Index: lib/libkvm/kvm_private.c
===================================================================
--- lib/libkvm/kvm_private.c
+++ lib/libkvm/kvm_private.c
@@ -290,15 +290,42 @@
}
int
-_kvm_pt_init(kvm_t *kd, size_t map_len, off_t map_off, off_t sparse_off,
- int page_size, int word_size)
+_kvm_pt_init(kvm_t *kd, off_t dump_avail_off, size_t map_len, off_t map_off,
+ off_t sparse_off, int page_size, int word_size)
{
uint64_t *addr;
uint32_t *popcount_bin;
- int bin_popcounts = 0;
+ int bin_popcounts = 0, i;
uint64_t pc_bins, res;
ssize_t rd;
+ i = 0;
+ do {
+ if (i * sizeof(kpaddr_t) >= kd->dump_avail_size) {
+ kd->dump_avail_size = MAX(8 * sizeof(kpaddr_t),
+ 2 * kd->dump_avail_size);
+ kd->dump_avail = realloc(kd->dump_avail,
+ kd->dump_avail_size);
+ if (kd->dump_avail == NULL) {
+ _kvm_err(kd, kd->program, "cannot allocate %zu "
+ "bytes for dump_avail", kd->dump_avail_size);
+ return (-1);
+ }
+ }
+ rd = pread(kd->pmfd, &kd->dump_avail[i], 2 * sizeof(kpaddr_t),
+ dump_avail_off);
+ if (rd < 0 || rd != 2 * sizeof(kpaddr_t)) {
+ _kvm_err(kd, kd->program, "cannot read %zu bytes for "
+ "dump_avail", 2 * sizeof(kpaddr_t));
+ return (-1);
+ }
+ i += 2;
+ dump_avail_off += 2 * sizeof(kpaddr_t);
+ } while (kd->dump_avail[i - 1] != 0 && i < 128);
+
+ if (i >= 128)
+ kd->dump_avail[0] = kd->dump_avail[1] = 0;
+
/*
* Map the bitmap specified by the arguments.
*/
@@ -394,6 +421,45 @@
return (0);
}
+uint64_t
+_kvm_pa_bit_id(kvm_t *kd, uint64_t pa, unsigned int page_size)
+{
+ uint64_t adj;
+ int i;
+
+ adj = 0;
+ for (i = 0; kd->dump_avail[i + 1] != 0; i += 2) {
+ if (pa >= kd->dump_avail[i + 1]) {
+ adj += howmany(kd->dump_avail[i + 1], page_size) -
+ kd->dump_avail[i] / page_size;
+ } else {
+ return (pa / page_size -
+ kd->dump_avail[i] / page_size + adj);
+ }
+ }
+ return (adj + pa / page_size -
+ howmany(kd->dump_avail[i - 1], page_size));
+}
+
+uint64_t
+_kvm_bit_id_pa(kvm_t *kd, uint64_t bit_id, unsigned int page_size)
+{
+ uint64_t sz;
+ int i;
+
+ for (i = 0; kd->dump_avail[i + 1] != 0; i += 2) {
+ sz = howmany(kd->dump_avail[i + 1], page_size) -
+ kd->dump_avail[i] / page_size;
+ if (bit_id < sz) {
+ return (rounddown2(kd->dump_avail[i], page_size) +
+ bit_id * page_size);
+ }
+ bit_id -= sz;
+ }
+ return (bit_id * page_size +
+ roundup2(kd->dump_avail[i - 1], page_size));
+}
+
/*
* Find the offset for the given physical page address; returns -1 otherwise.
*
@@ -412,7 +478,7 @@
_kvm_pt_find(kvm_t *kd, uint64_t pa, unsigned int page_size)
{
uint64_t *bitmap = kd->pt_map;
- uint64_t pte_bit_id = pa / page_size;
+ uint64_t pte_bit_id = _kvm_pa_bit_id(kd, pa, page_size);
uint64_t pte_u64 = pte_bit_id / BITS_IN(*bitmap);
uint64_t popcount_id = pte_bit_id / POPCOUNT_BITS;
uint64_t pte_mask = 1ULL << (pte_bit_id % BITS_IN(*bitmap));
@@ -714,9 +780,8 @@
}
void
-_kvm_bitmap_set(struct kvm_bitmap *bm, u_long pa, unsigned int page_size)
+_kvm_bitmap_set(struct kvm_bitmap *bm, u_long bm_index)
{
- u_long bm_index = pa / page_size;
uint8_t *byte = &bm->map[bm_index / 8];
*byte |= (1UL << (bm_index % 8));
Index: sys/amd64/amd64/minidump_machdep.c
===================================================================
--- sys/amd64/amd64/minidump_machdep.c
+++ sys/amd64/amd64/minidump_machdep.c
@@ -216,6 +216,7 @@
int
minidumpsys(struct dumperinfo *di)
{
+ kpaddr_t *dump_avail_out;
uint32_t pmapsize;
vm_offset_t va;
int error;
@@ -317,7 +318,7 @@
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
mdhdr.version = MINIDUMP_VERSION;
mdhdr.msgbufsize = msgbufp->msg_size;
- mdhdr.bitmapsize = BITSET_SIZE(vm_page_dump_pages);
+ mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
mdhdr.pmapsize = pmapsize;
mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS;
mdhdr.dmapbase = DMAP_MIN_ADDRESS;
@@ -336,6 +337,12 @@
/* Dump my header */
bzero(&fakepd, sizeof(fakepd));
bcopy(&mdhdr, &fakepd, sizeof(mdhdr));
+ dump_avail_out = (kpaddr_t *)((char *)fakepd + sizeof(mdhdr));
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ dump_avail_out[i] = dump_avail[i];
+ dump_avail_out[i + 1] = dump_avail[i + 1];
+ }
+ dump_avail_out[i] = dump_avail_out[i + 1] = 0;
error = blk_write(di, (char *)&fakepd, 0, PAGE_SIZE);
if (error)
goto fail;
Index: sys/amd64/include/minidump.h
===================================================================
--- sys/amd64/include/minidump.h
+++ sys/amd64/include/minidump.h
@@ -32,7 +32,7 @@
#define _MACHINE_MINIDUMP_H_ 1
#define MINIDUMP_MAGIC "minidump FreeBSD/amd64"
-#define MINIDUMP_VERSION 2
+#define MINIDUMP_VERSION 3
struct minidumphdr {
char magic[24];
Index: sys/arm/arm/minidump_machdep.c
===================================================================
--- sys/arm/arm/minidump_machdep.c
+++ sys/arm/arm/minidump_machdep.c
@@ -176,6 +176,7 @@
{
struct minidumphdr mdhdr;
uint64_t dumpsize;
+ kpaddr_t *dump_avail_out;
uint32_t ptesize;
uint32_t pa, prev_pa = 0, count = 0;
vm_offset_t va;
@@ -223,7 +224,7 @@
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
mdhdr.version = MINIDUMP_VERSION;
mdhdr.msgbufsize = msgbufp->msg_size;
- mdhdr.bitmapsize = BITSET_SIZE(vm_page_dump_pages);
+ mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
mdhdr.ptesize = ptesize;
mdhdr.kernbase = KERNBASE;
mdhdr.arch = __ARM_ARCH;
@@ -245,6 +246,12 @@
/* Dump my header */
bzero(dumpbuf, sizeof(dumpbuf));
bcopy(&mdhdr, dumpbuf, sizeof(mdhdr));
+ dump_avail_out = (kpaddr_t *)(dumpbuf + sizeof(mdhdr));
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ dump_avail_out[i] = dump_avail[i];
+ dump_avail_out[i + 1] = dump_avail[i + 1];
+ }
+ dump_avail_out[i] = dump_avail_out[i + 1] = 0;
error = blk_write(di, dumpbuf, 0, PAGE_SIZE);
if (error)
goto fail;
Index: sys/arm/include/minidump.h
===================================================================
--- sys/arm/include/minidump.h
+++ sys/arm/include/minidump.h
@@ -33,7 +33,7 @@
#define _MACHINE_MINIDUMP_H_
#define MINIDUMP_MAGIC "minidump FreeBSD/arm"
-#define MINIDUMP_VERSION 1
+#define MINIDUMP_VERSION 2
/*
* The first page of vmcore is dedicated to the following header.
Index: sys/arm64/arm64/minidump_machdep.c
===================================================================
--- sys/arm64/arm64/minidump_machdep.c
+++ sys/arm64/arm64/minidump_machdep.c
@@ -208,6 +208,7 @@
pt_entry_t *l3;
vm_offset_t va;
vm_paddr_t pa;
+ kpaddr_t *dump_avail_out;
uint32_t pmapsize;
int bit, error, i, j, retry_count;
@@ -265,7 +266,7 @@
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
mdhdr.version = MINIDUMP_VERSION;
mdhdr.msgbufsize = msgbufp->msg_size;
- mdhdr.bitmapsize = BITSET_SIZE(vm_page_dump_pages);
+ mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
mdhdr.pmapsize = pmapsize;
mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS;
mdhdr.dmapphys = DMAP_MIN_PHYSADDR;
@@ -285,6 +286,12 @@
/* Dump my header */
bzero(&tmpbuffer, sizeof(tmpbuffer));
bcopy(&mdhdr, &tmpbuffer, sizeof(mdhdr));
+ dump_avail_out = (kpaddr_t *)((char *)tmpbuffer + sizeof(mdhdr));
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ dump_avail_out[i] = dump_avail[i];
+ dump_avail_out[i + 1] = dump_avail[i + 1];
+ }
+ dump_avail_out[i] = dump_avail_out[i + 1] = 0;
error = blk_write(di, (char *)&tmpbuffer, 0, PAGE_SIZE);
if (error)
goto fail;
Index: sys/arm64/include/minidump.h
===================================================================
--- sys/arm64/include/minidump.h
+++ sys/arm64/include/minidump.h
@@ -31,7 +31,7 @@
#define _MACHINE_MINIDUMP_H_ 1
#define MINIDUMP_MAGIC "minidump FreeBSD/arm64"
-#define MINIDUMP_VERSION 1
+#define MINIDUMP_VERSION 2
struct minidumphdr {
char magic[24];
Index: sys/i386/i386/minidump_machdep_base.c
===================================================================
--- sys/i386/i386/minidump_machdep_base.c
+++ sys/i386/i386/minidump_machdep_base.c
@@ -176,6 +176,7 @@
minidumpsys(struct dumperinfo *di)
{
uint64_t dumpsize;
+ kpaddr_t *dump_avail_out;
uint32_t ptesize;
vm_offset_t va;
int error;
@@ -260,6 +261,12 @@
/* Dump my header */
bzero(&fakept, sizeof(fakept));
bcopy(&mdhdr, &fakept, sizeof(mdhdr));
+ dump_avail_out = (kpaddr_t *)((char *)fakept + sizeof(mdhdr));
+ for (i = 0; dump_avail[i + 1] != 0; i++) {
+ dump_avail_out[i] = dump_avail[i];
+ dump_avail_out[i + 1] = dump_avail[i + 1];
+ }
+ dump_avail_out[i] = dump_avail_out[i + 1] = 0;
error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
if (error)
goto fail;
Index: sys/i386/include/minidump.h
===================================================================
--- sys/i386/include/minidump.h
+++ sys/i386/include/minidump.h
@@ -32,7 +32,7 @@
#define _MACHINE_MINIDUMP_H_ 1
#define MINIDUMP_MAGIC "minidump FreeBSD/i386"
-#define MINIDUMP_VERSION 1
+#define MINIDUMP_VERSION 2
struct minidumphdr {
char magic[24];
Index: sys/mips/include/minidump.h
===================================================================
--- sys/mips/include/minidump.h
+++ sys/mips/include/minidump.h
@@ -32,7 +32,7 @@
#define _MACHINE_MINIDUMP_H_ 1
#define MINIDUMP_MAGIC "minidump FreeBSD/mips"
-#define MINIDUMP_VERSION 1
+#define MINIDUMP_VERSION 2
struct minidumphdr {
char magic[24];
Index: sys/mips/mips/minidump_machdep.c
===================================================================
--- sys/mips/mips/minidump_machdep.c
+++ sys/mips/mips/minidump_machdep.c
@@ -164,6 +164,7 @@
minidumpsys(struct dumperinfo *di)
{
struct minidumphdr mdhdr;
+ kpaddr_t *dump_avail_out;
uint32_t ptesize;
vm_paddr_t pa;
vm_offset_t prev_pte = 0;
@@ -222,7 +223,7 @@
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
mdhdr.version = MINIDUMP_VERSION;
mdhdr.msgbufsize = msgbufp->msg_size;
- mdhdr.bitmapsize = BITSET_SIZE(vm_page_dump_pages);
+ mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
mdhdr.ptesize = ptesize;
mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS;
@@ -239,6 +240,12 @@
/* Dump my header */
bzero(tmpbuffer, sizeof(tmpbuffer));
bcopy(&mdhdr, tmpbuffer, sizeof(mdhdr));
+ dump_avail_out = (kpaddr_t *)(tmpbuffer + sizeof(mdhdr));
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ dump_avail_out[i] = dump_avail[i];
+ dump_avail_out[i + 1] = dump_avail[i + 1];
+ }
+ dump_avail_out[i] = dump_avail_out[i + 1] = 0;
error = write_buffer(di, tmpbuffer, PAGE_SIZE);
if (error)
goto fail;
Index: sys/powerpc/include/minidump.h
===================================================================
--- sys/powerpc/include/minidump.h
+++ sys/powerpc/include/minidump.h
@@ -31,7 +31,7 @@
#define _MACHINE_MINIDUMP_H_ 1
#define MINIDUMP_MAGIC "minidump FreeBSD/powerpc64"
-#define MINIDUMP_VERSION 1
+#define MINIDUMP_VERSION 2
struct minidumphdr {
char magic[32];
Index: sys/powerpc/powerpc/minidump_machdep.c
===================================================================
--- sys/powerpc/powerpc/minidump_machdep.c
+++ sys/powerpc/powerpc/minidump_machdep.c
@@ -249,6 +249,7 @@
int bit, error, i, retry_count;
uint32_t pmapsize;
struct minidumphdr mdhdr;
+ kpaddr_t *dump_avail_out;
retry_count = 0;
retry:
@@ -288,7 +289,7 @@
strncpy(mdhdr.mmu_name, pmap_mmu_name(), sizeof(mdhdr.mmu_name) - 1);
mdhdr.version = MINIDUMP_VERSION;
mdhdr.msgbufsize = msgbufp->msg_size;
- mdhdr.bitmapsize = BITSET_SIZE(vm_page_dump_pages);
+ mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
mdhdr.pmapsize = pmapsize;
mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS;
mdhdr.kernend = VM_MAX_SAFE_KERNEL_ADDRESS;
@@ -311,6 +312,12 @@
/* Dump minidump header */
bzero(pgbuf, sizeof(pgbuf));
memcpy(pgbuf, &mdhdr, sizeof(mdhdr));
+ dump_avail_out = (kpaddr_t *)(pgbuf + sizeof(mdhdr));
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ dump_avail_out[i] = dump_avail[i];
+ dump_avail_out[i + 1] = dump_avail[i + 1];
+ }
+ dump_avail_out[i] = dump_avail_out[i + 1] = 0;
error = blk_write(di, pgbuf, 0, PAGE_SIZE);
if (error)
goto fail;
Index: sys/riscv/include/minidump.h
===================================================================
--- sys/riscv/include/minidump.h
+++ sys/riscv/include/minidump.h
@@ -31,7 +31,7 @@
#define _MACHINE_MINIDUMP_H_ 1
#define MINIDUMP_MAGIC "minidump FreeBSD/riscv"
-#define MINIDUMP_VERSION 1
+#define MINIDUMP_VERSION 2
struct minidumphdr {
char magic[24];
Index: sys/riscv/riscv/minidump_machdep.c
===================================================================
--- sys/riscv/riscv/minidump_machdep.c
+++ sys/riscv/riscv/minidump_machdep.c
@@ -213,6 +213,7 @@
pd_entry_t *l1, *l2;
pt_entry_t *l3;
struct minidumphdr mdhdr;
+ kpaddr_t *dump_avail_out;
uint32_t pmapsize;
vm_offset_t va;
vm_paddr_t pa;
@@ -274,7 +275,7 @@
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
mdhdr.version = MINIDUMP_VERSION;
mdhdr.msgbufsize = msgbufp->msg_size;
- mdhdr.bitmapsize = BITSET_SIZE(vm_page_dump_pages);
+ mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
mdhdr.pmapsize = pmapsize;
mdhdr.kernbase = KERNBASE;
mdhdr.dmapphys = DMAP_MIN_PHYSADDR;
@@ -294,6 +295,12 @@
/* Dump minidump header */
bzero(&tmpbuffer, sizeof(tmpbuffer));
bcopy(&mdhdr, &tmpbuffer, sizeof(mdhdr));
+ dump_avail_out = (kpaddr_t *)((char *)tmpbuffer + sizeof(mdhdr));
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ dump_avail_out[i] = dump_avail[i];
+ dump_avail_out[i + 1] = dump_avail[i + 1];
+ }
+ dump_avail_out[i] = dump_avail_out[i + 1] = 0;
error = blk_write(di, (char *)&tmpbuffer, 0, PAGE_SIZE);
if (error)
goto fail;
Index: sys/vm/vm_page.h
===================================================================
--- sys/vm/vm_page.h
+++ sys/vm/vm_page.h
@@ -589,22 +589,65 @@
extern struct bitset *vm_page_dump;
extern long vm_page_dump_pages;
+extern vm_paddr_t dump_avail[];
static inline void
dump_add_page(vm_paddr_t pa)
{
- BIT_SET_ATOMIC(vm_page_dump_pages, pa >> PAGE_SHIFT, vm_page_dump);
+ vm_pindex_t adj;
+ int i;
+
+ adj = 0;
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ if (pa >= dump_avail[i] && pa < dump_avail[i + 1]) {
+ BIT_SET_ATOMIC(vm_page_dump_pages,
+ (pa >> PAGE_SHIFT) - (dump_avail[i] >> PAGE_SHIFT) + adj,
+ vm_page_dump);
+ return;
+ }
+ adj += howmany(dump_avail[i + 1], PAGE_SIZE) -
+ dump_avail[i] / PAGE_SIZE;
+ }
}
static inline void
dump_drop_page(vm_paddr_t pa)
{
- BIT_CLR_ATOMIC(vm_page_dump_pages, pa >> PAGE_SHIFT, vm_page_dump);
+ vm_pindex_t adj;
+ int i;
+
+ adj = 0;
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ if (pa >= dump_avail[i] && pa < dump_avail[i + 1]) {
+ BIT_CLR_ATOMIC(vm_page_dump_pages,
+ (pa >> PAGE_SHIFT) - (dump_avail[i] >> PAGE_SHIFT) + adj,
+ vm_page_dump);
+ return;
+ }
+ adj += howmany(dump_avail[i + 1], PAGE_SIZE) -
+ dump_avail[i] / PAGE_SIZE;
+ }
+}
+
+static inline vm_paddr_t
+vm_page_dump_index_to_pa(int bit)
+{
+ int i, tot;
+
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ tot = howmany(dump_avail[i + 1], PAGE_SIZE) -
+ dump_avail[i] / PAGE_SIZE;
+ if (bit < tot)
+ return ((vm_paddr_t)bit * PAGE_SIZE +
+ dump_avail[i] & ~PAGE_MASK);
+ bit -= tot;
+ }
+ return ((vm_paddr_t)NULL);
}
#define VM_PAGE_DUMP_FOREACH(bit, pa) \
for ((bit) = BIT_FFS(vm_page_dump_pages, vm_page_dump); \
- pa = ((bit) - 1) * PAGE_SIZE, (bit) != 0; \
+ pa = vm_page_dump_index_to_pa(bit - 1), (bit) != 0; \
(bit) = BIT_FFS_AT(vm_page_dump_pages, vm_page_dump, bit)) \
bool vm_page_busy_acquire(vm_page_t m, int allocflags);
Index: sys/vm/vm_page.c
===================================================================
--- sys/vm/vm_page.c
+++ sys/vm/vm_page.c
@@ -603,10 +603,13 @@
* included should the sf_buf code decide to use them.
*/
last_pa = 0;
- for (i = 0; dump_avail[i + 1] != 0; i += 2)
+ vm_page_dump_pages = 0;
+ for (i = 0; dump_avail[i + 1] != 0; i += 2) {
+ vm_page_dump_pages += howmany(dump_avail[i + 1], PAGE_SIZE) -
+ dump_avail[i] / PAGE_SIZE;
if (dump_avail[i + 1] > last_pa)
last_pa = dump_avail[i + 1];
- vm_page_dump_pages = last_pa / PAGE_SIZE;
+ }
vm_page_dump_size = round_page(BITSET_SIZE(vm_page_dump_pages));
new_end -= vm_page_dump_size;
vm_page_dump = (void *)(uintptr_t)pmap_map(&vaddr, new_end,

File Metadata

Mime Type
text/plain
Expires
Sat, Jul 25, 9:31 AM (5 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29254381
Default Alt Text
D26131.1784971880.diff (23 KB)

Event Timeline