aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh64
diff options
context:
space:
mode:
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}