diff options
Diffstat (limited to 'arch/sh/kernel/machine_kexec.c')
| -rw-r--r-- | arch/sh/kernel/machine_kexec.c | 62 | 
1 files changed, 61 insertions, 1 deletions
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 7672141c841..5a559e666eb 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -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> @@ -147,4 +147,64 @@ void arch_crash_save_vmcoreinfo(void)  	VMCOREINFO_SYMBOL(node_data);  	VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);  #endif +#ifdef CONFIG_X2TLB +	VMCOREINFO_CONFIG(X2TLB); +#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) { +		unsigned long max = lmb_end_of_DRAM() - memory_limit; +		crashk_res.start = __lmb_alloc_base(crash_size, PAGE_SIZE, max); +		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; +		} +	} + +	crashk_res.end = crashk_res.start + crash_size - 1; + +	/* +	 * Crash kernel trumps memory limit +	 */ +	if ((lmb_end_of_DRAM() - memory_limit) <= crashk_res.end) { +		memory_limit = 0; +		pr_info("Disabled memory limit for crashkernel\n"); +	} + +	pr_info("Reserving %ldMB of memory at 0x%08lx " +		"for crashkernel (System RAM: %ldMB)\n", +		(unsigned long)(crash_size >> 20), +		(unsigned long)(crashk_res.start), +		(unsigned long)(lmb_phys_mem_size() >> 20)); + +	return; + +disable: +	crashk_res.start = crashk_res.end = 0;  }  |