aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/kgdb.c
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2010-05-20 22:04:25 -0400
committerJason Wessel <jason.wessel@windriver.com>2010-05-20 22:04:25 -0400
commitf503b5ae53cb557ac351a668fcac1baab1cef0db (patch)
treeb2deb02cec90cb18a075b3a49e6de949db374c77 /arch/x86/kernel/kgdb.c
parent98ec1878cacb393975cba64f7392eece81716cb4 (diff)
x86,kgdb: Add low level debug hook
The only way the debugger can handle a trap in inside rcu_lock, notify_die, or atomic_notifier_call_chain without a triple fault is to have a low level "first opportunity handler" in the int3 exception handler. Generally this will be something the vast majority of folks will not need, but for those who need it, it is added as a kernel .config option called KGDB_LOW_LEVEL_TRAP. CC: Ingo Molnar <mingo@elte.hu> CC: Thomas Gleixner <tglx@linutronix.de> CC: H. Peter Anvin <hpa@zytor.com> CC: x86@kernel.org Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'arch/x86/kernel/kgdb.c')
-rw-r--r--arch/x86/kernel/kgdb.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index acba57169938..95b89d4cb8f1 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -538,7 +538,7 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
538 return NOTIFY_DONE; 538 return NOTIFY_DONE;
539 } 539 }
540 540
541 if (kgdb_handle_exception(args->trapnr, args->signr, args->err, regs)) 541 if (kgdb_handle_exception(args->trapnr, args->signr, cmd, regs))
542 return NOTIFY_DONE; 542 return NOTIFY_DONE;
543 543
544 /* Must touch watchdog before return to normal operation */ 544 /* Must touch watchdog before return to normal operation */
@@ -546,6 +546,26 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
546 return NOTIFY_STOP; 546 return NOTIFY_STOP;
547} 547}
548 548
549#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
550int kgdb_ll_trap(int cmd, const char *str,
551 struct pt_regs *regs, long err, int trap, int sig)
552{
553 struct die_args args = {
554 .regs = regs,
555 .str = str,
556 .err = err,
557 .trapnr = trap,
558 .signr = sig,
559
560 };
561
562 if (!kgdb_io_module_registered)
563 return NOTIFY_DONE;
564
565 return __kgdb_notify(&args, cmd);
566}
567#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
568
549static int 569static int
550kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) 570kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
551{ 571{