It is highly desirable to trap into kdb on panic, and in order
to do so the notifier must be called before smp_send_stop(),
else the debug_core will not be able to correctly trap
all the CPUs.

CC: Ingo Molnar <[email protected]>
CC: Andrew Morton <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
 include/linux/kdb.h       |    1 +
 kernel/debug/debug_core.c |   19 +++++++++++++++++++
 kernel/panic.c            |    7 ++++---
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/include/linux/kdb.h b/include/linux/kdb.h
index 118fd49..75d8777 100644
--- a/include/linux/kdb.h
+++ b/include/linux/kdb.h
@@ -113,5 +113,6 @@ extern void kdb_si_swapinfo(struct sysinfo *);
 
 #else /* ! CONFIG_KGDB_KDB */
 #define KDB_IS_RUNNING() (0)
+#define kdb_printf(...)
 #endif /* CONFIG_KGDB_KDB */
 #endif /* !_KDB_H */
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 344e332..d755fd1 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -46,6 +46,7 @@
 #include <linux/pid.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
+#include <linux/kdb.h>
 
 #include <asm/cacheflush.h>
 #include <asm/byteorder.h>
@@ -749,11 +750,27 @@ static struct sysrq_key_op sysrq_dbg_op = {
 };
 #endif
 
+static int kgdb_panic_event(struct notifier_block *self,
+                           unsigned long val,
+                           void *data)
+{
+       if (dbg_kdb_mode)
+               kdb_printf("PANIC: %s\n", (char *)data);
+       kgdb_breakpoint();
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block kgdb_panic_event_nb = {
+       .notifier_call  = kgdb_panic_event,
+};
+
 static void kgdb_register_callbacks(void)
 {
        if (!kgdb_io_module_registered) {
                kgdb_io_module_registered = 1;
                kgdb_arch_init();
+               atomic_notifier_chain_register(&panic_notifier_list,
+                                              &kgdb_panic_event_nb);
 #ifdef CONFIG_MAGIC_SYSRQ
                register_sysrq_key('g', &sysrq_dbg_op);
 #endif
@@ -773,6 +790,8 @@ static void kgdb_unregister_callbacks(void)
         */
        if (kgdb_io_module_registered) {
                kgdb_io_module_registered = 0;
+               atomic_notifier_chain_unregister(&panic_notifier_list,
+                                              &kgdb_panic_event_nb);
                kgdb_arch_exit();
 #ifdef CONFIG_MAGIC_SYSRQ
                unregister_sysrq_key('g', &sysrq_dbg_op);
diff --git a/kernel/panic.c b/kernel/panic.c
index 5827f7b..1f4fb47 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -66,10 +66,13 @@ NORET_TYPE void panic(const char * fmt, ...)
         */
        preempt_disable();
 
-       bust_spinlocks(1);
        va_start(args, fmt);
        vsnprintf(buf, sizeof(buf), fmt, args);
        va_end(args);
+
+       atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
+
+       bust_spinlocks(1);
        printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
 #ifdef CONFIG_DEBUG_BUGVERBOSE
        dump_stack();
@@ -90,8 +93,6 @@ NORET_TYPE void panic(const char * fmt, ...)
         */
        smp_send_stop();
 
-       atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
-
        bust_spinlocks(0);
 
        if (!panic_blink)
-- 
1.6.3.1.9.g95405b


------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to