|
@@ -8,7 +8,6 @@
|
|
|
* This source code is licensed under the GNU General Public License,
|
|
|
* Version 2. See the file COPYING for more details.
|
|
|
*/
|
|
|
-
|
|
|
#include <linux/mm.h>
|
|
|
#include <linux/kexec.h>
|
|
|
#include <linux/delay.h>
|
|
@@ -16,6 +15,7 @@
|
|
|
#include <linux/numa.h>
|
|
|
#include <linux/ftrace.h>
|
|
|
#include <linux/suspend.h>
|
|
|
+#include <linux/lmb.h>
|
|
|
#include <asm/pgtable.h>
|
|
|
#include <asm/pgalloc.h>
|
|
|
#include <asm/mmu_context.h>
|
|
@@ -148,3 +148,52 @@ void arch_crash_save_vmcoreinfo(void)
|
|
|
VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
|
|
|
#endif
|
|
|
}
|
|
|
+
|
|
|
+void __init reserve_crashkernel(void)
|
|
|
+{
|
|
|
+ unsigned long long crash_size, crash_base;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ /* this is necessary because of lmb_phys_mem_size() */
|
|
|
+ lmb_analyze();
|
|
|
+
|
|
|
+ ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
|
|
|
+ &crash_size, &crash_base);
|
|
|
+ if (ret == 0 && crash_size > 0) {
|
|
|
+ crashk_res.start = crash_base;
|
|
|
+ crashk_res.end = crash_base + crash_size - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (crashk_res.end == crashk_res.start)
|
|
|
+ goto disable;
|
|
|
+
|
|
|
+ crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1);
|
|
|
+ if (!crashk_res.start) {
|
|
|
+ crashk_res.start = lmb_alloc(crash_size, PAGE_SIZE);
|
|
|
+ if (!crashk_res.start) {
|
|
|
+ pr_err("crashkernel allocation failed\n");
|
|
|
+ goto disable;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ret = lmb_reserve(crashk_res.start, crash_size);
|
|
|
+ if (unlikely(ret < 0)) {
|
|
|
+ pr_err("crashkernel reservation failed - "
|
|
|
+ "memory is in use\n");
|
|
|
+ goto disable;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_info("Reserving %ldMB of memory at %ldMB "
|
|
|
+ "for crashkernel (System RAM: %ldMB)\n",
|
|
|
+ (unsigned long)(crash_size >> 20),
|
|
|
+ (unsigned long)(crashk_res.start >> 20),
|
|
|
+ (unsigned long)(lmb_phys_mem_size() >> 20));
|
|
|
+
|
|
|
+ crashk_res.end = crashk_res.start + crash_size - 1;
|
|
|
+ insert_resource(&iomem_resource, &crashk_res);
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+disable:
|
|
|
+ crashk_res.start = crashk_res.end = 0;
|
|
|
+}
|