summaryrefslogtreecommitdiff
path: root/arch/sparc64/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/ptrace.c')
-rw-r--r--arch/sparc64/kernel/ptrace.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index e9fc0aa2da3..f6c9fc92921 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -287,11 +287,11 @@ static int genregs64_set(struct task_struct *target,
32 * sizeof(u64),
33 * sizeof(u64));
if (!ret) {
- /* Only the condition codes can be modified
- * in the %tstate register.
+ /* Only the condition codes and the "in syscall"
+ * state can be modified in the %tstate register.
*/
- tstate &= (TSTATE_ICC | TSTATE_XCC);
- regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
+ tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
regs->tstate |= tstate;
}
}
@@ -657,8 +657,10 @@ static int genregs32_set(struct task_struct *target,
switch (pos) {
case 32: /* PSR */
tstate = regs->tstate;
- tstate &= ~(TSTATE_ICC | TSTATE_XCC);
+ tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
tstate |= psr_to_tstate_icc(reg);
+ if (reg & PSR_SYSCALL)
+ tstate |= TSTATE_SYSCALL;
regs->tstate = tstate;
break;
case 33: /* PC */
@@ -944,6 +946,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
break;
default:
+ if (request == PTRACE_SPARC_DETACH)
+ request = PTRACE_DETACH;
ret = compat_ptrace_request(child, request, addr, data);
break;
}
@@ -1036,6 +1040,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
default:
+ if (request == PTRACE_SPARC_DETACH)
+ request = PTRACE_DETACH;
ret = ptrace_request(child, request, addr, data);
break;
}