Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libkvm/kvm_minidump_aarch64.c
Show First 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | _aarch64_minidump_freevtop(kvm_t *kd) | ||||
free(vm); | free(vm); | ||||
kd->vmst = NULL; | kd->vmst = NULL; | ||||
} | } | ||||
static int | static int | ||||
_aarch64_minidump_initvtop(kvm_t *kd) | _aarch64_minidump_initvtop(kvm_t *kd) | ||||
{ | { | ||||
struct vmstate *vmst; | struct vmstate *vmst; | ||||
off_t off, sparse_off; | off_t off, dump_avail_off, sparse_off; | ||||
vmst = _kvm_malloc(kd, sizeof(*vmst)); | vmst = _kvm_malloc(kd, sizeof(*vmst)); | ||||
if (vmst == NULL) { | if (vmst == NULL) { | ||||
_kvm_err(kd, kd->program, "cannot allocate vm"); | _kvm_err(kd, kd->program, "cannot allocate vm"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
kd->vmst = vmst; | kd->vmst = vmst; | ||||
if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) != | if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) != | ||||
sizeof(vmst->hdr)) { | sizeof(vmst->hdr)) { | ||||
_kvm_err(kd, kd->program, "cannot read dump header"); | _kvm_err(kd, kd->program, "cannot read dump header"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (strncmp(MINIDUMP_MAGIC, vmst->hdr.magic, | if (strncmp(MINIDUMP_MAGIC, vmst->hdr.magic, | ||||
sizeof(vmst->hdr.magic)) != 0) { | sizeof(vmst->hdr.magic)) != 0) { | ||||
_kvm_err(kd, kd->program, "not a minidump for this platform"); | _kvm_err(kd, kd->program, "not a minidump for this platform"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
vmst->hdr.version = le32toh(vmst->hdr.version); | vmst->hdr.version = le32toh(vmst->hdr.version); | ||||
if (vmst->hdr.version != MINIDUMP_VERSION) { | if (vmst->hdr.version != MINIDUMP_VERSION && vmst->hdr.version != 1) { | ||||
_kvm_err(kd, kd->program, "wrong minidump version. " | _kvm_err(kd, kd->program, "wrong minidump version. " | ||||
"Expected %d got %d", MINIDUMP_VERSION, vmst->hdr.version); | "Expected %d got %d", MINIDUMP_VERSION, vmst->hdr.version); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
vmst->hdr.msgbufsize = le32toh(vmst->hdr.msgbufsize); | vmst->hdr.msgbufsize = le32toh(vmst->hdr.msgbufsize); | ||||
vmst->hdr.bitmapsize = le32toh(vmst->hdr.bitmapsize); | vmst->hdr.bitmapsize = le32toh(vmst->hdr.bitmapsize); | ||||
vmst->hdr.pmapsize = le32toh(vmst->hdr.pmapsize); | vmst->hdr.pmapsize = le32toh(vmst->hdr.pmapsize); | ||||
vmst->hdr.kernbase = le64toh(vmst->hdr.kernbase); | vmst->hdr.kernbase = le64toh(vmst->hdr.kernbase); | ||||
vmst->hdr.dmapphys = le64toh(vmst->hdr.dmapphys); | vmst->hdr.dmapphys = le64toh(vmst->hdr.dmapphys); | ||||
vmst->hdr.dmapbase = le64toh(vmst->hdr.dmapbase); | vmst->hdr.dmapbase = le64toh(vmst->hdr.dmapbase); | ||||
vmst->hdr.dmapend = le64toh(vmst->hdr.dmapend); | vmst->hdr.dmapend = le64toh(vmst->hdr.dmapend); | ||||
vmst->hdr.dumpavailsize = vmst->hdr.version == MINIDUMP_VERSION ? | |||||
le32toh(vmst->hdr.dumpavailsize) : 0; | |||||
/* Skip header and msgbuf */ | /* Skip header and msgbuf */ | ||||
off = AARCH64_PAGE_SIZE + aarch64_round_page(vmst->hdr.msgbufsize); | dump_avail_off = AARCH64_PAGE_SIZE + aarch64_round_page(vmst->hdr.msgbufsize); | ||||
/* Skip dump_avail */ | |||||
off = dump_avail_off + aarch64_round_page(vmst->hdr.dumpavailsize); | |||||
/* build physical address lookup table for sparse pages */ | /* build physical address lookup table for sparse pages */ | ||||
sparse_off = off + aarch64_round_page(vmst->hdr.bitmapsize) + | sparse_off = off + aarch64_round_page(vmst->hdr.bitmapsize) + | ||||
aarch64_round_page(vmst->hdr.pmapsize); | aarch64_round_page(vmst->hdr.pmapsize); | ||||
if (_kvm_pt_init(kd, vmst->hdr.bitmapsize, off, sparse_off, | if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off, | ||||
AARCH64_PAGE_SIZE, sizeof(uint64_t)) == -1) { | vmst->hdr.bitmapsize, off, sparse_off, AARCH64_PAGE_SIZE, | ||||
sizeof(uint64_t)) == -1) { | |||||
return (-1); | return (-1); | ||||
} | } | ||||
off += aarch64_round_page(vmst->hdr.bitmapsize); | off += aarch64_round_page(vmst->hdr.bitmapsize); | ||||
if (_kvm_pmap_init(kd, vmst->hdr.pmapsize, off) == -1) { | if (_kvm_pmap_init(kd, vmst->hdr.pmapsize, off) == -1) { | ||||
return (-1); | return (-1); | ||||
} | } | ||||
off += aarch64_round_page(vmst->hdr.pmapsize); | off += aarch64_round_page(vmst->hdr.pmapsize); | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | for (pteindex = 0; pteindex < nptes; pteindex++) { | ||||
dva = vm->hdr.dmapbase + pa; | dva = vm->hdr.dmapbase + pa; | ||||
if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva, | if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva, | ||||
_aarch64_entry_to_prot(pte), AARCH64_PAGE_SIZE, 0)) { | _aarch64_entry_to_prot(pte), AARCH64_PAGE_SIZE, 0)) { | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
while (_kvm_bitmap_next(&bm, &bmindex)) { | while (_kvm_bitmap_next(&bm, &bmindex)) { | ||||
pa = bmindex * AARCH64_PAGE_SIZE; | pa = _kvm_bit_id_pa(kd, bmindex, AARCH64_PAGE_SIZE); | ||||
if (pa == _KVM_PA_INVALID) | |||||
break; | |||||
dva = vm->hdr.dmapbase + pa; | dva = vm->hdr.dmapbase + pa; | ||||
if (vm->hdr.dmapend < (dva + AARCH64_PAGE_SIZE)) | if (vm->hdr.dmapend < (dva + AARCH64_PAGE_SIZE)) | ||||
break; | break; | ||||
va = 0; | va = 0; | ||||
prot = VM_PROT_READ | VM_PROT_WRITE; | prot = VM_PROT_READ | VM_PROT_WRITE; | ||||
if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva, | if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva, | ||||
prot, AARCH64_PAGE_SIZE, 0)) { | prot, AARCH64_PAGE_SIZE, 0)) { | ||||
goto out; | goto out; | ||||
Show All 19 Lines |