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
This commit is contained in:
parent
60d3f112d9
commit
12fce57c8c
@ -67,13 +67,16 @@ typedef uint32_t arm_pt_entry_t;
|
||||
#define ARM_L1_C_ADDR_MASK 0xfffffc00 /* phys address of L2 Table */
|
||||
|
||||
#define ARM_L2_TYPE_INV 0x00 /* Invalid (fault) */
|
||||
#define ARM_L2_TYPE_L 0x01 /* Large Page - 64k - not used yet*/
|
||||
#define ARM_L2_TYPE_S 0x02 /* Small Page - 4 */
|
||||
#define ARM_L2_TYPE_L 0x01 /* Large Page - 64k */
|
||||
#define ARM_L2_TYPE_S 0x02 /* Small Page - 4k */
|
||||
#define ARM_L2_TYPE_T 0x03 /* Tiny Page - 1k - not used */
|
||||
#define ARM_L2_TYPE_MASK 0x03
|
||||
|
||||
#define ARM_L2_ADDR_BITS 0x000ff000 /* L2 PTE address bits */
|
||||
|
||||
#ifdef __arm__
|
||||
#include <machine/acle-compat.h>
|
||||
|
||||
_Static_assert(PAGE_SHIFT == ARM_PAGE_SHIFT, "PAGE_SHIFT mismatch");
|
||||
_Static_assert(PAGE_SIZE == ARM_PAGE_SIZE, "PAGE_SIZE mismatch");
|
||||
_Static_assert(PAGE_MASK == ARM_PAGE_MASK, "PAGE_MASK mismatch");
|
||||
@ -99,6 +102,9 @@ _Static_assert(L1_C_ADDR_MASK == ARM_L1_C_ADDR_MASK, "L1_C_ADDR_MASK mismatch");
|
||||
_Static_assert(L2_TYPE_INV == ARM_L2_TYPE_INV, "L2_TYPE_INV mismatch");
|
||||
_Static_assert(L2_TYPE_L == ARM_L2_TYPE_L, "L2_TYPE_L mismatch");
|
||||
_Static_assert(L2_TYPE_S == ARM_L2_TYPE_S, "L2_TYPE_S mismatch");
|
||||
#if __ARM_ARCH < 6
|
||||
_Static_assert(L2_TYPE_T == ARM_L2_TYPE_T, "L2_TYPE_T mismatch");
|
||||
#endif
|
||||
_Static_assert(L2_TYPE_MASK == ARM_L2_TYPE_MASK, "L2_TYPE_MASK mismatch");
|
||||
_Static_assert(L2_ADDR_BITS == ARM_L2_ADDR_BITS, "L2_ADDR_BITS mismatch");
|
||||
#endif
|
||||
|
@ -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);
|
||||
|
@ -312,7 +312,12 @@ minidumpsys(struct dumperinfo *di)
|
||||
mdhdr.bitmapsize = vm_page_dump_size;
|
||||
mdhdr.ptesize = ptesize;
|
||||
mdhdr.kernbase = KERNBASE;
|
||||
|
||||
mdhdr.arch = __ARM_ARCH;
|
||||
#if __ARM_ARCH >= 6
|
||||
mdhdr.mmuformat = MINIDUMP_MMU_FORMAT_V6;
|
||||
#else
|
||||
mdhdr.mmuformat = MINIDUMP_MMU_FORMAT_V4;
|
||||
#endif
|
||||
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, dumpsize,
|
||||
di->blocksize);
|
||||
|
||||
|
@ -28,11 +28,18 @@
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_MINIDUMP_H_
|
||||
#define _MACHINE_MINIDUMP_H_ 1
|
||||
#define _MACHINE_MINIDUMP_H_
|
||||
|
||||
#define MINIDUMP_MAGIC "minidump FreeBSD/arm"
|
||||
#define MINIDUMP_VERSION 1
|
||||
|
||||
/*
|
||||
* The first page of vmcore is dedicated to the following header.
|
||||
* As the rest of the page is zeroed, any header extension can be
|
||||
* done without version bumping. It should be taken into account
|
||||
* only that new entries will be zero in old vmcores.
|
||||
*/
|
||||
|
||||
struct minidumphdr {
|
||||
char magic[24];
|
||||
uint32_t version;
|
||||
@ -40,6 +47,13 @@ struct minidumphdr {
|
||||
uint32_t bitmapsize;
|
||||
uint32_t ptesize;
|
||||
uint32_t kernbase;
|
||||
uint32_t arch;
|
||||
uint32_t mmuformat;
|
||||
};
|
||||
|
||||
#define MINIDUMP_MMU_FORMAT_UNKNOWN 0
|
||||
#define MINIDUMP_MMU_FORMAT_V4 1
|
||||
#define MINIDUMP_MMU_FORMAT_V6 2
|
||||
#define MINIDUMP_MMU_FORMAT_V6_LPAE 3
|
||||
|
||||
#endif /* _MACHINE_MINIDUMP_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user