Skip to content

Commit

Permalink
sh: Fix restartable syscall arg5 clobbering.
Browse files Browse the repository at this point in the history
We use R0 as the 5th argument of syscall.  When the syscall restarts
after signal handling, we should restore the old value of R0.
The attached patch does it. Without this patch, I've experienced random
failures in the situation which signals are issued frequently.

Signed-off-by: Kaz Kojima <kkojima@rr.iij4u.or.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
Kaz Kojima authored and Paul Mundt committed Jun 18, 2007
1 parent 188e1f8 commit 69a3314
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions arch/sh/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,

static int
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
sigset_t *oldset, struct pt_regs *regs, unsigned int save_r0)
{
int ret;

Expand All @@ -500,6 +500,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
}
/* fallthrough */
case -ERESTARTNOINTR:
regs->regs[0] = save_r0;
regs->pc -= instruction_size(
ctrl_inw(regs->pc - 4));
break;
Expand Down Expand Up @@ -583,7 +584,8 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */
if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
if (handle_signal(signr, &ka, &info, oldset, regs, save_r0)
== 0) {
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
Expand Down

0 comments on commit 69a3314

Please sign in to comment.