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;
}
}
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 */
break;
default:
+ if (request == PTRACE_SPARC_DETACH)
+ request = PTRACE_DETACH;
ret = compat_ptrace_request(child, request, addr, data);
break;
}
break;
default:
+ if (request == PTRACE_SPARC_DETACH)
+ request = PTRACE_DETACH;
ret = ptrace_request(child, request, addr, data);
break;
}