diff options
Diffstat (limited to 'arch/sh/kernel/signal_64.c')
-rw-r--r-- | arch/sh/kernel/signal_64.c | 47 |
1 files changed, 12 insertions, 35 deletions
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index aa6428430842..6b5b3dfe886b 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c | |||
@@ -41,11 +41,9 @@ | |||
41 | 41 | ||
42 | #define DEBUG_SIG 0 | 42 | #define DEBUG_SIG 0 |
43 | 43 | ||
44 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 44 | static void |
45 | |||
46 | static int | ||
47 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 45 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
48 | sigset_t *oldset, struct pt_regs * regs); | 46 | struct pt_regs * regs); |
49 | 47 | ||
50 | static inline void | 48 | static inline void |
51 | handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) | 49 | handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) |
@@ -88,7 +86,6 @@ static void do_signal(struct pt_regs *regs) | |||
88 | siginfo_t info; | 86 | siginfo_t info; |
89 | int signr; | 87 | int signr; |
90 | struct k_sigaction ka; | 88 | struct k_sigaction ka; |
91 | sigset_t *oldset; | ||
92 | 89 | ||
93 | /* | 90 | /* |
94 | * We want the common case to go fast, which | 91 | * We want the common case to go fast, which |
@@ -99,28 +96,13 @@ static void do_signal(struct pt_regs *regs) | |||
99 | if (!user_mode(regs)) | 96 | if (!user_mode(regs)) |
100 | return; | 97 | return; |
101 | 98 | ||
102 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) | ||
103 | oldset = ¤t->saved_sigmask; | ||
104 | else | ||
105 | oldset = ¤t->blocked; | ||
106 | |||
107 | signr = get_signal_to_deliver(&info, &ka, regs, 0); | 99 | signr = get_signal_to_deliver(&info, &ka, regs, 0); |
108 | if (signr > 0) { | 100 | if (signr > 0) { |
109 | handle_syscall_restart(regs, &ka.sa); | 101 | handle_syscall_restart(regs, &ka.sa); |
110 | 102 | ||
111 | /* Whee! Actually deliver the signal. */ | 103 | /* Whee! Actually deliver the signal. */ |
112 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 104 | handle_signal(signr, &info, &ka, regs); |
113 | /* | 105 | return; |
114 | * If a signal was successfully delivered, the | ||
115 | * saved sigmask is in its frame, and we can | ||
116 | * clear the TS_RESTORE_SIGMASK flag. | ||
117 | */ | ||
118 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | ||
119 | |||
120 | tracehook_signal_handler(signr, &info, &ka, regs, | ||
121 | test_thread_flag(TIF_SINGLESTEP)); | ||
122 | return; | ||
123 | } | ||
124 | } | 106 | } |
125 | 107 | ||
126 | /* Did we come from a system call? */ | 108 | /* Did we come from a system call? */ |
@@ -143,12 +125,7 @@ static void do_signal(struct pt_regs *regs) | |||
143 | } | 125 | } |
144 | 126 | ||
145 | /* No signal to deliver -- put the saved sigmask back */ | 127 | /* No signal to deliver -- put the saved sigmask back */ |
146 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { | 128 | restore_saved_sigmask(); |
147 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | ||
148 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
149 | } | ||
150 | |||
151 | return; | ||
152 | } | 129 | } |
153 | 130 | ||
154 | /* | 131 | /* |
@@ -351,7 +328,6 @@ asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3, | |||
351 | sizeof(frame->extramask)))) | 328 | sizeof(frame->extramask)))) |
352 | goto badframe; | 329 | goto badframe; |
353 | 330 | ||
354 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
355 | set_current_blocked(&set); | 331 | set_current_blocked(&set); |
356 | 332 | ||
357 | if (restore_sigcontext(regs, &frame->sc, &ret)) | 333 | if (restore_sigcontext(regs, &frame->sc, &ret)) |
@@ -384,7 +360,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, | |||
384 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 360 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
385 | goto badframe; | 361 | goto badframe; |
386 | 362 | ||
387 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
388 | set_current_blocked(&set); | 363 | set_current_blocked(&set); |
389 | 364 | ||
390 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret)) | 365 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret)) |
@@ -659,10 +634,11 @@ give_sigsegv: | |||
659 | /* | 634 | /* |
660 | * OK, we're invoking a handler | 635 | * OK, we're invoking a handler |
661 | */ | 636 | */ |
662 | static int | 637 | static void |
663 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 638 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
664 | sigset_t *oldset, struct pt_regs * regs) | 639 | struct pt_regs * regs) |
665 | { | 640 | { |
641 | sigset_t *oldset = sigmask_to_save(); | ||
666 | int ret; | 642 | int ret; |
667 | 643 | ||
668 | /* Set up the stack frame */ | 644 | /* Set up the stack frame */ |
@@ -671,10 +647,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
671 | else | 647 | else |
672 | ret = setup_frame(sig, ka, oldset, regs); | 648 | ret = setup_frame(sig, ka, oldset, regs); |
673 | 649 | ||
674 | if (ret == 0) | 650 | if (ret) |
675 | block_sigmask(ka, sig); | 651 | return; |
676 | 652 | ||
677 | return ret; | 653 | signal_delivered(sig, info, ka, regs, |
654 | test_thread_flag(TIF_SINGLESTEP)); | ||
678 | } | 655 | } |
679 | 656 | ||
680 | asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | 657 | asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) |