diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 14:17:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 14:17:05 -0400 |
commit | 79c4581262e225a7c96d88b632b05ab3b5e9a52c (patch) | |
tree | 8ef030c74ab7e0d0df27cf86195f915efd2832f7 /arch/powerpc/kernel/crash.c | |
parent | 59534f7298c5e28aaa64e6ed550e247f64ee72ae (diff) | |
parent | 99ec28f183daa450faa7bdad6f932364ae325648 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (92 commits)
powerpc: Remove unused 'protect4gb' boot parameter
powerpc: Build-in e1000e for pseries & ppc64_defconfig
powerpc/pseries: Make request_ras_irqs() available to other pseries code
powerpc/numa: Use ibm,architecture-vec-5 to detect form 1 affinity
powerpc/numa: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim
powerpc: Use smt_snooze_delay=-1 to always busy loop
powerpc: Remove check of ibm,smt-snooze-delay OF property
powerpc/kdump: Fix race in kdump shutdown
powerpc/kexec: Fix race in kexec shutdown
powerpc/kexec: Speedup kexec hash PTE tear down
powerpc/pseries: Add hcall to read 4 ptes at a time in real mode
powerpc: Use more accurate limit for first segment memory allocations
powerpc/kdump: Use chip->shutdown to disable IRQs
powerpc/kdump: CPUs assume the context of the oopsing CPU
powerpc/crashdump: Do not fail on NULL pointer dereferencing
powerpc/eeh: Fix oops when probing in early boot
powerpc/pci: Check devices status property when scanning OF tree
powerpc/vio: Switch VIO Bus PM to use generic helpers
powerpc: Avoid bad relocations in iSeries code
powerpc: Use common cpu_die (fixes SMP+SUSPEND build)
...
Diffstat (limited to 'arch/powerpc/kernel/crash.c')
-rw-r--r-- | arch/powerpc/kernel/crash.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 6f4613dd05ef..8c066d6a8e4b 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -162,6 +162,32 @@ static void crash_kexec_prepare_cpus(int cpu) | |||
162 | /* Leave the IPI callback set */ | 162 | /* Leave the IPI callback set */ |
163 | } | 163 | } |
164 | 164 | ||
165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ | ||
166 | static void crash_kexec_wait_realmode(int cpu) | ||
167 | { | ||
168 | unsigned int msecs; | ||
169 | int i; | ||
170 | |||
171 | msecs = 10000; | ||
172 | for (i=0; i < NR_CPUS && msecs > 0; i++) { | ||
173 | if (i == cpu) | ||
174 | continue; | ||
175 | |||
176 | while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { | ||
177 | barrier(); | ||
178 | if (!cpu_possible(i)) { | ||
179 | break; | ||
180 | } | ||
181 | if (!cpu_online(i)) { | ||
182 | break; | ||
183 | } | ||
184 | msecs--; | ||
185 | mdelay(1); | ||
186 | } | ||
187 | } | ||
188 | mb(); | ||
189 | } | ||
190 | |||
165 | /* | 191 | /* |
166 | * This function will be called by secondary cpus or by kexec cpu | 192 | * This function will be called by secondary cpus or by kexec cpu |
167 | * if soft-reset is activated to stop some CPUs. | 193 | * if soft-reset is activated to stop some CPUs. |
@@ -347,10 +373,12 @@ int crash_shutdown_unregister(crash_shutdown_t handler) | |||
347 | EXPORT_SYMBOL(crash_shutdown_unregister); | 373 | EXPORT_SYMBOL(crash_shutdown_unregister); |
348 | 374 | ||
349 | static unsigned long crash_shutdown_buf[JMP_BUF_LEN]; | 375 | static unsigned long crash_shutdown_buf[JMP_BUF_LEN]; |
376 | static int crash_shutdown_cpu = -1; | ||
350 | 377 | ||
351 | static int handle_fault(struct pt_regs *regs) | 378 | static int handle_fault(struct pt_regs *regs) |
352 | { | 379 | { |
353 | longjmp(crash_shutdown_buf, 1); | 380 | if (crash_shutdown_cpu == smp_processor_id()) |
381 | longjmp(crash_shutdown_buf, 1); | ||
354 | return 0; | 382 | return 0; |
355 | } | 383 | } |
356 | 384 | ||
@@ -375,11 +403,14 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
375 | for_each_irq(i) { | 403 | for_each_irq(i) { |
376 | struct irq_desc *desc = irq_to_desc(i); | 404 | struct irq_desc *desc = irq_to_desc(i); |
377 | 405 | ||
406 | if (!desc || !desc->chip || !desc->chip->eoi) | ||
407 | continue; | ||
408 | |||
378 | if (desc->status & IRQ_INPROGRESS) | 409 | if (desc->status & IRQ_INPROGRESS) |
379 | desc->chip->eoi(i); | 410 | desc->chip->eoi(i); |
380 | 411 | ||
381 | if (!(desc->status & IRQ_DISABLED)) | 412 | if (!(desc->status & IRQ_DISABLED)) |
382 | desc->chip->disable(i); | 413 | desc->chip->shutdown(i); |
383 | } | 414 | } |
384 | 415 | ||
385 | /* | 416 | /* |
@@ -388,6 +419,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
388 | */ | 419 | */ |
389 | old_handler = __debugger_fault_handler; | 420 | old_handler = __debugger_fault_handler; |
390 | __debugger_fault_handler = handle_fault; | 421 | __debugger_fault_handler = handle_fault; |
422 | crash_shutdown_cpu = smp_processor_id(); | ||
391 | for (i = 0; crash_shutdown_handles[i]; i++) { | 423 | for (i = 0; crash_shutdown_handles[i]; i++) { |
392 | if (setjmp(crash_shutdown_buf) == 0) { | 424 | if (setjmp(crash_shutdown_buf) == 0) { |
393 | /* | 425 | /* |
@@ -401,6 +433,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
401 | asm volatile("sync; isync"); | 433 | asm volatile("sync; isync"); |
402 | } | 434 | } |
403 | } | 435 | } |
436 | crash_shutdown_cpu = -1; | ||
404 | __debugger_fault_handler = old_handler; | 437 | __debugger_fault_handler = old_handler; |
405 | 438 | ||
406 | /* | 439 | /* |
@@ -412,6 +445,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
412 | crash_kexec_prepare_cpus(crashing_cpu); | 445 | crash_kexec_prepare_cpus(crashing_cpu); |
413 | cpu_set(crashing_cpu, cpus_in_crash); | 446 | cpu_set(crashing_cpu, cpus_in_crash); |
414 | crash_kexec_stop_spus(); | 447 | crash_kexec_stop_spus(); |
448 | crash_kexec_wait_realmode(crashing_cpu); | ||
415 | if (ppc_md.kexec_cpu_down) | 449 | if (ppc_md.kexec_cpu_down) |
416 | ppc_md.kexec_cpu_down(1, 0); | 450 | ppc_md.kexec_cpu_down(1, 0); |
417 | } | 451 | } |