diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-05-13 20:12:39 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-05-13 20:12:39 -0400 |
commit | c18fe9a0467afaec7de05ec76cd994ae7c866760 (patch) | |
tree | 4f469753ff8829c50bd26b6be32526824040c508 /arch/sh64/kernel | |
parent | 599c26d32950c33bdd2a5ac6939bfe15ecf057e0 (diff) |
sh64: ppoll/pselect6() and restartable syscalls.
This patch was hanging around for some time while we were waiting
for the compiler situation to improve.. now that all is well again,
finally merge it.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh64/kernel')
-rw-r--r-- | arch/sh64/kernel/entry.S | 4 | ||||
-rw-r--r-- | arch/sh64/kernel/signal.c | 33 |
2 files changed, 31 insertions, 6 deletions
diff --git a/arch/sh64/kernel/entry.S b/arch/sh64/kernel/entry.S index 40d45346248d..7013fcb6665c 100644 --- a/arch/sh64/kernel/entry.S +++ b/arch/sh64/kernel/entry.S | |||
@@ -947,14 +947,14 @@ ret_with_reschedule: | |||
947 | ! FIXME:!!! | 947 | ! FIXME:!!! |
948 | ! no handling of TIF_SYSCALL_TRACE yet!! | 948 | ! no handling of TIF_SYSCALL_TRACE yet!! |
949 | 949 | ||
950 | movi (1 << TIF_NEED_RESCHED), r8 | 950 | movi _TIF_NEED_RESCHED, r8 |
951 | and r8, r7, r8 | 951 | and r8, r7, r8 |
952 | pta work_resched, tr0 | 952 | pta work_resched, tr0 |
953 | bne r8, ZERO, tr0 | 953 | bne r8, ZERO, tr0 |
954 | 954 | ||
955 | pta restore_all, tr1 | 955 | pta restore_all, tr1 |
956 | 956 | ||
957 | movi (1 << TIF_SIGPENDING), r8 | 957 | movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8 |
958 | and r8, r7, r8 | 958 | and r8, r7, r8 |
959 | pta work_notifysig, tr0 | 959 | pta work_notifysig, tr0 |
960 | bne r8, ZERO, tr0 | 960 | bne r8, ZERO, tr0 |
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c index b76bdfa473d6..c8525ade0564 100644 --- a/arch/sh64/kernel/signal.c +++ b/arch/sh64/kernel/signal.c | |||
@@ -698,7 +698,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
698 | if (try_to_freeze()) | 698 | if (try_to_freeze()) |
699 | goto no_signal; | 699 | goto no_signal; |
700 | 700 | ||
701 | if (!oldset) | 701 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
702 | oldset = ¤t->saved_sigmask; | ||
703 | else if (!oldset) | ||
702 | oldset = ¤t->blocked; | 704 | oldset = ¤t->blocked; |
703 | 705 | ||
704 | signr = get_signal_to_deliver(&info, &ka, regs, 0); | 706 | signr = get_signal_to_deliver(&info, &ka, regs, 0); |
@@ -706,6 +708,15 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
706 | if (signr > 0) { | 708 | if (signr > 0) { |
707 | /* Whee! Actually deliver the signal. */ | 709 | /* Whee! Actually deliver the signal. */ |
708 | handle_signal(signr, &info, &ka, oldset, regs); | 710 | handle_signal(signr, &info, &ka, oldset, regs); |
711 | |||
712 | /* | ||
713 | * If a signal was successfully delivered, the saved sigmask | ||
714 | * is in its frame, and we can clear the TIF_RESTORE_SIGMASK | ||
715 | * flag. | ||
716 | */ | ||
717 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
718 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
719 | |||
709 | return 1; | 720 | return 1; |
710 | } | 721 | } |
711 | 722 | ||
@@ -713,13 +724,27 @@ no_signal: | |||
713 | /* Did we come from a system call? */ | 724 | /* Did we come from a system call? */ |
714 | if (regs->syscall_nr >= 0) { | 725 | if (regs->syscall_nr >= 0) { |
715 | /* Restart the system call - no handlers present */ | 726 | /* Restart the system call - no handlers present */ |
716 | if (regs->regs[REG_RET] == -ERESTARTNOHAND || | 727 | switch (regs->regs[REG_RET]) { |
717 | regs->regs[REG_RET] == -ERESTARTSYS || | 728 | case -ERESTARTNOHAND: |
718 | regs->regs[REG_RET] == -ERESTARTNOINTR) { | 729 | case -ERESTARTSYS: |
730 | case -ERESTARTNOINTR: | ||
719 | /* Decode Syscall # */ | 731 | /* Decode Syscall # */ |
720 | regs->regs[REG_RET] = regs->syscall_nr; | 732 | regs->regs[REG_RET] = regs->syscall_nr; |
721 | regs->pc -= 4; | 733 | regs->pc -= 4; |
734 | break; | ||
735 | |||
736 | case -ERESTART_RESTARTBLOCK: | ||
737 | regs->regs[REG_RET] = __NR_restart_syscall; | ||
738 | regs->pc -= 4; | ||
739 | break; | ||
722 | } | 740 | } |
723 | } | 741 | } |
742 | |||
743 | /* No signal to deliver -- put the saved sigmask back */ | ||
744 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
745 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
746 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
747 | } | ||
748 | |||
724 | return 0; | 749 | return 0; |
725 | } | 750 | } |