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 387a916..3504c1c 100644
--- a/include/linux/kdb.h
+++ b/include/linux/kdb.h
@@ -114,5 +114,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 e6c6f8a..b28a0a4 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>
@@ -750,11 +751,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
@@ -774,6 +791,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.4.rc1


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to