diff options
Diffstat (limited to 'arch/mips/kernel/kgdb.c')
| -rw-r--r-- | arch/mips/kernel/kgdb.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 23817a6e32b..7afcc2f22c0 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -32,6 +32,7 @@ #include <asm/cacheflush.h> #include <asm/processor.h> #include <asm/sigcontext.h> +#include <asm/uaccess.h> static struct hard_trap_info { unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ @@ -40,7 +41,7 @@ static struct hard_trap_info { { 6, SIGBUS }, /* instruction bus error */ { 7, SIGBUS }, /* data bus error */ { 9, SIGTRAP }, /* break */ -/* { 11, SIGILL }, */ /* CPU unusable */ +/* { 11, SIGILL }, */ /* CPU unusable */ { 12, SIGFPE }, /* overflow */ { 13, SIGTRAP }, /* trap */ { 14, SIGSEGV }, /* virtual instruction cache coherency */ @@ -208,7 +209,14 @@ void arch_kgdb_breakpoint(void) static void kgdb_call_nmi_hook(void *ignored) { + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(get_ds()); + kgdb_nmicallback(raw_smp_processor_id(), NULL); + + set_fs(old_fs); } void kgdb_roundup_cpus(unsigned long flags) @@ -282,6 +290,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, struct die_args *args = (struct die_args *)ptr; struct pt_regs *regs = args->regs; int trap = (regs->cp0_cause & 0x7c) >> 2; + mm_segment_t old_fs; #ifdef CONFIG_KPROBES /* @@ -296,11 +305,17 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, if (user_mode(regs)) return NOTIFY_DONE; + /* Kernel mode. Set correct address limit */ + old_fs = get_fs(); + set_fs(get_ds()); + if (atomic_read(&kgdb_active) != -1) kgdb_nmicallback(smp_processor_id(), regs); - if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) + if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) { + set_fs(old_fs); return NOTIFY_DONE; + } if (atomic_read(&kgdb_setting_breakpoint)) if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst)) @@ -310,6 +325,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, local_irq_enable(); __flush_cache_all(); + set_fs(old_fs); return NOTIFY_STOP; } @@ -321,7 +337,7 @@ int kgdb_ll_trap(int cmd, const char *str, .regs = regs, .str = str, .err = err, - .trapnr = trap, + .trapnr = trap, .signr = sig, }; @@ -371,7 +387,7 @@ int kgdb_arch_init(void) union mips_instruction insn = { .r_format = { .opcode = spec_op, - .func = break_op, + .func = break_op, } }; memcpy(arch_kgdb_ops.gdb_bpt_instr, insn.byte, BREAK_INSTR_SIZE); |
