diff options
Diffstat (limited to 'arch/sh/kernel/signal.c')
-rw-r--r-- | arch/sh/kernel/signal.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index b475c4d2405f..eb6a3b97e46c 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c | |||
@@ -33,7 +33,8 @@ | |||
33 | 33 | ||
34 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 34 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
35 | 35 | ||
36 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); | 36 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, |
37 | unsigned int save_r0); | ||
37 | 38 | ||
38 | /* | 39 | /* |
39 | * Atomically swap in the new signal mask, and wait for a signal. | 40 | * Atomically swap in the new signal mask, and wait for a signal. |
@@ -56,7 +57,7 @@ sys_sigsuspend(old_sigset_t mask, | |||
56 | while (1) { | 57 | while (1) { |
57 | current->state = TASK_INTERRUPTIBLE; | 58 | current->state = TASK_INTERRUPTIBLE; |
58 | schedule(); | 59 | schedule(); |
59 | if (do_signal(®s, &saveset)) | 60 | if (do_signal(®s, &saveset, regs.regs[0])) |
60 | return -EINTR; | 61 | return -EINTR; |
61 | } | 62 | } |
62 | } | 63 | } |
@@ -85,7 +86,7 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, | |||
85 | while (1) { | 86 | while (1) { |
86 | current->state = TASK_INTERRUPTIBLE; | 87 | current->state = TASK_INTERRUPTIBLE; |
87 | schedule(); | 88 | schedule(); |
88 | if (do_signal(®s, &saveset)) | 89 | if (do_signal(®s, &saveset, regs.regs[0])) |
89 | return -EINTR; | 90 | return -EINTR; |
90 | } | 91 | } |
91 | } | 92 | } |
@@ -563,7 +564,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
563 | * the kernel can handle, and then we build all the user-level signal handling | 564 | * the kernel can handle, and then we build all the user-level signal handling |
564 | * stack-frames in one go after that. | 565 | * stack-frames in one go after that. |
565 | */ | 566 | */ |
566 | int do_signal(struct pt_regs *regs, sigset_t *oldset) | 567 | int do_signal(struct pt_regs *regs, sigset_t *oldset, unsigned int save_r0) |
567 | { | 568 | { |
568 | siginfo_t info; | 569 | siginfo_t info; |
569 | int signr; | 570 | int signr; |
@@ -597,9 +598,12 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
597 | /* Restart the system call - no handlers present */ | 598 | /* Restart the system call - no handlers present */ |
598 | if (regs->regs[0] == -ERESTARTNOHAND || | 599 | if (regs->regs[0] == -ERESTARTNOHAND || |
599 | regs->regs[0] == -ERESTARTSYS || | 600 | regs->regs[0] == -ERESTARTSYS || |
600 | regs->regs[0] == -ERESTARTNOINTR || | 601 | regs->regs[0] == -ERESTARTNOINTR) { |
601 | regs->regs[0] == -ERESTART_RESTARTBLOCK) { | 602 | regs->regs[0] = save_r0; |
602 | regs->pc -= 2; | 603 | regs->pc -= 2; |
604 | } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { | ||
605 | regs->pc -= 2; | ||
606 | regs->regs[3] = __NR_restart_syscall; | ||
603 | } | 607 | } |
604 | } | 608 | } |
605 | return 0; | 609 | return 0; |