Author: skra
Date: Fri Jan 15 18:53:06 2016
New Revision: 294098
URL: https://svnweb.freebsd.org/changeset/base/294098

Log:
  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

Modified:
  head/lib/libkvm/kvm_arm.h
  head/lib/libkvm/kvm_minidump_arm.c
  head/sys/arm/arm/minidump_machdep.c
  head/sys/arm/include/minidump.h

Modified: head/lib/libkvm/kvm_arm.h
==============================================================================
--- head/lib/libkvm/kvm_arm.h   Fri Jan 15 18:27:34 2016        (r294097)
+++ head/lib/libkvm/kvm_arm.h   Fri Jan 15 18:53:06 2016        (r294098)
@@ -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_
 _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

Modified: head/lib/libkvm/kvm_minidump_arm.c
==============================================================================
--- head/lib/libkvm/kvm_minidump_arm.c  Fri Jan 15 18:27:34 2016        
(r294097)
+++ head/lib/libkvm/kvm_minidump_arm.c  Fri Jan 15 18:53:06 2016        
(r294098)
@@ -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
        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
 
                *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);

Modified: head/sys/arm/arm/minidump_machdep.c
==============================================================================
--- head/sys/arm/arm/minidump_machdep.c Fri Jan 15 18:27:34 2016        
(r294097)
+++ head/sys/arm/arm/minidump_machdep.c Fri Jan 15 18:53:06 2016        
(r294098)
@@ -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);
 

Modified: head/sys/arm/include/minidump.h
==============================================================================
--- head/sys/arm/include/minidump.h     Fri Jan 15 18:27:34 2016        
(r294097)
+++ head/sys/arm/include/minidump.h     Fri Jan 15 18:53:06 2016        
(r294098)
@@ -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_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to