diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-10-10 18:03:57 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-18 18:45:45 +0400 |
commit | 4b3ea63f5af44f93bd28d94a93508bbd3186be89 (patch) | |
tree | 67c9f9eddaedff1df14eb08a9576e847a62697bc /arch | |
parent | 19a420033da02200c424adfa3a7b9eed6e3a6dc2 (diff) | |
download | linux-4b3ea63f5af44f93bd28d94a93508bbd3186be89.tar.xz |
ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc"
commit 5b24282846c064ee90d40fcb3a8f63b8e754fd28 upstream.
ARCompact TRAP_S insn used for breakpoints, commits before exception is
taken (updating architectural PC). So ptregs->ret contains next-PC and
not the breakpoint PC itself. This is different from other restartable
exceptions such as TLB Miss where ptregs->ret has exact faulting PC.
gdb needs to know exact-PC hence ARC ptrace GETREGSET provides for
@stop_pc which returns ptregs->ret vs. EFA depending on the
situation.
However, writing stop_pc (SETREGSET request), which updates ptregs->ret
doesn't makes sense stop_pc doesn't always correspond to that reg as
described above.
This was not an issue so far since user_regs->ret / user_regs->stop_pc
had same value and both writing to ptregs->ret was OK, needless, but NOT
broken, hence not observed.
With gdb "jump", they diverge, and user_regs->ret updating ptregs is
overwritten immediately with stop_pc, which this patch fixes.
Reported-by: Anton Kolesov <akolesov@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arc/kernel/ptrace.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index c6a81c58d0f3..0851604bb9cd 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c @@ -92,7 +92,7 @@ static int genregs_set(struct task_struct *target, REG_IN_CHUNK(scratch, callee, ptregs); /* pt_regs[bta..orig_r8] */ REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */ REG_IGNORE_ONE(efa); /* efa update invalid */ - REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */ + REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */ return ret; } |