Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/amd64/minidump_machdep.c
Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
CTASSERT(sizeof(struct kerneldumpheader) == 512); | CTASSERT(sizeof(struct kerneldumpheader) == 512); | ||||
/* | /* | ||||
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This | * Don't touch the first SIZEOF_METADATA bytes on the dump device. This | ||||
* is to protect us from metadata and to protect metadata from us. | * is to protect us from metadata and to protect metadata from us. | ||||
*/ | */ | ||||
#define SIZEOF_METADATA (64*1024) | #define SIZEOF_METADATA (64*1024) | ||||
#define MD_ALIGN(x) (((off_t)(x) + PAGE_MASK) & ~PAGE_MASK) | |||||
#define DEV_ALIGN(x) (((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1)) | |||||
uint64_t *vm_page_dump; | uint64_t *vm_page_dump; | ||||
int vm_page_dump_size; | int vm_page_dump_size; | ||||
static struct kerneldumpheader kdh; | static struct kerneldumpheader kdh; | ||||
static off_t dumplo; | static off_t dumplo; | ||||
/* Handle chunked writes. */ | /* Handle chunked writes. */ | ||||
static size_t fragsz; | static size_t fragsz; | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
minidumpsys(struct dumperinfo *di) | minidumpsys(struct dumperinfo *di) | ||||
{ | { | ||||
uint32_t pmapsize; | uint32_t pmapsize; | ||||
vm_offset_t va; | vm_offset_t va; | ||||
int error; | int error; | ||||
uint64_t bits; | uint64_t bits; | ||||
uint64_t *pml4, *pdp, *pd, *pt, pa; | uint64_t *pml4, *pdp, *pd, *pt, pa; | ||||
size_t size; | |||||
int i, ii, j, k, n, bit; | int i, ii, j, k, n, bit; | ||||
int retry_count; | int retry_count; | ||||
struct minidumphdr mdhdr; | struct minidumphdr mdhdr; | ||||
retry_count = 0; | retry_count = 0; | ||||
retry: | retry: | ||||
retry_count++; | retry_count++; | ||||
counter = 0; | counter = 0; | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | while (bits) { | ||||
dump_drop_page(pa); | dump_drop_page(pa); | ||||
} | } | ||||
bits &= ~(1ul << bit); | bits &= ~(1ul << bit); | ||||
} | } | ||||
} | } | ||||
dumpsize += PAGE_SIZE; | dumpsize += PAGE_SIZE; | ||||
/* Determine dump offset on device. */ | /* Determine dump offset on device. */ | ||||
if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) { | if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2) { | ||||
error = E2BIG; | error = E2BIG; | ||||
goto fail; | goto fail; | ||||
} | } | ||||
dumplo = di->mediaoffset + di->mediasize - dumpsize; | dumplo = di->mediaoffset + di->mediasize - dumpsize; | ||||
dumplo -= sizeof(kdh) * 2; | dumplo -= di->blocksize * 2; | ||||
progress = dumpsize; | progress = dumpsize; | ||||
/* Initialize mdhdr */ | /* Initialize mdhdr */ | ||||
bzero(&mdhdr, sizeof(mdhdr)); | bzero(&mdhdr, sizeof(mdhdr)); | ||||
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 = vm_page_dump_size; | ||||
mdhdr.pmapsize = pmapsize; | mdhdr.pmapsize = pmapsize; | ||||
mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS; | mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS; | ||||
mdhdr.dmapbase = DMAP_MIN_ADDRESS; | mdhdr.dmapbase = DMAP_MIN_ADDRESS; | ||||
mdhdr.dmapend = DMAP_MAX_ADDRESS; | mdhdr.dmapend = DMAP_MAX_ADDRESS; | ||||
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_AMD64_VERSION, dumpsize, di->blocksize); | mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_AMD64_VERSION, dumpsize, di->blocksize); | ||||
printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20, | printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20, | ||||
ptoa((uintmax_t)physmem) / 1048576); | ptoa((uintmax_t)physmem) / 1048576); | ||||
/* Dump leader */ | /* Dump leader */ | ||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); | error = dump_write_pad(di, &kdh, 0, dumplo, sizeof(kdh), &size); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
dumplo += sizeof(kdh); | dumplo += size; | ||||
/* Dump my header */ | /* Dump my header */ | ||||
bzero(&fakepd, sizeof(fakepd)); | bzero(&fakepd, sizeof(fakepd)); | ||||
bcopy(&mdhdr, &fakepd, sizeof(mdhdr)); | bcopy(&mdhdr, &fakepd, sizeof(mdhdr)); | ||||
error = blk_write(di, (char *)&fakepd, 0, PAGE_SIZE); | error = blk_write(di, (char *)&fakepd, 0, PAGE_SIZE); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) { | ||||
} | } | ||||
} | } | ||||
error = blk_flush(di); | error = blk_flush(di); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
/* Dump trailer */ | /* Dump trailer */ | ||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); | error = dump_write_pad(di, &kdh, 0, dumplo, sizeof(kdh), &size); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
dumplo += sizeof(kdh); | dumplo += size; | ||||
/* Signal completion, signoff and exit stage left. */ | /* Signal completion, signoff and exit stage left. */ | ||||
dump_write(di, NULL, 0, 0, 0); | dump_write(di, NULL, 0, 0, 0); | ||||
printf("\nDump complete\n"); | printf("\nDump complete\n"); | ||||
return (0); | return (0); | ||||
fail: | fail: | ||||
if (error < 0) | if (error < 0) | ||||
▲ Show 20 Lines • Show All 41 Lines • Show Last 20 Lines |