diff options
Diffstat (limited to 'arch/avr32')
-rw-r--r-- | arch/avr32/kernel/entry-avr32b.S | 4 | ||||
-rw-r--r-- | arch/avr32/kernel/signal.c | 41 |
2 files changed, 15 insertions, 30 deletions
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 5e6beb2597a8..df2884181313 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S | |||
@@ -281,7 +281,7 @@ syscall_exit_work: | |||
281 | ld.w r1, r0[TI_flags] | 281 | ld.w r1, r0[TI_flags] |
282 | rjmp 1b | 282 | rjmp 1b |
283 | 283 | ||
284 | 2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME | 284 | 2: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME |
285 | tst r1, r2 | 285 | tst r1, r2 |
286 | breq 3f | 286 | breq 3f |
287 | unmask_interrupts | 287 | unmask_interrupts |
@@ -587,7 +587,7 @@ fault_exit_work: | |||
587 | ld.w r1, r0[TI_flags] | 587 | ld.w r1, r0[TI_flags] |
588 | rjmp fault_exit_work | 588 | rjmp fault_exit_work |
589 | 589 | ||
590 | 1: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME | 590 | 1: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME |
591 | tst r1, r2 | 591 | tst r1, r2 |
592 | breq 2f | 592 | breq 2f |
593 | unmask_interrupts | 593 | unmask_interrupts |
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c index e7595ef74f51..c140f9b41dce 100644 --- a/arch/avr32/kernel/signal.c +++ b/arch/avr32/kernel/signal.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <asm/ucontext.h> | 22 | #include <asm/ucontext.h> |
23 | #include <asm/syscalls.h> | 23 | #include <asm/syscalls.h> |
24 | 24 | ||
25 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
26 | |||
27 | asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 25 | asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
28 | struct pt_regs *regs) | 26 | struct pt_regs *regs) |
29 | { | 27 | { |
@@ -89,7 +87,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) | |||
89 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 87 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
90 | goto badframe; | 88 | goto badframe; |
91 | 89 | ||
92 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
93 | set_current_blocked(&set); | 90 | set_current_blocked(&set); |
94 | 91 | ||
95 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) | 92 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
@@ -224,30 +221,27 @@ static inline void setup_syscall_restart(struct pt_regs *regs) | |||
224 | 221 | ||
225 | static inline void | 222 | static inline void |
226 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 223 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, |
227 | sigset_t *oldset, struct pt_regs *regs, int syscall) | 224 | struct pt_regs *regs, int syscall) |
228 | { | 225 | { |
229 | int ret; | 226 | int ret; |
230 | 227 | ||
231 | /* | 228 | /* |
232 | * Set up the stack frame | 229 | * Set up the stack frame |
233 | */ | 230 | */ |
234 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 231 | ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); |
235 | 232 | ||
236 | /* | 233 | /* |
237 | * Check that the resulting registers are sane | 234 | * Check that the resulting registers are sane |
238 | */ | 235 | */ |
239 | ret |= !valid_user_regs(regs); | 236 | ret |= !valid_user_regs(regs); |
240 | 237 | ||
241 | if (ret != 0) { | ||
242 | force_sigsegv(sig, current); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | /* | 238 | /* |
247 | * Block the signal if we were successful. | 239 | * Block the signal if we were successful. |
248 | */ | 240 | */ |
249 | block_sigmask(ka, sig); | 241 | if (ret != 0) |
250 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 242 | force_sigsegv(sig, current); |
243 | else | ||
244 | signal_delivered(sig, info, ka, regs, 0); | ||
251 | } | 245 | } |
252 | 246 | ||
253 | /* | 247 | /* |
@@ -255,7 +249,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
255 | * doesn't want to handle. Thus you cannot kill init even with a | 249 | * doesn't want to handle. Thus you cannot kill init even with a |
256 | * SIGKILL even by mistake. | 250 | * SIGKILL even by mistake. |
257 | */ | 251 | */ |
258 | int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall) | 252 | static void do_signal(struct pt_regs *regs, int syscall) |
259 | { | 253 | { |
260 | siginfo_t info; | 254 | siginfo_t info; |
261 | int signr; | 255 | int signr; |
@@ -267,12 +261,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall) | |||
267 | * without doing anything if so. | 261 | * without doing anything if so. |
268 | */ | 262 | */ |
269 | if (!user_mode(regs)) | 263 | if (!user_mode(regs)) |
270 | return 0; | 264 | return; |
271 | |||
272 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
273 | oldset = ¤t->saved_sigmask; | ||
274 | else if (!oldset) | ||
275 | oldset = ¤t->blocked; | ||
276 | 265 | ||
277 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 266 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
278 | if (syscall) { | 267 | if (syscall) { |
@@ -297,15 +286,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall) | |||
297 | 286 | ||
298 | if (signr == 0) { | 287 | if (signr == 0) { |
299 | /* No signal to deliver -- put the saved sigmask back */ | 288 | /* No signal to deliver -- put the saved sigmask back */ |
300 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 289 | restore_saved_sigmask(); |
301 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 290 | return; |
302 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
303 | } | ||
304 | return 0; | ||
305 | } | 291 | } |
306 | 292 | ||
307 | handle_signal(signr, &ka, &info, oldset, regs, syscall); | 293 | handle_signal(signr, &ka, &info, regs, syscall); |
308 | return 1; | ||
309 | } | 294 | } |
310 | 295 | ||
311 | asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) | 296 | asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) |
@@ -315,8 +300,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) | |||
315 | if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR) | 300 | if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR) |
316 | syscall = 1; | 301 | syscall = 1; |
317 | 302 | ||
318 | if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 303 | if (ti->flags & _TIF_SIGPENDING)) |
319 | do_signal(regs, ¤t->blocked, syscall); | 304 | do_signal(regs, syscall); |
320 | 305 | ||
321 | if (ti->flags & _TIF_NOTIFY_RESUME) { | 306 | if (ti->flags & _TIF_NOTIFY_RESUME) { |
322 | clear_thread_flag(TIF_NOTIFY_RESUME); | 307 | clear_thread_flag(TIF_NOTIFY_RESUME); |