diff options
author | Milton Miller <miltonm@bga.com> | 2009-01-02 05:46:15 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-01-12 22:47:59 -0500 |
commit | 66c721e184e594d5761c5db804ade08fab81930d (patch) | |
tree | 5f1832ed0eb95c55b4a3c650b541c0aecd6d8aec | |
parent | e16459c6b7e9c1390020a3e2a033b5383d1c4f3b (diff) |
powerpc/kexec: Check crash_base for relocatable kernel
Enforce that the crash kernel region never overlaps the current kernel,
as it will be written directly on kexec load.
Also, default to the previous KDUMP_KERNELBASE if the start is 0.
Other architectures (x86, ia64) state that specifying the start address
0 (or omitting it) will result in the kernel allocating it. Before the
relocatable patch in 2.6.28, powerpc would adjust any other start value
to the hardcoded KDUMP_KERNELBASE of 32M.
Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/kernel/machine_kexec.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index b3abebb7ee64..d59e2b1bdcba 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
@@ -93,10 +93,35 @@ void __init reserve_crashkernel(void) | |||
93 | KDUMP_KERNELBASE); | 93 | KDUMP_KERNELBASE); |
94 | 94 | ||
95 | crashk_res.start = KDUMP_KERNELBASE; | 95 | crashk_res.start = KDUMP_KERNELBASE; |
96 | #else | ||
97 | if (!crashk_res.start) { | ||
98 | /* | ||
99 | * unspecified address, choose a region of specified size | ||
100 | * can overlap with initrd (ignoring corruption when retained) | ||
101 | * ppc64 requires kernel and some stacks to be in first segemnt | ||
102 | */ | ||
103 | crashk_res.start = KDUMP_KERNELBASE; | ||
104 | } | ||
105 | |||
106 | crash_base = PAGE_ALIGN(crashk_res.start); | ||
107 | if (crash_base != crashk_res.start) { | ||
108 | printk("Crash kernel base must be aligned to 0x%lx\n", | ||
109 | PAGE_SIZE); | ||
110 | crashk_res.start = crash_base; | ||
111 | } | ||
112 | |||
96 | #endif | 113 | #endif |
97 | crash_size = PAGE_ALIGN(crash_size); | 114 | crash_size = PAGE_ALIGN(crash_size); |
98 | crashk_res.end = crashk_res.start + crash_size - 1; | 115 | crashk_res.end = crashk_res.start + crash_size - 1; |
99 | 116 | ||
117 | /* The crash region must not overlap the current kernel */ | ||
118 | if (overlaps_crashkernel(__pa(_stext), _end - _stext)) { | ||
119 | printk(KERN_WARNING | ||
120 | "Crash kernel can not overlap current kernel\n"); | ||
121 | crashk_res.start = crashk_res.end = 0; | ||
122 | return; | ||
123 | } | ||
124 | |||
100 | /* Crash kernel trumps memory limit */ | 125 | /* Crash kernel trumps memory limit */ |
101 | if (memory_limit && memory_limit <= crashk_res.end) { | 126 | if (memory_limit && memory_limit <= crashk_res.end) { |
102 | memory_limit = crashk_res.end + 1; | 127 | memory_limit = crashk_res.end + 1; |