diff options
author | Dave Kleikamp <dave.kleikamp@oracle.com> | 2015-01-06 19:31:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-02 00:42:57 -0500 |
commit | 94ab5990760a54bb1f0fca99e0d374260cae3b8b (patch) | |
tree | c24586962b38930c843bd6135fb71b64fdc812f2 | |
parent | 8f765b84918de82789c1f7650490e15208cb1eb3 (diff) |
sparc64: fatal trap should stop all cpus
"echo c > /proc/sysrq-trigger" does not result in a system crash. There
are two problems. One is that the trap handler ignores the global
variable, panic_on_oops. The other is that smp_send_stop() is a no-op
which leaves the other cpus running normally when one cpu panics.
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc/kernel/smp_64.c | 27 | ||||
-rw-r--r-- | arch/sparc/kernel/traps_64.c | 2 |
2 files changed, 26 insertions, 3 deletions
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index da6f1a7fc4db..61139d9924ca 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -1406,11 +1406,32 @@ void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) | |||
1406 | scheduler_ipi(); | 1406 | scheduler_ipi(); |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | /* This is a nop because we capture all other cpus | 1409 | static void stop_this_cpu(void *dummy) |
1410 | * anyways when making the PROM active. | 1410 | { |
1411 | */ | 1411 | prom_stopself(); |
1412 | } | ||
1413 | |||
1412 | void smp_send_stop(void) | 1414 | void smp_send_stop(void) |
1413 | { | 1415 | { |
1416 | int cpu; | ||
1417 | |||
1418 | if (tlb_type == hypervisor) { | ||
1419 | for_each_online_cpu(cpu) { | ||
1420 | if (cpu == smp_processor_id()) | ||
1421 | continue; | ||
1422 | #ifdef CONFIG_SUN_LDOMS | ||
1423 | if (ldom_domaining_enabled) { | ||
1424 | unsigned long hv_err; | ||
1425 | hv_err = sun4v_cpu_stop(cpu); | ||
1426 | if (hv_err) | ||
1427 | printk(KERN_ERR "sun4v_cpu_stop() " | ||
1428 | "failed err=%lu\n", hv_err); | ||
1429 | } else | ||
1430 | #endif | ||
1431 | prom_stopcpu_cpuid(cpu); | ||
1432 | } | ||
1433 | } else | ||
1434 | smp_call_function(stop_this_cpu, NULL, 0); | ||
1414 | } | 1435 | } |
1415 | 1436 | ||
1416 | /** | 1437 | /** |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 1ef1af4cf96b..0e699745d643 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -2427,6 +2427,8 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs) | |||
2427 | } | 2427 | } |
2428 | user_instruction_dump ((unsigned int __user *) regs->tpc); | 2428 | user_instruction_dump ((unsigned int __user *) regs->tpc); |
2429 | } | 2429 | } |
2430 | if (panic_on_oops) | ||
2431 | panic("Fatal exception"); | ||
2430 | if (regs->tstate & TSTATE_PRIV) | 2432 | if (regs->tstate & TSTATE_PRIV) |
2431 | do_exit(SIGKILL); | 2433 | do_exit(SIGKILL); |
2432 | do_exit(SIGSEGV); | 2434 | do_exit(SIGSEGV); |