diff options
author | Mohan Kumar M <mohan@in.ibm.com> | 2008-10-21 13:38:10 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-22 00:01:22 -0400 |
commit | 54622f10a6aabb8bb2bdacf3dd070046f03dc246 (patch) | |
tree | 73eb5ad4eeb7174b8c0ae1904bbe80602c5e295d | |
parent | 4792adbac9eb41cea77a45ab76258ea10d411173 (diff) |
powerpc: Support for relocatable kdump kernel
This adds relocatable kernel support for kdump. With this one can
use the same regular kernel to capture the kdump. A signature (0xfeed1234)
is passed in r6 from panic code to the next kernel through kexec_sequence
and purgatory code. The signature is used to differentiate between
kdump kernel and non-kdump kernels.
The purgatory code compares the signature and sets the __kdump_flag in
head_64.S. During the boot up, kernel code checks __kdump_flag and if it
is set, the kernel will behave as relocatable kdump kernel. This kernel
will boot at the address where it was loaded by kexec-tools ie. at the
address reserved through crashkernel boot parameter.
CONFIG_CRASH_DUMP depends on CONFIG_RELOCATABLE option to build kdump
kernel as relocatable. So the same kernel can be used as production and
kdump kernel.
This patch incorporates the changes suggested by Paul Mackerras to avoid
GOT use and to avoid two copies of the code.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | Documentation/kdump/kdump.txt | 14 | ||||
-rw-r--r-- | arch/powerpc/Kconfig | 10 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kdump.h | 17 | ||||
-rw-r--r-- | arch/powerpc/kernel/crash_dump.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 39 | ||||
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 69 | ||||
-rw-r--r-- | arch/powerpc/kernel/machine_kexec.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/machine_kexec_64.c | 13 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_64.S | 9 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/ras.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 6 |
11 files changed, 121 insertions, 66 deletions
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt index 0705040531a5..3f4bc840da8b 100644 --- a/Documentation/kdump/kdump.txt +++ b/Documentation/kdump/kdump.txt | |||
@@ -109,7 +109,8 @@ There are two possible methods of using Kdump. | |||
109 | 2) Or use the system kernel binary itself as dump-capture kernel and there is | 109 | 2) Or use the system kernel binary itself as dump-capture kernel and there is |
110 | no need to build a separate dump-capture kernel. This is possible | 110 | no need to build a separate dump-capture kernel. This is possible |
111 | only with the architecutres which support a relocatable kernel. As | 111 | only with the architecutres which support a relocatable kernel. As |
112 | of today, i386, x86_64 and ia64 architectures support relocatable kernel. | 112 | of today, i386, x86_64, ppc64 and ia64 architectures support relocatable |
113 | kernel. | ||
113 | 114 | ||
114 | Building a relocatable kernel is advantageous from the point of view that | 115 | Building a relocatable kernel is advantageous from the point of view that |
115 | one does not have to build a second kernel for capturing the dump. But | 116 | one does not have to build a second kernel for capturing the dump. But |
@@ -207,8 +208,15 @@ Dump-capture kernel config options (Arch Dependent, i386 and x86_64) | |||
207 | Dump-capture kernel config options (Arch Dependent, ppc64) | 208 | Dump-capture kernel config options (Arch Dependent, ppc64) |
208 | ---------------------------------------------------------- | 209 | ---------------------------------------------------------- |
209 | 210 | ||
210 | * Make and install the kernel and its modules. DO NOT add this kernel | 211 | 1) Enable "Build a kdump crash kernel" support under "Kernel" options: |
211 | to the boot loader configuration files. | 212 | |
213 | CONFIG_CRASH_DUMP=y | ||
214 | |||
215 | 2) Enable "Build a relocatable kernel" support | ||
216 | |||
217 | CONFIG_RELOCATABLE=y | ||
218 | |||
219 | Make and install the kernel and its modules. | ||
212 | 220 | ||
213 | Dump-capture kernel config options (Arch Dependent, ia64) | 221 | Dump-capture kernel config options (Arch Dependent, ia64) |
214 | ---------------------------------------------------------- | 222 | ---------------------------------------------------------- |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 369d93e7377c..5b1527883fcb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -323,13 +323,11 @@ config KEXEC | |||
323 | 323 | ||
324 | config CRASH_DUMP | 324 | config CRASH_DUMP |
325 | bool "Build a kdump crash kernel" | 325 | bool "Build a kdump crash kernel" |
326 | depends on PPC_MULTIPLATFORM && PPC64 | 326 | depends on PPC_MULTIPLATFORM && PPC64 && RELOCATABLE |
327 | help | 327 | help |
328 | Build a kernel suitable for use as a kdump capture kernel. | 328 | Build a kernel suitable for use as a kdump capture kernel. |
329 | The kernel will be linked at a different address than normal, and | 329 | The same kernel binary can be used as production kernel and dump |
330 | so can only be used for Kdump. | 330 | capture kernel. |
331 | |||
332 | Don't change this unless you know what you are doing. | ||
333 | 331 | ||
334 | config PHYP_DUMP | 332 | config PHYP_DUMP |
335 | bool "Hypervisor-assisted dump (EXPERIMENTAL)" | 333 | bool "Hypervisor-assisted dump (EXPERIMENTAL)" |
@@ -829,11 +827,9 @@ config PAGE_OFFSET | |||
829 | default "0xc000000000000000" | 827 | default "0xc000000000000000" |
830 | config KERNEL_START | 828 | config KERNEL_START |
831 | hex | 829 | hex |
832 | default "0xc000000002000000" if CRASH_DUMP | ||
833 | default "0xc000000000000000" | 830 | default "0xc000000000000000" |
834 | config PHYSICAL_START | 831 | config PHYSICAL_START |
835 | hex | 832 | hex |
836 | default "0x02000000" if CRASH_DUMP | ||
837 | default "0x00000000" | 833 | default "0x00000000" |
838 | endif | 834 | endif |
839 | 835 | ||
diff --git a/arch/powerpc/include/asm/kdump.h b/arch/powerpc/include/asm/kdump.h index f6c93c716898..a503da9d56f3 100644 --- a/arch/powerpc/include/asm/kdump.h +++ b/arch/powerpc/include/asm/kdump.h | |||
@@ -9,6 +9,12 @@ | |||
9 | * Reserve to the end of the FWNMI area, see head_64.S */ | 9 | * Reserve to the end of the FWNMI area, see head_64.S */ |
10 | #define KDUMP_RESERVE_LIMIT 0x10000 /* 64K */ | 10 | #define KDUMP_RESERVE_LIMIT 0x10000 /* 64K */ |
11 | 11 | ||
12 | /* | ||
13 | * Used to differentiate between relocatable kdump kernel and other | ||
14 | * kernels | ||
15 | */ | ||
16 | #define KDUMP_SIGNATURE 0xfeed1234 | ||
17 | |||
12 | #ifdef CONFIG_CRASH_DUMP | 18 | #ifdef CONFIG_CRASH_DUMP |
13 | 19 | ||
14 | #define KDUMP_TRAMPOLINE_START 0x0100 | 20 | #define KDUMP_TRAMPOLINE_START 0x0100 |
@@ -19,17 +25,18 @@ | |||
19 | #endif /* CONFIG_CRASH_DUMP */ | 25 | #endif /* CONFIG_CRASH_DUMP */ |
20 | 26 | ||
21 | #ifndef __ASSEMBLY__ | 27 | #ifndef __ASSEMBLY__ |
22 | #ifdef CONFIG_CRASH_DUMP | ||
23 | 28 | ||
29 | extern unsigned long __kdump_flag; | ||
30 | |||
31 | #if defined(CONFIG_CRASH_DUMP) && !defined(CONFIG_RELOCATABLE) | ||
24 | extern void reserve_kdump_trampoline(void); | 32 | extern void reserve_kdump_trampoline(void); |
25 | extern void setup_kdump_trampoline(void); | 33 | extern void setup_kdump_trampoline(void); |
26 | 34 | #else | |
27 | #else /* !CONFIG_CRASH_DUMP */ | 35 | /* !CRASH_DUMP || RELOCATABLE */ |
28 | |||
29 | static inline void reserve_kdump_trampoline(void) { ; } | 36 | static inline void reserve_kdump_trampoline(void) { ; } |
30 | static inline void setup_kdump_trampoline(void) { ; } | 37 | static inline void setup_kdump_trampoline(void) { ; } |
38 | #endif | ||
31 | 39 | ||
32 | #endif /* CONFIG_CRASH_DUMP */ | ||
33 | #endif /* __ASSEMBLY__ */ | 40 | #endif /* __ASSEMBLY__ */ |
34 | 41 | ||
35 | #endif /* __PPC64_KDUMP_H */ | 42 | #endif /* __PPC64_KDUMP_H */ |
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 97e056379728..19671aca6591 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
@@ -30,6 +30,7 @@ | |||
30 | /* Stores the physical address of elf header of crash image. */ | 30 | /* Stores the physical address of elf header of crash image. */ |
31 | unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; | 31 | unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; |
32 | 32 | ||
33 | #ifndef CONFIG_RELOCATABLE | ||
33 | void __init reserve_kdump_trampoline(void) | 34 | void __init reserve_kdump_trampoline(void) |
34 | { | 35 | { |
35 | lmb_reserve(0, KDUMP_RESERVE_LIMIT); | 36 | lmb_reserve(0, KDUMP_RESERVE_LIMIT); |
@@ -68,6 +69,7 @@ void __init setup_kdump_trampoline(void) | |||
68 | 69 | ||
69 | DBG(" <- setup_kdump_trampoline()\n"); | 70 | DBG(" <- setup_kdump_trampoline()\n"); |
70 | } | 71 | } |
72 | #endif /* CONFIG_RELOCATABLE */ | ||
71 | 73 | ||
72 | /* | 74 | /* |
73 | * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by | 75 | * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 84856bee33a5..69489bd3210c 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -97,6 +97,12 @@ __secondary_hold_spinloop: | |||
97 | __secondary_hold_acknowledge: | 97 | __secondary_hold_acknowledge: |
98 | .llong 0x0 | 98 | .llong 0x0 |
99 | 99 | ||
100 | /* This flag is set by purgatory if we should be a kdump kernel. */ | ||
101 | /* Do not move this variable as purgatory knows about it. */ | ||
102 | .globl __kdump_flag | ||
103 | __kdump_flag: | ||
104 | .llong 0x0 | ||
105 | |||
100 | #ifdef CONFIG_PPC_ISERIES | 106 | #ifdef CONFIG_PPC_ISERIES |
101 | /* | 107 | /* |
102 | * At offset 0x20, there is a pointer to iSeries LPAR data. | 108 | * At offset 0x20, there is a pointer to iSeries LPAR data. |
@@ -1384,7 +1390,13 @@ _STATIC(__after_prom_start) | |||
1384 | /* process relocations for the final address of the kernel */ | 1390 | /* process relocations for the final address of the kernel */ |
1385 | lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ | 1391 | lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ |
1386 | sldi r25,r25,32 | 1392 | sldi r25,r25,32 |
1387 | mr r3,r25 | 1393 | #ifdef CONFIG_CRASH_DUMP |
1394 | ld r7,__kdump_flag-_stext(r26) | ||
1395 | cmpldi cr0,r7,1 /* kdump kernel ? - stay where we are */ | ||
1396 | bne 1f | ||
1397 | add r25,r25,r26 | ||
1398 | #endif | ||
1399 | 1: mr r3,r25 | ||
1388 | bl .relocate | 1400 | bl .relocate |
1389 | #endif | 1401 | #endif |
1390 | 1402 | ||
@@ -1398,11 +1410,26 @@ _STATIC(__after_prom_start) | |||
1398 | li r3,0 /* target addr */ | 1410 | li r3,0 /* target addr */ |
1399 | mr. r4,r26 /* In some cases the loader may */ | 1411 | mr. r4,r26 /* In some cases the loader may */ |
1400 | beq 9f /* have already put us at zero */ | 1412 | beq 9f /* have already put us at zero */ |
1401 | lis r5,(copy_to_here - _stext)@ha | ||
1402 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ | ||
1403 | li r6,0x100 /* Start offset, the first 0x100 */ | 1413 | li r6,0x100 /* Start offset, the first 0x100 */ |
1404 | /* bytes were copied earlier. */ | 1414 | /* bytes were copied earlier. */ |
1405 | 1415 | ||
1416 | #ifdef CONFIG_CRASH_DUMP | ||
1417 | /* | ||
1418 | * Check if the kernel has to be running as relocatable kernel based on the | ||
1419 | * variable __kdump_flag, if it is set the kernel is treated as relocatable | ||
1420 | * kernel, otherwise it will be moved to PHYSICAL_START | ||
1421 | */ | ||
1422 | ld r7,__kdump_flag-_stext(r26) | ||
1423 | cmpldi cr0,r7,1 | ||
1424 | bne 3f | ||
1425 | |||
1426 | li r5,__end_interrupts - _stext /* just copy interrupts */ | ||
1427 | b 5f | ||
1428 | 3: | ||
1429 | #endif | ||
1430 | lis r5,(copy_to_here - _stext)@ha | ||
1431 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ | ||
1432 | |||
1406 | bl .copy_and_flush /* copy the first n bytes */ | 1433 | bl .copy_and_flush /* copy the first n bytes */ |
1407 | /* this includes the code being */ | 1434 | /* this includes the code being */ |
1408 | /* executed here. */ | 1435 | /* executed here. */ |
@@ -1411,15 +1438,15 @@ _STATIC(__after_prom_start) | |||
1411 | mtctr r8 | 1438 | mtctr r8 |
1412 | bctr | 1439 | bctr |
1413 | 1440 | ||
1441 | p_end: .llong _end - _stext | ||
1442 | |||
1414 | 4: /* Now copy the rest of the kernel up to _end */ | 1443 | 4: /* Now copy the rest of the kernel up to _end */ |
1415 | addis r5,r26,(p_end - _stext)@ha | 1444 | addis r5,r26,(p_end - _stext)@ha |
1416 | ld r5,(p_end - _stext)@l(r5) /* get _end */ | 1445 | ld r5,(p_end - _stext)@l(r5) /* get _end */ |
1417 | bl .copy_and_flush /* copy the rest */ | 1446 | 5: bl .copy_and_flush /* copy the rest */ |
1418 | 1447 | ||
1419 | 9: b .start_here_multiplatform | 1448 | 9: b .start_here_multiplatform |
1420 | 1449 | ||
1421 | p_end: .llong _end - _stext | ||
1422 | |||
1423 | /* | 1450 | /* |
1424 | * Copy routine used to copy the kernel to start at physical address 0 | 1451 | * Copy routine used to copy the kernel to start at physical address 0 |
1425 | * and flush and invalidate the caches as needed. | 1452 | * and flush and invalidate the caches as needed. |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index ea1ba89f9c90..3857d7e2af0c 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -458,6 +458,42 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
458 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | 458 | spin_unlock_irqrestore(&(tbl->it_lock), flags); |
459 | } | 459 | } |
460 | 460 | ||
461 | static void iommu_table_clear(struct iommu_table *tbl) | ||
462 | { | ||
463 | if (!__kdump_flag) { | ||
464 | /* Clear the table in case firmware left allocations in it */ | ||
465 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | ||
466 | return; | ||
467 | } | ||
468 | |||
469 | #ifdef CONFIG_CRASH_DUMP | ||
470 | if (ppc_md.tce_get) { | ||
471 | unsigned long index, tceval, tcecount = 0; | ||
472 | |||
473 | /* Reserve the existing mappings left by the first kernel. */ | ||
474 | for (index = 0; index < tbl->it_size; index++) { | ||
475 | tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); | ||
476 | /* | ||
477 | * Freed TCE entry contains 0x7fffffffffffffff on JS20 | ||
478 | */ | ||
479 | if (tceval && (tceval != 0x7fffffffffffffffUL)) { | ||
480 | __set_bit(index, tbl->it_map); | ||
481 | tcecount++; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { | ||
486 | printk(KERN_WARNING "TCE table is full; freeing "); | ||
487 | printk(KERN_WARNING "%d entries for the kdump boot\n", | ||
488 | KDUMP_MIN_TCE_ENTRIES); | ||
489 | for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; | ||
490 | index < tbl->it_size; index++) | ||
491 | __clear_bit(index, tbl->it_map); | ||
492 | } | ||
493 | } | ||
494 | #endif | ||
495 | } | ||
496 | |||
461 | /* | 497 | /* |
462 | * Build a iommu_table structure. This contains a bit map which | 498 | * Build a iommu_table structure. This contains a bit map which |
463 | * is used to manage allocation of the tce space. | 499 | * is used to manage allocation of the tce space. |
@@ -484,38 +520,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
484 | tbl->it_largehint = tbl->it_halfpoint; | 520 | tbl->it_largehint = tbl->it_halfpoint; |
485 | spin_lock_init(&tbl->it_lock); | 521 | spin_lock_init(&tbl->it_lock); |
486 | 522 | ||
487 | #ifdef CONFIG_CRASH_DUMP | 523 | iommu_table_clear(tbl); |
488 | if (ppc_md.tce_get) { | ||
489 | unsigned long index; | ||
490 | unsigned long tceval; | ||
491 | unsigned long tcecount = 0; | ||
492 | |||
493 | /* | ||
494 | * Reserve the existing mappings left by the first kernel. | ||
495 | */ | ||
496 | for (index = 0; index < tbl->it_size; index++) { | ||
497 | tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); | ||
498 | /* | ||
499 | * Freed TCE entry contains 0x7fffffffffffffff on JS20 | ||
500 | */ | ||
501 | if (tceval && (tceval != 0x7fffffffffffffffUL)) { | ||
502 | __set_bit(index, tbl->it_map); | ||
503 | tcecount++; | ||
504 | } | ||
505 | } | ||
506 | if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { | ||
507 | printk(KERN_WARNING "TCE table is full; "); | ||
508 | printk(KERN_WARNING "freeing %d entries for the kdump boot\n", | ||
509 | KDUMP_MIN_TCE_ENTRIES); | ||
510 | for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; | ||
511 | index < tbl->it_size; index++) | ||
512 | __clear_bit(index, tbl->it_map); | ||
513 | } | ||
514 | } | ||
515 | #else | ||
516 | /* Clear the hardware table in case firmware left allocations in it */ | ||
517 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | ||
518 | #endif | ||
519 | 524 | ||
520 | if (!welcomed) { | 525 | if (!welcomed) { |
521 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 526 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", |
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index aab76887a842..ac2a21f45c75 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
@@ -88,11 +88,13 @@ void __init reserve_crashkernel(void) | |||
88 | 88 | ||
89 | crash_size = crashk_res.end - crashk_res.start + 1; | 89 | crash_size = crashk_res.end - crashk_res.start + 1; |
90 | 90 | ||
91 | #ifndef CONFIG_RELOCATABLE | ||
91 | if (crashk_res.start != KDUMP_KERNELBASE) | 92 | if (crashk_res.start != KDUMP_KERNELBASE) |
92 | printk("Crash kernel location must be 0x%x\n", | 93 | printk("Crash kernel location must be 0x%x\n", |
93 | KDUMP_KERNELBASE); | 94 | KDUMP_KERNELBASE); |
94 | 95 | ||
95 | crashk_res.start = KDUMP_KERNELBASE; | 96 | crashk_res.start = KDUMP_KERNELBASE; |
97 | #endif | ||
96 | crash_size = PAGE_ALIGN(crash_size); | 98 | crash_size = PAGE_ALIGN(crash_size); |
97 | crashk_res.end = crashk_res.start + crash_size - 1; | 99 | crashk_res.end = crashk_res.start + crash_size - 1; |
98 | 100 | ||
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 4bd8b4f5e70d..e6efec788c4d 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -255,11 +255,14 @@ static union thread_union kexec_stack | |||
255 | /* Our assembly helper, in kexec_stub.S */ | 255 | /* Our assembly helper, in kexec_stub.S */ |
256 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, | 256 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, |
257 | void *image, void *control, | 257 | void *image, void *control, |
258 | void (*clear_all)(void)) ATTRIB_NORET; | 258 | void (*clear_all)(void), |
259 | unsigned long kdump_flag) ATTRIB_NORET; | ||
259 | 260 | ||
260 | /* too late to fail here */ | 261 | /* too late to fail here */ |
261 | void default_machine_kexec(struct kimage *image) | 262 | void default_machine_kexec(struct kimage *image) |
262 | { | 263 | { |
264 | unsigned long kdump_flag = 0; | ||
265 | |||
263 | /* prepare control code if any */ | 266 | /* prepare control code if any */ |
264 | 267 | ||
265 | /* | 268 | /* |
@@ -270,8 +273,10 @@ void default_machine_kexec(struct kimage *image) | |||
270 | * using debugger IPI. | 273 | * using debugger IPI. |
271 | */ | 274 | */ |
272 | 275 | ||
273 | if (crashing_cpu == -1) | 276 | if (crashing_cpu == -1) |
274 | kexec_prepare_cpus(); | 277 | kexec_prepare_cpus(); |
278 | else | ||
279 | kdump_flag = KDUMP_SIGNATURE; | ||
275 | 280 | ||
276 | /* switch to a staticly allocated stack. Based on irq stack code. | 281 | /* switch to a staticly allocated stack. Based on irq stack code. |
277 | * XXX: the task struct will likely be invalid once we do the copy! | 282 | * XXX: the task struct will likely be invalid once we do the copy! |
@@ -284,7 +289,7 @@ void default_machine_kexec(struct kimage *image) | |||
284 | */ | 289 | */ |
285 | kexec_sequence(&kexec_stack, image->start, image, | 290 | kexec_sequence(&kexec_stack, image->start, image, |
286 | page_address(image->control_code_page), | 291 | page_address(image->control_code_page), |
287 | ppc_md.hpte_clear_all); | 292 | ppc_md.hpte_clear_all, kdump_flag); |
288 | /* NOTREACHED */ | 293 | /* NOTREACHED */ |
289 | } | 294 | } |
290 | 295 | ||
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 3053fe5c62f2..a243fd072a77 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -611,10 +611,12 @@ real_mode: /* assume normal blr return */ | |||
611 | 611 | ||
612 | 612 | ||
613 | /* | 613 | /* |
614 | * kexec_sequence(newstack, start, image, control, clear_all()) | 614 | * kexec_sequence(newstack, start, image, control, clear_all(), kdump_flag) |
615 | * | 615 | * |
616 | * does the grungy work with stack switching and real mode switches | 616 | * does the grungy work with stack switching and real mode switches |
617 | * also does simple calls to other code | 617 | * also does simple calls to other code |
618 | * | ||
619 | * kdump_flag says whether the next kernel should be a kdump kernel. | ||
618 | */ | 620 | */ |
619 | 621 | ||
620 | _GLOBAL(kexec_sequence) | 622 | _GLOBAL(kexec_sequence) |
@@ -647,7 +649,7 @@ _GLOBAL(kexec_sequence) | |||
647 | mr r29,r5 /* image (virt) */ | 649 | mr r29,r5 /* image (virt) */ |
648 | mr r28,r6 /* control, unused */ | 650 | mr r28,r6 /* control, unused */ |
649 | mr r27,r7 /* clear_all() fn desc */ | 651 | mr r27,r7 /* clear_all() fn desc */ |
650 | mr r26,r8 /* spare */ | 652 | mr r26,r8 /* kdump flag */ |
651 | lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */ | 653 | lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */ |
652 | 654 | ||
653 | /* disable interrupts, we are overwriting kernel data next */ | 655 | /* disable interrupts, we are overwriting kernel data next */ |
@@ -709,5 +711,6 @@ _GLOBAL(kexec_sequence) | |||
709 | mr r4,r30 # start, aka phys mem offset | 711 | mr r4,r30 # start, aka phys mem offset |
710 | mtlr 4 | 712 | mtlr 4 |
711 | li r5,0 | 713 | li r5,0 |
712 | blr /* image->start(physid, image->start, 0); */ | 714 | mr r6,r26 /* kdump_flag */ |
715 | blr /* image->start(physid, image->start, 0, kdump_flag); */ | ||
713 | #endif /* CONFIG_KEXEC */ | 716 | #endif /* CONFIG_KEXEC */ |
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 2a14b052abcd..665af1c4195b 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/machdep.h> | 21 | #include <asm/machdep.h> |
22 | #include <asm/rtas.h> | 22 | #include <asm/rtas.h> |
23 | #include <asm/cell-regs.h> | 23 | #include <asm/cell-regs.h> |
24 | #include <asm/kdump.h> | ||
24 | 25 | ||
25 | #include "ras.h" | 26 | #include "ras.h" |
26 | 27 | ||
@@ -111,9 +112,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order) | |||
111 | int ret = -ENOMEM; | 112 | int ret = -ENOMEM; |
112 | unsigned long addr; | 113 | unsigned long addr; |
113 | 114 | ||
114 | #ifdef CONFIG_CRASH_DUMP | 115 | if (__kdump_flag) |
115 | rtas_call(ptcal_stop_tok, 1, 1, NULL, nid); | 116 | rtas_call(ptcal_stop_tok, 1, 1, NULL, nid); |
116 | #endif | ||
117 | 117 | ||
118 | area = kmalloc(sizeof(*area), GFP_KERNEL); | 118 | area = kmalloc(sizeof(*area), GFP_KERNEL); |
119 | if (!area) | 119 | if (!area) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index a8c446697f9e..d56491d182d3 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/tce.h> | 44 | #include <asm/tce.h> |
45 | #include <asm/ppc-pci.h> | 45 | #include <asm/ppc-pci.h> |
46 | #include <asm/udbg.h> | 46 | #include <asm/udbg.h> |
47 | #include <asm/kdump.h> | ||
47 | 48 | ||
48 | #include "plpar_wrappers.h" | 49 | #include "plpar_wrappers.h" |
49 | 50 | ||
@@ -291,9 +292,8 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
291 | 292 | ||
292 | tbl->it_base = (unsigned long)__va(*basep); | 293 | tbl->it_base = (unsigned long)__va(*basep); |
293 | 294 | ||
294 | #ifndef CONFIG_CRASH_DUMP | 295 | if (!__kdump_flag) |
295 | memset((void *)tbl->it_base, 0, *sizep); | 296 | memset((void *)tbl->it_base, 0, *sizep); |
296 | #endif | ||
297 | 297 | ||
298 | tbl->it_busno = phb->bus->number; | 298 | tbl->it_busno = phb->bus->number; |
299 | 299 | ||