extern void printk_nmi_enter(void);
 extern void printk_nmi_exit(void);
 extern void printk_nmi_flush(void);
+extern void printk_nmi_flush_on_panic(void);
 #else
 static inline void printk_nmi_init(void) { }
 static inline void printk_nmi_enter(void) { }
 static inline void printk_nmi_exit(void) { }
 static inline void printk_nmi_flush(void) { }
+static inline void printk_nmi_flush_on_panic(void) { }
 #endif /* PRINTK_NMI */
 
 #ifdef CONFIG_PRINTK
 
        old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu);
        if (old_cpu == PANIC_CPU_INVALID) {
                /* This is the 1st CPU which comes here, so go ahead. */
+               printk_nmi_flush_on_panic();
                __crash_kexec(regs);
 
                /*
 
         *
         * Bypass the panic_cpu check and call __crash_kexec directly.
         */
-       if (!crash_kexec_post_notifiers)
+       if (!crash_kexec_post_notifiers) {
+               printk_nmi_flush_on_panic();
                __crash_kexec(NULL);
+       }
 
        /*
         * Note smp_send_stop is the usual smp shutdown function, which
         */
        atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
 
+       /* Call flush even twice. It tries harder with a single online CPU */
+       printk_nmi_flush_on_panic();
        kmsg_dump(KMSG_DUMP_PANIC);
 
        /*
 
 
 #ifdef CONFIG_PRINTK_NMI
 
+extern raw_spinlock_t logbuf_lock;
+
 /*
  * printk() could not take logbuf_lock in NMI context. Instead,
  * it temporary stores the strings into a per-CPU buffer.
 
 
 #include <linux/preempt.h>
 #include <linux/spinlock.h>
+#include <linux/debug_locks.h>
 #include <linux/smp.h>
 #include <linux/cpumask.h>
 #include <linux/irq_work.h>
 {
        const char *buf = s->buffer + start;
 
-       printk("%.*s", (end - start) + 1, buf);
+       /*
+        * The buffers are flushed in NMI only on panic.  The messages must
+        * go only into the ring buffer at this stage.  Consoles will get
+        * explicitly called later when a crashdump is not generated.
+        */
+       if (in_nmi())
+               printk_deferred("%.*s", (end - start) + 1, buf);
+       else
+               printk("%.*s", (end - start) + 1, buf);
+
 }
 
 /*
                __printk_nmi_flush(&per_cpu(nmi_print_seq, cpu).work);
 }
 
+/**
+ * printk_nmi_flush_on_panic - flush all per-cpu nmi buffers when the system
+ *     goes down.
+ *
+ * Similar to printk_nmi_flush() but it can be called even in NMI context when
+ * the system goes down. It does the best effort to get NMI messages into
+ * the main ring buffer.
+ *
+ * Note that it could try harder when there is only one CPU online.
+ */
+void printk_nmi_flush_on_panic(void)
+{
+       /*
+        * Make sure that we could access the main ring buffer.
+        * Do not risk a double release when more CPUs are up.
+        */
+       if (in_nmi() && raw_spin_is_locked(&logbuf_lock)) {
+               if (num_online_cpus() > 1)
+                       return;
+
+               debug_locks_off();
+               raw_spin_lock_init(&logbuf_lock);
+       }
+
+       printk_nmi_flush();
+}
+
 void __init printk_nmi_init(void)
 {
        int cpu;
 
  * within the scheduler's rq lock. It must be released before calling
  * console_unlock() or anything else that might wake up a process.
  */
-static DEFINE_RAW_SPINLOCK(logbuf_lock);
+DEFINE_RAW_SPINLOCK(logbuf_lock);
 
 #ifdef CONFIG_PRINTK
 DECLARE_WAIT_QUEUE_HEAD(log_wait);