aboutsummaryrefslogtreecommitdiff
path: root/lib/libkvm/kvm_minidump_arm.c
diff options
context:
space:
mode:
authorSvatopluk Kraus <skra@FreeBSD.org>2016-01-15 18:53:06 +0000
committerSvatopluk Kraus <skra@FreeBSD.org>2016-01-15 18:53:06 +0000
commiteffb4b3c8cf285cca106f89b3b08552c5028256e (patch)
tree25c0fb18c21d2b6dfd083920de36e7f780f3e9e5 /lib/libkvm/kvm_minidump_arm.c
parent765b890b924bd1885ad1c7e93adfa2775066e358 (diff)
downloadsrc-effb4b3c8cf285cca106f89b3b08552c5028256e.tar.gz
src-effb4b3c8cf285cca106f89b3b08552c5028256e.zip
Add mmu format info into ARM vmcore.
Fix kvatop translation for 64K pages. Reviewed by: jhb Approved by: kib (mentor) Differential Revision: https://reviews.freebsd.org/D4942
Notes
Notes: svn path=/head/; revision=294098
Diffstat (limited to 'lib/libkvm/kvm_minidump_arm.c')
-rw-r--r--lib/libkvm/kvm_minidump_arm.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/libkvm/kvm_minidump_arm.c b/lib/libkvm/kvm_minidump_arm.c
index 9e9cd6726804..4d7666666626 100644
--- a/lib/libkvm/kvm_minidump_arm.c
+++ b/lib/libkvm/kvm_minidump_arm.c
@@ -112,6 +112,12 @@ _arm_minidump_initvtop(kvm_t *kd)
vmst->hdr.bitmapsize = _kvm32toh(kd, vmst->hdr.bitmapsize);
vmst->hdr.ptesize = _kvm32toh(kd, vmst->hdr.ptesize);
vmst->hdr.kernbase = _kvm32toh(kd, vmst->hdr.kernbase);
+ vmst->hdr.arch = _kvm32toh(kd, vmst->hdr.arch);
+ vmst->hdr.mmuformat = _kvm32toh(kd, vmst->hdr.mmuformat);
+ if (vmst->hdr.mmuformat == MINIDUMP_MMU_FORMAT_UNKNOWN) {
+ /* This is a safe default as 1K pages are not used. */
+ vmst->hdr.mmuformat = MINIDUMP_MMU_FORMAT_V6;
+ }
/* Skip header and msgbuf */
off = ARM_PAGE_SIZE + arm_round_page(vmst->hdr.msgbufsize);
@@ -179,19 +185,27 @@ _arm_minidump_kvatop(kvm_t *kd, kvaddr_t va, off_t *pa)
if (va >= vm->hdr.kernbase) {
pteindex = (va - vm->hdr.kernbase) >> ARM_PAGE_SHIFT;
pte = _kvm32toh(kd, ptemap[pteindex]);
- if (!pte) {
+ if ((pte & ARM_L2_TYPE_MASK) == ARM_L2_TYPE_INV) {
_kvm_err(kd, kd->program,
"_arm_minidump_kvatop: pte not valid");
goto invalid;
}
if ((pte & ARM_L2_TYPE_MASK) == ARM_L2_TYPE_L) {
- offset = va & ARM_L2_L_OFFSET;
- a = pte & ARM_L2_L_FRAME;
- } else if ((pte & ARM_L2_TYPE_MASK) == ARM_L2_TYPE_S) {
+ /* 64K page -> convert to be like 4K page */
+ offset = va & ARM_L2_S_OFFSET;
+ a = (pte & ARM_L2_L_FRAME) +
+ (va & ARM_L2_L_OFFSET & ARM_L2_S_FRAME);
+ } else {
+ if (kd->vmst->hdr.mmuformat == MINIDUMP_MMU_FORMAT_V4 &&
+ (pte & ARM_L2_TYPE_MASK) == ARM_L2_TYPE_T) {
+ _kvm_err(kd, kd->program,
+ "_arm_minidump_kvatop: pte not supported");
+ goto invalid;
+ }
+ /* 4K page */
offset = va & ARM_L2_S_OFFSET;
a = pte & ARM_L2_S_FRAME;
- } else
- goto invalid;
+ }
ofs = _kvm_hpt_find(&vm->hpt, a);
if (ofs == -1) {
@@ -203,7 +217,6 @@ _arm_minidump_kvatop(kvm_t *kd, kvaddr_t va, off_t *pa)
*pa = ofs + offset;
return (ARM_PAGE_SIZE - offset);
-
} else
_kvm_err(kd, kd->program, "_arm_minidump_kvatop: virtual "
"address 0x%jx not minidumped", (uintmax_t)va);