aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/signal.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-09-27 04:22:49 -0400
committerPaul Mundt <lethal@linux-sh.org>2006-09-27 04:22:49 -0400
commit0b8929354cdeddb17e81bfda903812c9adfd0b67 (patch)
treeff3a450e750752bfde6afe414ee0c1b0eea3ac8e /arch/sh/kernel/signal.c
parente96636ccfa373a00a0ee0558e1971baa7856d8b5 (diff)
sh: __NR_restart_syscall support.
This implements support for __NR_restart_syscall. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/signal.c')
-rw-r--r--arch/sh/kernel/signal.c16
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
36asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 36asmlinkage 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(&regs, &saveset)) 60 if (do_signal(&regs, &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(&regs, &saveset)) 89 if (do_signal(&regs, &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 */
566int do_signal(struct pt_regs *regs, sigset_t *oldset) 567int 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;