diff options
Diffstat (limited to 'arch/mips/kernel/kgdb.c')
-rw-r--r-- | arch/mips/kernel/kgdb.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index fcaac2f132f0..7afcc2f22c0d 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/cacheflush.h> | 32 | #include <asm/cacheflush.h> |
33 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
34 | #include <asm/sigcontext.h> | 34 | #include <asm/sigcontext.h> |
35 | #include <asm/uaccess.h> | ||
35 | 36 | ||
36 | static struct hard_trap_info { | 37 | static struct hard_trap_info { |
37 | unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ | 38 | unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ |
@@ -208,7 +209,14 @@ void arch_kgdb_breakpoint(void) | |||
208 | 209 | ||
209 | static void kgdb_call_nmi_hook(void *ignored) | 210 | static void kgdb_call_nmi_hook(void *ignored) |
210 | { | 211 | { |
212 | mm_segment_t old_fs; | ||
213 | |||
214 | old_fs = get_fs(); | ||
215 | set_fs(get_ds()); | ||
216 | |||
211 | kgdb_nmicallback(raw_smp_processor_id(), NULL); | 217 | kgdb_nmicallback(raw_smp_processor_id(), NULL); |
218 | |||
219 | set_fs(old_fs); | ||
212 | } | 220 | } |
213 | 221 | ||
214 | void kgdb_roundup_cpus(unsigned long flags) | 222 | void kgdb_roundup_cpus(unsigned long flags) |
@@ -282,6 +290,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, | |||
282 | struct die_args *args = (struct die_args *)ptr; | 290 | struct die_args *args = (struct die_args *)ptr; |
283 | struct pt_regs *regs = args->regs; | 291 | struct pt_regs *regs = args->regs; |
284 | int trap = (regs->cp0_cause & 0x7c) >> 2; | 292 | int trap = (regs->cp0_cause & 0x7c) >> 2; |
293 | mm_segment_t old_fs; | ||
285 | 294 | ||
286 | #ifdef CONFIG_KPROBES | 295 | #ifdef CONFIG_KPROBES |
287 | /* | 296 | /* |
@@ -296,11 +305,17 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, | |||
296 | if (user_mode(regs)) | 305 | if (user_mode(regs)) |
297 | return NOTIFY_DONE; | 306 | return NOTIFY_DONE; |
298 | 307 | ||
308 | /* Kernel mode. Set correct address limit */ | ||
309 | old_fs = get_fs(); | ||
310 | set_fs(get_ds()); | ||
311 | |||
299 | if (atomic_read(&kgdb_active) != -1) | 312 | if (atomic_read(&kgdb_active) != -1) |
300 | kgdb_nmicallback(smp_processor_id(), regs); | 313 | kgdb_nmicallback(smp_processor_id(), regs); |
301 | 314 | ||
302 | if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) | 315 | if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) { |
316 | set_fs(old_fs); | ||
303 | return NOTIFY_DONE; | 317 | return NOTIFY_DONE; |
318 | } | ||
304 | 319 | ||
305 | if (atomic_read(&kgdb_setting_breakpoint)) | 320 | if (atomic_read(&kgdb_setting_breakpoint)) |
306 | if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst)) | 321 | 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, | |||
310 | local_irq_enable(); | 325 | local_irq_enable(); |
311 | __flush_cache_all(); | 326 | __flush_cache_all(); |
312 | 327 | ||
328 | set_fs(old_fs); | ||
313 | return NOTIFY_STOP; | 329 | return NOTIFY_STOP; |
314 | } | 330 | } |
315 | 331 | ||