summary refs log tree commit diff
path: root/kernel/debug/debug_core.c
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2010-05-20 21:04:28 -0500
committerJason Wessel <jason.wessel@windriver.com>2010-05-20 21:04:28 -0500
commit4402c153cb9c549cd21d6007ef0dfac50c8d148d (patch)
tree2a2589958e3d5243b265ba2a9fb6f5f2ecb33b57 /kernel/debug/debug_core.c
parent5b778dadcde0d93eb20a67bad8105b6ed8d7810f (diff)
downloadlinux-4402c153cb9c549cd21d6007ef0dfac50c8d148d.tar.gz
kdb,debug_core: Allow the debug core to receive a panic notification
It is highly desirable to trap into kdb on panic.  The debug core will
attempt to register as the first in line for the panic notifier.

CC: Ingo Molnar <mingo@elte.hu>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'kernel/debug/debug_core.c')
-rw-r--r--kernel/debug/debug_core.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index b38bb25dbbb3..64b5588c9638 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -762,11 +762,28 @@ 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,
+       .priority	= INT_MAX,
+};
+
 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
@@ -786,6 +803,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);