diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/kernel/process.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal32.c | 6 |
3 files changed, 11 insertions, 7 deletions
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 05601374915..500ac6d483a 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -591,12 +591,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, if (clone_flags & CLONE_SETTLS) t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; - /* We do not want to accidently trigger system call restart - * handling in the new thread. Therefore, clear out the trap - * type, which will make pt_regs_regs_is_syscall() return false. - */ - pt_regs_clear_trap_type(t->kregs); - return 0; } diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index f2d88d8f7a4..45d6bf632da 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -332,6 +332,9 @@ void do_rt_sigreturn(struct pt_regs *regs) regs->tpc = tpc; regs->tnpc = tnpc; + /* Prevent syscall restart. */ + pt_regs_clear_trap_type(regs); + sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; @@ -515,7 +518,8 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) siginfo_t info; int signr; - if (pt_regs_is_syscall(regs)) { + if (pt_regs_is_syscall(regs) && + (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { pt_regs_clear_trap_type(regs); cookie.restart_syscall = 1; } else diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 91f8d0826db..9415d2c918c 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -268,6 +268,9 @@ void do_sigreturn32(struct pt_regs *regs) regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); regs->tstate |= psr_to_tstate_icc(psr); + /* Prevent syscall restart. */ + pt_regs_clear_trap_type(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); @@ -351,6 +354,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); regs->tstate |= psr_to_tstate_icc(psr); + /* Prevent syscall restart. */ + pt_regs_clear_trap_type(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); |