diff options
-rw-r--r-- | arch/sh64/kernel/entry.S | 4 | ||||
-rw-r--r-- | arch/sh64/kernel/signal.c | 33 | ||||
-rw-r--r-- | include/asm-sh64/thread_info.h | 6 |
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 = ¤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 | } |
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 | ||