diff mbox

sparc64: fatal trap should stop all cpus

Message ID 54A1E25E.3020806@oracle.com
State Changes Requested
Delegated to: David Miller
Headers show

Commit Message

Dave Kleikamp Dec. 29, 2014, 11:23 p.m. UTC
"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>
---
 arch/sparc/kernel/smp_64.c   |   12 +++++++++---
 arch/sparc/kernel/traps_64.c |    2 ++
 2 files changed, 11 insertions(+), 3 deletions(-)

Comments

David Miller Jan. 5, 2015, 4:58 a.m. UTC | #1
From: Dave Kleikamp <dave.kleikamp@oracle.com>
Date: Mon, 29 Dec 2014 17:23:10 -0600

> +	while (1) ;

Like the powerpc implementation, please correctly format this as:

	while (1)
		;

However I also have to wonder if we should be doing a hypervisor
or firmware CPU stop call in that handler.

That's what the XEN x86 implementation does.

It should logically do something like:

	if (tlb_type == hypervisor) {
		if (ldom_domaining_enabled)
			sun4v_stop_cpu(cpuid);
		else
			prom_stopcpu_cpuid(cpuid);
	} else
		smp_call_function(wrapper_around_prom_stopself, NULL, 0);
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 32d4b3b..37d5789 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1406,11 +1406,17 @@  void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
 	scheduler_ipi();
 }
 
-/* This is a nop because we capture all other cpus
- * anyways when making the PROM active.
- */
+void stop_this_cpu(void *dummy)
+{
+	set_cpu_online(smp_processor_id(), false);
+
+	local_irq_disable();
+	while (1) ;
+}
+
 void smp_send_stop(void)
 {
+	smp_call_function(stop_this_cpu, NULL, 0);
 }
 
 /**
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index e7ecf15..720be08 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2408,6 +2408,8 @@  void die_if_kernel(char *str, struct pt_regs *regs)
 		}
 		user_instruction_dump ((unsigned int __user *) regs->tpc);
 	}
+	if (panic_on_oops)
+		panic("Fatal exception");
 	if (regs->tstate & TSTATE_PRIV)
 		do_exit(SIGKILL);
 	do_exit(SIGSEGV);