diff options
Diffstat (limited to 'arch/sparc/kernel/signal_32.c')
-rw-r--r-- | arch/sparc/kernel/signal_32.c | 39 |
1 files changed, 8 insertions, 31 deletions
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 6b42e8622d12..68f9c8650af4 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c | |||
@@ -29,8 +29,6 @@ | |||
29 | 29 | ||
30 | #include "sigutil.h" | 30 | #include "sigutil.h" |
31 | 31 | ||
32 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
33 | |||
34 | extern void fpsave(unsigned long *fpregs, unsigned long *fsr, | 32 | extern void fpsave(unsigned long *fpregs, unsigned long *fsr, |
35 | void *fpqueue, unsigned long *fpqdepth); | 33 | void *fpqueue, unsigned long *fpqdepth); |
36 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); | 34 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); |
@@ -130,7 +128,6 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) | |||
130 | if (err) | 128 | if (err) |
131 | goto segv_and_exit; | 129 | goto segv_and_exit; |
132 | 130 | ||
133 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
134 | set_current_blocked(&set); | 131 | set_current_blocked(&set); |
135 | return; | 132 | return; |
136 | 133 | ||
@@ -197,7 +194,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) | |||
197 | goto segv; | 194 | goto segv; |
198 | } | 195 | } |
199 | 196 | ||
200 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
201 | set_current_blocked(&set); | 197 | set_current_blocked(&set); |
202 | return; | 198 | return; |
203 | segv: | 199 | segv: |
@@ -449,10 +445,11 @@ sigsegv: | |||
449 | return -EFAULT; | 445 | return -EFAULT; |
450 | } | 446 | } |
451 | 447 | ||
452 | static inline int | 448 | static inline void |
453 | handle_signal(unsigned long signr, struct k_sigaction *ka, | 449 | handle_signal(unsigned long signr, struct k_sigaction *ka, |
454 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) | 450 | siginfo_t *info, struct pt_regs *regs) |
455 | { | 451 | { |
452 | sigset_t *oldset = sigmask_to_save(); | ||
456 | int err; | 453 | int err; |
457 | 454 | ||
458 | if (ka->sa.sa_flags & SA_SIGINFO) | 455 | if (ka->sa.sa_flags & SA_SIGINFO) |
@@ -461,12 +458,9 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
461 | err = setup_frame(ka, regs, signr, oldset); | 458 | err = setup_frame(ka, regs, signr, oldset); |
462 | 459 | ||
463 | if (err) | 460 | if (err) |
464 | return err; | 461 | return; |
465 | |||
466 | block_sigmask(ka, signr); | ||
467 | tracehook_signal_handler(signr, info, ka, regs, 0); | ||
468 | 462 | ||
469 | return 0; | 463 | signal_delivered(signr, info, ka, regs, 0); |
470 | } | 464 | } |
471 | 465 | ||
472 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 466 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
@@ -498,7 +492,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
498 | { | 492 | { |
499 | struct k_sigaction ka; | 493 | struct k_sigaction ka; |
500 | int restart_syscall; | 494 | int restart_syscall; |
501 | sigset_t *oldset; | ||
502 | siginfo_t info; | 495 | siginfo_t info; |
503 | int signr; | 496 | int signr; |
504 | 497 | ||
@@ -523,11 +516,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
523 | if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) | 516 | if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) |
524 | regs->u_regs[UREG_G6] = orig_i0; | 517 | regs->u_regs[UREG_G6] = orig_i0; |
525 | 518 | ||
526 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
527 | oldset = ¤t->saved_sigmask; | ||
528 | else | ||
529 | oldset = ¤t->blocked; | ||
530 | |||
531 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 519 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
532 | 520 | ||
533 | /* If the debugger messes with the program counter, it clears | 521 | /* If the debugger messes with the program counter, it clears |
@@ -544,15 +532,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
544 | if (signr > 0) { | 532 | if (signr > 0) { |
545 | if (restart_syscall) | 533 | if (restart_syscall) |
546 | syscall_restart(orig_i0, regs, &ka.sa); | 534 | syscall_restart(orig_i0, regs, &ka.sa); |
547 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { | 535 | handle_signal(signr, &ka, &info, regs); |
548 | /* a signal was successfully delivered; the saved | ||
549 | * sigmask will have been stored in the signal frame, | ||
550 | * and will be restored by sigreturn, so we can simply | ||
551 | * clear the TIF_RESTORE_SIGMASK flag. | ||
552 | */ | ||
553 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
554 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
555 | } | ||
556 | return; | 536 | return; |
557 | } | 537 | } |
558 | if (restart_syscall && | 538 | if (restart_syscall && |
@@ -576,16 +556,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
576 | /* if there's no signal to deliver, we just put the saved sigmask | 556 | /* if there's no signal to deliver, we just put the saved sigmask |
577 | * back | 557 | * back |
578 | */ | 558 | */ |
579 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 559 | restore_saved_sigmask(); |
580 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
581 | set_current_blocked(¤t->saved_sigmask); | ||
582 | } | ||
583 | } | 560 | } |
584 | 561 | ||
585 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, | 562 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, |
586 | unsigned long thread_info_flags) | 563 | unsigned long thread_info_flags) |
587 | { | 564 | { |
588 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 565 | if (thread_info_flags & _TIF_SIGPENDING) |
589 | do_signal(regs, orig_i0); | 566 | do_signal(regs, orig_i0); |
590 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 567 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
591 | clear_thread_flag(TIF_NOTIFY_RESUME); | 568 | clear_thread_flag(TIF_NOTIFY_RESUME); |