summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2011-06-06 15:47:14 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-07 19:03:52 -0700
commitdb1c9dfa649f9bd8dc11415fbfe5cfe1e24c5b33 (patch)
treee032d804997b7494ff994b496aa5b3575e3a7495
parent2e65d1f6eecc176ba1341541b5f41edd7eb4346a (diff)
downloadlinux-db1c9dfa649f9bd8dc11415fbfe5cfe1e24c5b33.tar.bz2
MN10300: die_if_no_fixup() shouldn't use get_user() as it doesn't call set_fs()
die_if_no_fixup() shouldn't use get_user() as it doesn't call set_fs() to indicate that it wants to probe a kernel address. Instead it should use probe_kernel_read(). This fixes the problem of gdb seeing SIGILL rather than SIGTRAP when hitting the KGDB special breakpoint upon SysRq+g being seen. The problem was that die_if_no_fixup() was failing to read the opcode of the instruction that caused the exception, and thus not fixing up the exception. This caused gdb to get a S04 response to the $? request in its remote protocol rather than S05 - which would then cause it to continue with $C04 rather than $c in an attempt to pass the signal onto the inferior process. The kernel, however, does not support $Cnn, and so objects by returning an E22 response, indicating an error. gdb does not expect this and prints: warning: Remote failure reply: E22 and then returns to the gdb command prompt unable to continue. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/mn10300/kernel/traps.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index f03cb278828f..bd3e5e73826e 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -28,7 +28,7 @@
#include <linux/irq.h>
#include <asm/processor.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/atomic.h>
#include <asm/smp.h>
@@ -156,7 +156,7 @@ int die_if_no_fixup(const char *str, struct pt_regs *regs,
case EXCEP_TRAP:
case EXCEP_UNIMPINS:
- if (get_user(opcode, (uint8_t __user *)regs->pc) != 0)
+ if (probe_kernel_read(&opcode, (u8 *)regs->pc, 1) < 0)
break;
if (opcode == 0xff) {
if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))