diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 11:08:05 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 11:08:05 -0700 |
commit | 90b9a32d8f441369b2f97a765d2d957b531eb653 (patch) | |
tree | 3146d251a983ba12226e75c121613de6f051af8b /arch/mips | |
parent | 8b108c609adefd98577c35f0a41497a610041a6c (diff) | |
parent | 4402c153cb9c549cd21d6007ef0dfac50c8d148d (diff) |
Merge branch 'kdb-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb
* 'kdb-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb: (25 commits)
kdb,debug_core: Allow the debug core to receive a panic notification
MAINTAINERS: update kgdb, kdb, and debug_core info
debug_core,kdb: Allow the debug core to process a recursive debug entry
printk,kdb: capture printk() when in kdb shell
kgdboc,kdb: Allow kdb to work on a non open console port
kgdb: Add the ability to schedule a breakpoint via a tasklet
mips,kgdb: kdb low level trap catch and stack trace
powerpc,kgdb: Introduce low level trap catching
x86,kgdb: Add low level debug hook
kgdb: remove post_primary_code references
kgdb,docs: Update the kgdb docs to include kdb
kgdboc,keyboard: Keyboard driver for kdb with kgdb
kgdb: gdb "monitor" -> kdb passthrough
sparc,sunzilog: Add console polling support for sunzilog serial driver
sh,sh-sci: Use NO_POLL_CHAR in the SCIF polled console code
kgdb,8250,pl011: Return immediately from console poll
kgdb: core changes to support kdb
kdb: core for kgdb back end (2 of 2)
kdb: core for kgdb back end (1 of 2)
kgdb,blackfin: Add in kgdb_arch_set_pc for blackfin
...
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/kgdb.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/kgdb.c | 27 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 13 |
3 files changed, 41 insertions, 1 deletions
diff --git a/arch/mips/include/asm/kgdb.h b/arch/mips/include/asm/kgdb.h index 48223b09396..19002d605ac 100644 --- a/arch/mips/include/asm/kgdb.h +++ b/arch/mips/include/asm/kgdb.h @@ -38,6 +38,8 @@ extern int kgdb_early_setup; extern void *saved_vectors[32]; extern void handle_exception(struct pt_regs *regs); extern void breakinst(void); +extern int kgdb_ll_trap(int cmd, const char *str, + struct pt_regs *regs, long err, int trap, int sig); #endif /* __KERNEL__ */ diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 50c9bb88066..9b78ff6e9b8 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -180,6 +180,11 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) *(ptr++) = regs->cp0_epc; } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) +{ + regs->cp0_epc = pc; +} + /* * Calls linux_debug_hook before the kernel dies. If KGDB is enabled, * then try to fall into the debugger @@ -198,7 +203,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, if (atomic_read(&kgdb_active) != -1) kgdb_nmicallback(smp_processor_id(), regs); - if (kgdb_handle_exception(trap, compute_signal(trap), 0, regs)) + if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) return NOTIFY_DONE; if (atomic_read(&kgdb_setting_breakpoint)) @@ -212,6 +217,26 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, return NOTIFY_STOP; } +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP +int kgdb_ll_trap(int cmd, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig, + + }; + + if (!kgdb_io_module_registered) + return NOTIFY_DONE; + + return kgdb_mips_notify(NULL, cmd, &args); +} +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ + static struct notifier_block kgdb_notifier = { .notifier_call = kgdb_mips_notify, }; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index d612c6dcb74..950bde8813f 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -26,6 +26,7 @@ #include <linux/kgdb.h> #include <linux/kdebug.h> #include <linux/notifier.h> +#include <linux/kdb.h> #include <asm/bootinfo.h> #include <asm/branch.h> @@ -185,6 +186,11 @@ void show_stack(struct task_struct *task, unsigned long *sp) regs.regs[29] = task->thread.reg29; regs.regs[31] = 0; regs.cp0_epc = task->thread.reg31; +#ifdef CONFIG_KGDB_KDB + } else if (atomic_read(&kgdb_active) != -1 && + kdb_current_regs) { + memcpy(®s, kdb_current_regs, sizeof(regs)); +#endif /* CONFIG_KGDB_KDB */ } else { prepare_frametrace(®s); } @@ -360,6 +366,8 @@ void __noreturn die(const char * str, struct pt_regs * regs) unsigned long dvpret = dvpe(); #endif /* CONFIG_MIPS_MT_SMTC */ + notify_die(DIE_OOPS, str, (struct pt_regs *)regs, SIGSEGV, 0, 0); + console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); @@ -704,6 +712,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, siginfo_t info; char b[40]; +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP + if (kgdb_ll_trap(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) + return; +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ + if (notify_die(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) return; |