@@ -492,6 +492,25 @@ static void __init request_crashkernel(struct resource *res)
(unsigned long)(resource_size(&crashk_res) >> 20),
(unsigned long)(crashk_res.start >> 20));
}
+
+/*
+ * Traditionally, MIPS's contiguous low memory is 256M, so crashkernel=X@Y is
+ * unable to be large enough in some cases. Thus, if the total memory of a node
+ * is more than 1GB, we reserve the top 128MB for the capture kernel.
+ */
+static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
+{
+ if (crashk_res.start == crashk_res.end)
+ return;
+
+ if ((e0 - s0) <= (SZ_1G >> PAGE_SHIFT))
+ return;
+
+ s0 = e0 - (SZ_128M >> PAGE_SHIFT);
+
+ memblock_reserve(PFN_PHYS(s0), (e0 - s0) << PAGE_SHIFT);
+}
+
#else /* !defined(CONFIG_KEXEC) */
static void __init mips_parse_crashkernel(void)
{
@@ -500,6 +519,10 @@ static void __init mips_parse_crashkernel(void)
static void __init request_crashkernel(struct resource *res)
{
}
+
+static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
+{
+}
#endif /* !defined(CONFIG_KEXEC) */
static void __init check_kernel_sections_mem(void)
@@ -627,6 +650,9 @@ static void __init bootcmdline_init(void)
*/
static void __init arch_mem_init(char **cmdline_p)
{
+ unsigned int node;
+ unsigned long start_pfn, end_pfn;
+
/* call board setup routine */
plat_mem_setup();
memblock_set_bottom_up(true);
@@ -666,6 +692,12 @@ static void __init arch_mem_init(char **cmdline_p)
if (crashk_res.start != crashk_res.end)
memblock_reserve(crashk_res.start, resource_size(&crashk_res));
#endif
+
+ for_each_online_node(node) {
+ get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
+ reserve_crashm_region(node, start_pfn, end_pfn);
+ }
+
device_tree_init();
/*