Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147972120
D26131.1784971880.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
23 KB
Referenced Files
None
Subscribers
None
D26131.1784971880.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D26131: Sparsify the vm_page_dump bitmap
Attached
Detach File
Event Timeline
Log In to Comment