diff options
Diffstat (limited to 'arch/powerpc/kernel/machine_kexec.c')
| -rw-r--r-- | arch/powerpc/kernel/machine_kexec.c | 56 | 
1 files changed, 56 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index a81ca1b841e..e60a0c544d6 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -13,6 +13,7 @@  #include <linux/reboot.h>  #include <linux/threads.h>  #include <asm/machdep.h> +#include <asm/lmb.h>  void machine_crash_shutdown(struct pt_regs *regs)  { @@ -59,3 +60,58 @@ NORET_TYPE void machine_kexec(struct kimage *image)  	}  	for(;;);  } + +static int __init early_parse_crashk(char *p) +{ +	unsigned long size; + +	if (!p) +		return 1; + +	size = memparse(p, &p); + +	if (*p == '@') +		crashk_res.start = memparse(p + 1, &p); +	else +		crashk_res.start = KDUMP_KERNELBASE; + +	crashk_res.end = crashk_res.start + size - 1; + +	return 0; +} +early_param("crashkernel", early_parse_crashk); + +void __init reserve_crashkernel(void) +{ +	unsigned long size; + +	if (crashk_res.start == 0) +		return; + +	/* We might have got these values via the command line or the +	 * device tree, either way sanitise them now. */ + +	size = crashk_res.end - crashk_res.start + 1; + +	if (crashk_res.start != KDUMP_KERNELBASE) +		printk("Crash kernel location must be 0x%x\n", +				KDUMP_KERNELBASE); + +	crashk_res.start = KDUMP_KERNELBASE; +	size = PAGE_ALIGN(size); +	crashk_res.end = crashk_res.start + size - 1; + +	/* Crash kernel trumps memory limit */ +	if (memory_limit && memory_limit <= crashk_res.end) { +		memory_limit = crashk_res.end + 1; +		printk("Adjusted memory limit for crashkernel, now 0x%lx\n", +				memory_limit); +	} + +	lmb_reserve(crashk_res.start, size); +} + +int overlaps_crashkernel(unsigned long start, unsigned long size) +{ +	return (start + size) > crashk_res.start && start <= crashk_res.end; +}  |