summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-06-04 15:15:46 +1000
committerPaul Mackerras <paulus@samba.org>2007-06-14 22:29:57 +1000
commit912000e73ee8fcb97831b123c9c3a7274b71cab7 (patch)
treea81fcda0f11cbb4c428ffae9f9f55f12677051fe /arch/powerpc/kernel/ptrace.c
parent1b6610d6fcb8dc23631cf48f09aa02e6649e379d (diff)
[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.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index c9c330d35c1..dd4837c4a68 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 {