diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sh/kernel/entry.S | 2 | ||||
-rw-r--r-- | arch/sh/kernel/signal.c | 16 | ||||
-rw-r--r-- | arch/sh/kernel/syscalls.S | 2 |
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 | ! |
539 | syscall_exit: | 541 | syscall_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 | ||
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; |
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 |
36 | ENTRY(sys_call_table) | 36 | ENTRY(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 |