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
