diff options
-rw-r--r-- | arch/x86/kernel/e820_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/machine_kexec_32.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/setup_32.c | 49 |
3 files changed, 46 insertions, 28 deletions
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index 3c86b979a40a..d58039e8de74 100644 --- a/arch/x86/kernel/e820_32.c +++ b/arch/x86/kernel/e820_32.c | |||
@@ -288,7 +288,8 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
288 | request_resource(res, code_resource); | 288 | request_resource(res, code_resource); |
289 | request_resource(res, data_resource); | 289 | request_resource(res, data_resource); |
290 | #ifdef CONFIG_KEXEC | 290 | #ifdef CONFIG_KEXEC |
291 | request_resource(res, &crashk_res); | 291 | if (crashk_res.start != crashk_res.end) |
292 | request_resource(res, &crashk_res); | ||
292 | #endif | 293 | #endif |
293 | } | 294 | } |
294 | } | 295 | } |
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 8459ca64bc2f..11b935f4f886 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c | |||
@@ -149,28 +149,6 @@ NORET_TYPE void machine_kexec(struct kimage *image) | |||
149 | image->start, cpu_has_pae); | 149 | image->start, cpu_has_pae); |
150 | } | 150 | } |
151 | 151 | ||
152 | /* crashkernel=size@addr specifies the location to reserve for | ||
153 | * a crash kernel. By reserving this memory we guarantee | ||
154 | * that linux never sets it up as a DMA target. | ||
155 | * Useful for holding code to do something appropriate | ||
156 | * after a kernel panic. | ||
157 | */ | ||
158 | static int __init parse_crashkernel(char *arg) | ||
159 | { | ||
160 | unsigned long size, base; | ||
161 | size = memparse(arg, &arg); | ||
162 | if (*arg == '@') { | ||
163 | base = memparse(arg+1, &arg); | ||
164 | /* FIXME: Do I want a sanity check | ||
165 | * to validate the memory range? | ||
166 | */ | ||
167 | crashk_res.start = base; | ||
168 | crashk_res.end = base + size - 1; | ||
169 | } | ||
170 | return 0; | ||
171 | } | ||
172 | early_param("crashkernel", parse_crashkernel); | ||
173 | |||
174 | void arch_crash_save_vmcoreinfo(void) | 152 | void arch_crash_save_vmcoreinfo(void) |
175 | { | 153 | { |
176 | #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE | 154 | #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE |
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index b87a6fd5ba48..978dc0196a0f 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -378,6 +378,49 @@ extern unsigned long __init setup_memory(void); | |||
378 | extern void zone_sizes_init(void); | 378 | extern void zone_sizes_init(void); |
379 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ | 379 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
380 | 380 | ||
381 | static inline unsigned long long get_total_mem(void) | ||
382 | { | ||
383 | unsigned long long total; | ||
384 | |||
385 | total = max_low_pfn - min_low_pfn; | ||
386 | #ifdef CONFIG_HIGHMEM | ||
387 | total += highend_pfn - highstart_pfn; | ||
388 | #endif | ||
389 | |||
390 | return total << PAGE_SHIFT; | ||
391 | } | ||
392 | |||
393 | #ifdef CONFIG_KEXEC | ||
394 | static void __init reserve_crashkernel(void) | ||
395 | { | ||
396 | unsigned long long total_mem; | ||
397 | unsigned long long crash_size, crash_base; | ||
398 | int ret; | ||
399 | |||
400 | total_mem = get_total_mem(); | ||
401 | |||
402 | ret = parse_crashkernel(boot_command_line, total_mem, | ||
403 | &crash_size, &crash_base); | ||
404 | if (ret == 0 && crash_size > 0) { | ||
405 | if (crash_base > 0) { | ||
406 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | ||
407 | "for crashkernel (System RAM: %ldMB)\n", | ||
408 | (unsigned long)(crash_size >> 20), | ||
409 | (unsigned long)(crash_base >> 20), | ||
410 | (unsigned long)(total_mem >> 20)); | ||
411 | crashk_res.start = crash_base; | ||
412 | crashk_res.end = crash_base + crash_size - 1; | ||
413 | reserve_bootmem(crash_base, crash_size); | ||
414 | } else | ||
415 | printk(KERN_INFO "crashkernel reservation failed - " | ||
416 | "you have to specify a base address\n"); | ||
417 | } | ||
418 | } | ||
419 | #else | ||
420 | static inline void __init reserve_crashkernel(void) | ||
421 | {} | ||
422 | #endif | ||
423 | |||
381 | void __init setup_bootmem_allocator(void) | 424 | void __init setup_bootmem_allocator(void) |
382 | { | 425 | { |
383 | unsigned long bootmap_size; | 426 | unsigned long bootmap_size; |
@@ -453,11 +496,7 @@ void __init setup_bootmem_allocator(void) | |||
453 | } | 496 | } |
454 | } | 497 | } |
455 | #endif | 498 | #endif |
456 | #ifdef CONFIG_KEXEC | 499 | reserve_crashkernel(); |
457 | if (crashk_res.start != crashk_res.end) | ||
458 | reserve_bootmem(crashk_res.start, | ||
459 | crashk_res.end - crashk_res.start + 1); | ||
460 | #endif | ||
461 | } | 500 | } |
462 | 501 | ||
463 | /* | 502 | /* |