summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2010-10-28 15:03:30 -0400
committerChris Metcalf <cmetcalf@tilera.com>2010-11-01 15:31:04 -0400
commit34a89d26bdc4ba46a406fa3842239e921c493d44 (patch)
treebbfc0dcd4376f6f6337cc199fa785f53243b36cb
parentd59e609d6568ba5ab23c256f412ac5ec360722c1 (diff)
arch/tile: correct double syscall restart for nested signals
This change is modelled on similar fixes for other architectures. The pt_regs "faultnum" member is set to the trap (fault) number that caused us to enter the kernel, and is INT_SWINT_1 for the syscall software interrupt. We already supported a pseudo value, INT_SWINT_1_SIGRETURN, that we used for the rt_sigreturn syscall; it avoided the case where one signal was handled, then we "tail-called" to another handler. This change avoids the similar case where we start to call one handler, then are preempted into another handler when we start trying to run the first handler. We clear ->faultnum after calling handle_signal(), and to be paranoid also in the case where there was no signal to deliver. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
-rw-r--r--arch/tile/kernel/signal.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index fb28e85ae3a..704ce0bce83 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -330,7 +330,7 @@ void do_signal(struct pt_regs *regs)
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
- return;
+ goto done;
}
/* Did we come from a system call? */
@@ -358,4 +358,8 @@ void do_signal(struct pt_regs *regs)
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
}
+
+done:
+ /* Avoid double syscall restart if there are nested signals. */
+ regs->faultnum = INT_SWINT_1_SIGRETURN;
}