From 2678fefedbbc03a3ae6f5c254791bf147d6c52fd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 1 May 2008 03:30:22 -0700 Subject: sparc64: Fix syscall restart, for real... The change I put into copy_thread() just papered over the real problem. When we are looking to see if we should do a syscall restart, when deliverying a signal, we should only interpret the syscall return value as an error if the carry condition code(s) are set. Otherwise it's a success return. Also, sigreturn paths should do a pt_regs_clear_trap_type(). It turns out that doing a syscall restart when returning from a fork() does and should happen, from time to time. Even if copy_thread() returns success, copy_process() can still unwind and signal -ERESTARTNOINTR in the parent. Signed-off-by: David S. Miller --- arch/sparc64/kernel/signal32.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/sparc64/kernel/signal32.c') diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 91f8d0826db1..9415d2c918c5 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); -- cgit v1.2.3