aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh64
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-05-13 20:12:39 -0400
committerPaul Mundt <lethal@linux-sh.org>2007-05-13 20:12:39 -0400
commitc18fe9a0467afaec7de05ec76cd994ae7c866760 (patch)
tree4f469753ff8829c50bd26b6be32526824040c508 /arch/sh64
parent599c26d32950c33bdd2a5ac6939bfe15ecf057e0 (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')
-rw-r--r--arch/sh64/kernel/entry.S4
-rw-r--r--arch/sh64/kernel/signal.c33
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 = &current->saved_sigmask;
703 else if (!oldset)
702 oldset = &current->blocked; 704 oldset = &current->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, &current->saved_sigmask, NULL);
747 }
748
724 return 0; 749 return 0;
725} 750}