aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh64/kernel/entry.S4
-rw-r--r--arch/sh64/kernel/signal.c33
-rw-r--r--include/asm-sh64/thread_info.h6
3 files changed, 37 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}
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h
index 1f825cb163c3..f6d5117c53af 100644
--- a/include/asm-sh64/thread_info.h
+++ b/include/asm-sh64/thread_info.h
@@ -78,7 +78,13 @@ static inline struct thread_info *current_thread_info(void)
78#define TIF_SIGPENDING 2 /* signal pending */ 78#define TIF_SIGPENDING 2 /* signal pending */
79#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 79#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
80#define TIF_MEMDIE 4 80#define TIF_MEMDIE 4
81#define TIF_RESTORE_SIGMASK 5 /* Restore signal mask in do_signal */
81 82
83#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
84#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
85#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
86#define _TIF_MEMDIE (1 << TIF_MEMDIE)
87#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
82 88
83#endif /* __KERNEL__ */ 89#endif /* __KERNEL__ */
84 90