Commit 69a33147 authored by Kaz Kojima's avatar Kaz Kojima Committed by Paul Mundt

sh: Fix restartable syscall arg5 clobbering.

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: default avatarKaz Kojima <kkojima@rr.iij4u.or.jp>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 188e1f81
...@@ -481,7 +481,7 @@ give_sigsegv: ...@@ -481,7 +481,7 @@ give_sigsegv:
static int static int
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, 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; int ret;
...@@ -500,6 +500,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -500,6 +500,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
} }
/* fallthrough */ /* fallthrough */
case -ERESTARTNOINTR: case -ERESTARTNOINTR:
regs->regs[0] = save_r0;
regs->pc -= instruction_size( regs->pc -= instruction_size(
ctrl_inw(regs->pc - 4)); ctrl_inw(regs->pc - 4));
break; break;
...@@ -583,7 +584,8 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) ...@@ -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); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* 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 /* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame, * sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply * and will be restored by sigreturn, so we can simply
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment