|
@@ -39,6 +39,7 @@
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/kexec.h>
|
|
#include <linux/kexec.h>
|
|
|
|
+#include <linux/crash_dump.h>
|
|
|
|
|
|
#include <asm/boot.h>
|
|
#include <asm/boot.h>
|
|
#include <asm/fixmap.h>
|
|
#include <asm/fixmap.h>
|
|
@@ -165,6 +166,56 @@ static void __init kexec_reserve_crashkres_pages(void)
|
|
}
|
|
}
|
|
#endif /* CONFIG_KEXEC_CORE */
|
|
#endif /* CONFIG_KEXEC_CORE */
|
|
|
|
|
|
|
|
+#ifdef CONFIG_CRASH_DUMP
|
|
|
|
+static int __init early_init_dt_scan_elfcorehdr(unsigned long node,
|
|
|
|
+ const char *uname, int depth, void *data)
|
|
|
|
+{
|
|
|
|
+ const __be32 *reg;
|
|
|
|
+ int len;
|
|
|
|
+
|
|
|
|
+ if (depth != 1 || strcmp(uname, "chosen") != 0)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ reg = of_get_flat_dt_prop(node, "linux,elfcorehdr", &len);
|
|
|
|
+ if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ elfcorehdr_addr = dt_mem_next_cell(dt_root_addr_cells, ®);
|
|
|
|
+ elfcorehdr_size = dt_mem_next_cell(dt_root_size_cells, ®);
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * reserve_elfcorehdr() - reserves memory for elf core header
|
|
|
|
+ *
|
|
|
|
+ * This function reserves the memory occupied by an elf core header
|
|
|
|
+ * described in the device tree. This region contains all the
|
|
|
|
+ * information about primary kernel's core image and is used by a dump
|
|
|
|
+ * capture kernel to access the system memory on primary kernel.
|
|
|
|
+ */
|
|
|
|
+static void __init reserve_elfcorehdr(void)
|
|
|
|
+{
|
|
|
|
+ of_scan_flat_dt(early_init_dt_scan_elfcorehdr, NULL);
|
|
|
|
+
|
|
|
|
+ if (!elfcorehdr_size)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
|
|
|
|
+ pr_warn("elfcorehdr is overlapped\n");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
|
|
|
|
+
|
|
|
|
+ pr_info("Reserving %lldKB of memory at 0x%llx for elfcorehdr\n",
|
|
|
|
+ elfcorehdr_size >> 10, elfcorehdr_addr);
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static void __init reserve_elfcorehdr(void)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+#endif /* CONFIG_CRASH_DUMP */
|
|
/*
|
|
/*
|
|
* Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
|
|
* Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
|
|
* currently assumes that for memory starting above 4G, 32-bit devices will
|
|
* currently assumes that for memory starting above 4G, 32-bit devices will
|
|
@@ -423,6 +474,8 @@ void __init arm64_memblock_init(void)
|
|
|
|
|
|
reserve_crashkernel();
|
|
reserve_crashkernel();
|
|
|
|
|
|
|
|
+ reserve_elfcorehdr();
|
|
|
|
+
|
|
dma_contiguous_reserve(arm64_dma_phys_limit);
|
|
dma_contiguous_reserve(arm64_dma_phys_limit);
|
|
|
|
|
|
memblock_allow_resize();
|
|
memblock_allow_resize();
|