Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/minidump_machdep.c
Context not available. | |||||
CTASSERT(sizeof(struct kerneldumpheader) == 512); | CTASSERT(sizeof(struct kerneldumpheader) == 512); | ||||
uint64_t *vm_page_dump; | |||||
int vm_page_dump_size; | |||||
static struct kerneldumpheader kdh; | static struct kerneldumpheader kdh; | ||||
/* Handle chunked writes. */ | /* Handle chunked writes. */ | ||||
Context not available. | |||||
static uint64_t tmpbuffer[Ln_ENTRIES]; | static uint64_t tmpbuffer[Ln_ENTRIES]; | ||||
CTASSERT(sizeof(*vm_page_dump) == 8); | |||||
static int | static int | ||||
is_dumpable(vm_paddr_t pa) | is_dumpable(vm_paddr_t pa) | ||||
{ | { | ||||
Context not available. | |||||
pt_entry_t *l3; | pt_entry_t *l3; | ||||
vm_offset_t va; | vm_offset_t va; | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
uint64_t bits; | |||||
uint32_t pmapsize; | uint32_t pmapsize; | ||||
int bit, error, i, j, retry_count; | int error, i, j, retry_count; | ||||
retry_count = 0; | retry_count = 0; | ||||
retry: | retry: | ||||
Context not available. | |||||
/* Calculate dump size. */ | /* Calculate dump size. */ | ||||
dumpsize = pmapsize; | dumpsize = pmapsize; | ||||
dumpsize += round_page(msgbufp->msg_size); | dumpsize += round_page(msgbufp->msg_size); | ||||
dumpsize += round_page(vm_page_dump_size); | dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages)); | ||||
for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) { | VM_PAGE_DUMP_FOREACH(pa) { | ||||
bits = vm_page_dump[i]; | if (is_dumpable(pa)) | ||||
while (bits) { | dumpsize += PAGE_SIZE; | ||||
bit = ffsl(bits) - 1; | else | ||||
pa = (((uint64_t)i * sizeof(*vm_page_dump) * NBBY) + | dump_drop_page(pa); | ||||
bit) * PAGE_SIZE; | |||||
/* Clear out undumpable pages now if needed */ | |||||
if (is_dumpable(pa)) | |||||
dumpsize += PAGE_SIZE; | |||||
else | |||||
dump_drop_page(pa); | |||||
bits &= ~(1ul << bit); | |||||
} | |||||
} | } | ||||
dumpsize += PAGE_SIZE; | dumpsize += PAGE_SIZE; | ||||
Context not available. | |||||
strcpy(mdhdr.magic, MINIDUMP_MAGIC); | strcpy(mdhdr.magic, MINIDUMP_MAGIC); | ||||
mdhdr.version = MINIDUMP_VERSION; | mdhdr.version = MINIDUMP_VERSION; | ||||
mdhdr.msgbufsize = msgbufp->msg_size; | mdhdr.msgbufsize = msgbufp->msg_size; | ||||
mdhdr.bitmapsize = vm_page_dump_size; | mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages)); | ||||
mdhdr.pmapsize = pmapsize; | mdhdr.pmapsize = pmapsize; | ||||
mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS; | mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS; | ||||
mdhdr.dmapphys = DMAP_MIN_PHYSADDR; | mdhdr.dmapphys = DMAP_MIN_PHYSADDR; | ||||
Context not available. | |||||
/* Dump bitmap */ | /* Dump bitmap */ | ||||
error = blk_write(di, (char *)vm_page_dump, 0, | error = blk_write(di, (char *)vm_page_dump, 0, | ||||
round_page(vm_page_dump_size)); | round_page(BITSET_SIZE(vm_page_dump_pages))); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
Context not available. | |||||
} | } | ||||
/* Dump memory chunks */ | /* Dump memory chunks */ | ||||
for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) { | VM_PAGE_DUMP_FOREACH(pa) { | ||||
bits = vm_page_dump[i]; | error = blk_write(di, 0, pa, PAGE_SIZE); | ||||
while (bits) { | if (error) | ||||
bit = ffsl(bits) - 1; | goto fail; | ||||
pa = (((uint64_t)i * sizeof(*vm_page_dump) * NBBY) + | |||||
bit) * PAGE_SIZE; | |||||
error = blk_write(di, 0, pa, PAGE_SIZE); | |||||
if (error) | |||||
goto fail; | |||||
bits &= ~(1ul << bit); | |||||
} | |||||
} | } | ||||
error = blk_flush(di); | error = blk_flush(di); | ||||
Context not available. | |||||
printf("** DUMP FAILED (ERROR %d) **\n", error); | printf("** DUMP FAILED (ERROR %d) **\n", error); | ||||
return (error); | return (error); | ||||
} | } | ||||
void | |||||
dump_add_page(vm_paddr_t pa) | |||||
{ | |||||
int idx, bit; | |||||
pa >>= PAGE_SHIFT; | |||||
idx = pa >> 6; /* 2^6 = 64 */ | |||||
bit = pa & 63; | |||||
atomic_set_long(&vm_page_dump[idx], 1ul << bit); | |||||
} | |||||
void | |||||
dump_drop_page(vm_paddr_t pa) | |||||
{ | |||||
int idx, bit; | |||||
pa >>= PAGE_SHIFT; | |||||
idx = pa >> 6; /* 2^6 = 64 */ | |||||
bit = pa & 63; | |||||
atomic_clear_long(&vm_page_dump[idx], 1ul << bit); | |||||
} | |||||
Context not available. |