|
@@ -71,6 +71,32 @@ void __weak nmi_panic_self_stop(struct pt_regs *regs)
|
|
|
panic_smp_self_stop();
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Stop other CPUs in panic. Architecture dependent code may override this
|
|
|
+ * with more suitable version. For example, if the architecture supports
|
|
|
+ * crash dump, it should save registers of each stopped CPU and disable
|
|
|
+ * per-CPU features such as virtualization extensions.
|
|
|
+ */
|
|
|
+void __weak crash_smp_send_stop(void)
|
|
|
+{
|
|
|
+ static int cpus_stopped;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This function can be called twice in panic path, but obviously
|
|
|
+ * we execute this only once.
|
|
|
+ */
|
|
|
+ if (cpus_stopped)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Note smp_send_stop is the usual smp shutdown function, which
|
|
|
+ * unfortunately means it may not be hardened to work in a panic
|
|
|
+ * situation.
|
|
|
+ */
|
|
|
+ smp_send_stop();
|
|
|
+ cpus_stopped = 1;
|
|
|
+}
|
|
|
+
|
|
|
atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID);
|
|
|
|
|
|
/*
|
|
@@ -164,14 +190,21 @@ void panic(const char *fmt, ...)
|
|
|
if (!_crash_kexec_post_notifiers) {
|
|
|
printk_nmi_flush_on_panic();
|
|
|
__crash_kexec(NULL);
|
|
|
- }
|
|
|
|
|
|
- /*
|
|
|
- * Note smp_send_stop is the usual smp shutdown function, which
|
|
|
- * unfortunately means it may not be hardened to work in a panic
|
|
|
- * situation.
|
|
|
- */
|
|
|
- smp_send_stop();
|
|
|
+ /*
|
|
|
+ * Note smp_send_stop is the usual smp shutdown function, which
|
|
|
+ * unfortunately means it may not be hardened to work in a
|
|
|
+ * panic situation.
|
|
|
+ */
|
|
|
+ smp_send_stop();
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * If we want to do crash dump after notifier calls and
|
|
|
+ * kmsg_dump, we will need architecture dependent extra
|
|
|
+ * works in addition to stopping other CPUs.
|
|
|
+ */
|
|
|
+ crash_smp_send_stop();
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* Run any panic handlers, including those that might need to
|