aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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
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')
-rw-r--r--arch/sh/kernel/entry.S2
-rw-r--r--arch/sh/kernel/signal.c16
-rw-r--r--arch/sh/kernel/syscalls.S2
3 files changed, 13 insertions, 7 deletions
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index b087d34dba35..fcbf50d4ee10 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -376,6 +376,7 @@ work_notifysig:
376 bt/s restore_all 376 bt/s restore_all
377 mov r15, r4 377 mov r15, r4
378 mov #0, r5 378 mov #0, r5
379 mov r12, r6 ! set arg2(save_r0)
379 mov.l 2f, r1 380 mov.l 2f, r1
380 mova restore_all, r0 381 mova restore_all, r0
381 jmp @r1 382 jmp @r1
@@ -534,6 +535,7 @@ syscall_call:
534 mov.l @r9, r8 535 mov.l @r9, r8
535 jsr @r8 ! jump to specific syscall handler 536 jsr @r8 ! jump to specific syscall handler
536 nop 537 nop
538 mov.l @(OFF_R0,r15), r12 ! save r0
537 mov.l r0, @(OFF_R0,r15) ! save the return value 539 mov.l r0, @(OFF_R0,r15) ! save the return value
538 ! 540 !
539syscall_exit: 541syscall_exit:
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;
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S
index ada61b0d9a73..ea23b213c77f 100644
--- a/arch/sh/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls.S
@@ -34,7 +34,7 @@
34 34
35 .data 35 .data
36ENTRY(sys_call_table) 36ENTRY(sys_call_table)
37 .long sys_ni_syscall /* 0 - old "setup()" system call*/ 37 .long sys_restart_syscall /* 0 - old "setup()" system call*/
38 .long sys_exit 38 .long sys_exit
39 .long sys_fork 39 .long sys_fork
40 .long sys_read 40 .long sys_read