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>
This commit is contained in:
parent
2e65d1f6ee
commit
db1c9dfa64
1 changed files with 2 additions and 2 deletions
|
@ -28,7 +28,7 @@
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
#include <asm/smp.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_TRAP:
|
||||||
case EXCEP_UNIMPINS:
|
case EXCEP_UNIMPINS:
|
||||||
if (get_user(opcode, (uint8_t __user *)regs->pc) != 0)
|
if (probe_kernel_read(&opcode, (u8 *)regs->pc, 1) < 0)
|
||||||
break;
|
break;
|
||||||
if (opcode == 0xff) {
|
if (opcode == 0xff) {
|
||||||
if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
|
if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
|
||||||
|
|
Loading…
Reference in a new issue