diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2007-06-04 09:15:46 +0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-06-14 16:29:57 +0400 |
commit | 912000e73ee8fcb97831b123c9c3a7274b71cab7 (patch) | |
tree | a81fcda0f11cbb4c428ffae9f9f55f12677051fe /arch/powerpc/kernel/ptrace.c | |
parent | 1b6610d6fcb8dc23631cf48f09aa02e6649e379d (diff) | |
download | linux-912000e73ee8fcb97831b123c9c3a7274b71cab7.tar.xz |
[POWERPC] Allow ptrace write to pt_regs trap and orig_r3
This patch allows a ptracer to write to the "trap" and "orig_r3" words
of the pt_regs.
This, along with a subsequent patch to the signal restart code, should
enable gdb to properly handle syscall restarting after executing a separate
function (at least when there's no restart block).
This patch also removes ptrace32.c code toying directly with the registers
and makes it use the ptrace_get/put_reg() accessors for everything so that
the logic for checking what is permitted is in only one place.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index c9c330d35c17..dd4837c4a68a 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -75,10 +75,15 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data) if (task->thread.regs == NULL) return -EIO; - if (regno <= PT_MAX_PUT_REG) { + if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) { if (regno == PT_MSR) data = (data & MSR_DEBUGCHANGE) | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); + /* We prevent mucking around with the reserved area of trap + * which are used internally by the kernel + */ + if (regno == PT_TRAP) + data &= 0xfff0; ((unsigned long *)task->thread.regs)[regno] = data; return 0; } @@ -409,8 +414,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; CHECK_FULL_REGS(child->thread.regs); - if (index == PT_ORIG_R3) - break; if (index < PT_FPR0) { ret = ptrace_put_reg(child, index, data); } else { |