|
@@ -378,6 +378,49 @@ extern unsigned long __init setup_memory(void);
|
|
|
extern void zone_sizes_init(void);
|
|
|
#endif /* !CONFIG_NEED_MULTIPLE_NODES */
|
|
|
|
|
|
+static inline unsigned long long get_total_mem(void)
|
|
|
+{
|
|
|
+ unsigned long long total;
|
|
|
+
|
|
|
+ total = max_low_pfn - min_low_pfn;
|
|
|
+#ifdef CONFIG_HIGHMEM
|
|
|
+ total += highend_pfn - highstart_pfn;
|
|
|
+#endif
|
|
|
+
|
|
|
+ return total << PAGE_SHIFT;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef CONFIG_KEXEC
|
|
|
+static void __init reserve_crashkernel(void)
|
|
|
+{
|
|
|
+ unsigned long long total_mem;
|
|
|
+ unsigned long long crash_size, crash_base;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ total_mem = get_total_mem();
|
|
|
+
|
|
|
+ ret = parse_crashkernel(boot_command_line, total_mem,
|
|
|
+ &crash_size, &crash_base);
|
|
|
+ if (ret == 0 && crash_size > 0) {
|
|
|
+ if (crash_base > 0) {
|
|
|
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
|
|
|
+ "for crashkernel (System RAM: %ldMB)\n",
|
|
|
+ (unsigned long)(crash_size >> 20),
|
|
|
+ (unsigned long)(crash_base >> 20),
|
|
|
+ (unsigned long)(total_mem >> 20));
|
|
|
+ crashk_res.start = crash_base;
|
|
|
+ crashk_res.end = crash_base + crash_size - 1;
|
|
|
+ reserve_bootmem(crash_base, crash_size);
|
|
|
+ } else
|
|
|
+ printk(KERN_INFO "crashkernel reservation failed - "
|
|
|
+ "you have to specify a base address\n");
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void __init reserve_crashkernel(void)
|
|
|
+{}
|
|
|
+#endif
|
|
|
+
|
|
|
void __init setup_bootmem_allocator(void)
|
|
|
{
|
|
|
unsigned long bootmap_size;
|
|
@@ -453,11 +496,7 @@ void __init setup_bootmem_allocator(void)
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
-#ifdef CONFIG_KEXEC
|
|
|
- if (crashk_res.start != crashk_res.end)
|
|
|
- reserve_bootmem(crashk_res.start,
|
|
|
- crashk_res.end - crashk_res.start + 1);
|
|
|
-#endif
|
|
|
+ reserve_crashkernel();
|
|
|
}
|
|
|
|
|
|
/*
|