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 a81ca1b841ec..e60a0c544d63 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/reboot.h> | 13 | #include <linux/reboot.h> |
14 | #include <linux/threads.h> | 14 | #include <linux/threads.h> |
15 | #include <asm/machdep.h> | 15 | #include <asm/machdep.h> |
16 | #include <asm/lmb.h> | ||
16 | 17 | ||
17 | void machine_crash_shutdown(struct pt_regs *regs) | 18 | void machine_crash_shutdown(struct pt_regs *regs) |
18 | { | 19 | { |
@@ -59,3 +60,58 @@ NORET_TYPE void machine_kexec(struct kimage *image) | |||
59 | } | 60 | } |
60 | for(;;); | 61 | for(;;); |
61 | } | 62 | } |
63 | |||
64 | static int __init early_parse_crashk(char *p) | ||
65 | { | ||
66 | unsigned long size; | ||
67 | |||
68 | if (!p) | ||
69 | return 1; | ||
70 | |||
71 | size = memparse(p, &p); | ||
72 | |||
73 | if (*p == '@') | ||
74 | crashk_res.start = memparse(p + 1, &p); | ||
75 | else | ||
76 | crashk_res.start = KDUMP_KERNELBASE; | ||
77 | |||
78 | crashk_res.end = crashk_res.start + size - 1; | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | early_param("crashkernel", early_parse_crashk); | ||
83 | |||
84 | void __init reserve_crashkernel(void) | ||
85 | { | ||
86 | unsigned long size; | ||
87 | |||
88 | if (crashk_res.start == 0) | ||
89 | return; | ||
90 | |||
91 | /* We might have got these values via the command line or the | ||
92 | * device tree, either way sanitise them now. */ | ||
93 | |||
94 | size = crashk_res.end - crashk_res.start + 1; | ||
95 | |||
96 | if (crashk_res.start != KDUMP_KERNELBASE) | ||
97 | printk("Crash kernel location must be 0x%x\n", | ||
98 | KDUMP_KERNELBASE); | ||
99 | |||
100 | crashk_res.start = KDUMP_KERNELBASE; | ||
101 | size = PAGE_ALIGN(size); | ||
102 | crashk_res.end = crashk_res.start + size - 1; | ||
103 | |||
104 | /* Crash kernel trumps memory limit */ | ||
105 | if (memory_limit && memory_limit <= crashk_res.end) { | ||
106 | memory_limit = crashk_res.end + 1; | ||
107 | printk("Adjusted memory limit for crashkernel, now 0x%lx\n", | ||
108 | memory_limit); | ||
109 | } | ||
110 | |||
111 | lmb_reserve(crashk_res.start, size); | ||
112 | } | ||
113 | |||
114 | int overlaps_crashkernel(unsigned long start, unsigned long size) | ||
115 | { | ||
116 | return (start + size) > crashk_res.start && start <= crashk_res.end; | ||
117 | } | ||