diff options
Diffstat (limited to 'arch/sparc64/kernel/signal32.c')
-rw-r--r-- | arch/sparc64/kernel/signal32.c | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 9415d2c918c5..97cdd1bf4a10 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -269,7 +269,7 @@ void do_sigreturn32(struct pt_regs *regs) | |||
269 | regs->tstate |= psr_to_tstate_icc(psr); | 269 | regs->tstate |= psr_to_tstate_icc(psr); |
270 | 270 | ||
271 | /* Prevent syscall restart. */ | 271 | /* Prevent syscall restart. */ |
272 | pt_regs_clear_trap_type(regs); | 272 | pt_regs_clear_syscall(regs); |
273 | 273 | ||
274 | err |= __get_user(fpu_save, &sf->fpu_save); | 274 | err |= __get_user(fpu_save, &sf->fpu_save); |
275 | if (fpu_save) | 275 | if (fpu_save) |
@@ -355,7 +355,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) | |||
355 | regs->tstate |= psr_to_tstate_icc(psr); | 355 | regs->tstate |= psr_to_tstate_icc(psr); |
356 | 356 | ||
357 | /* Prevent syscall restart. */ | 357 | /* Prevent syscall restart. */ |
358 | pt_regs_clear_trap_type(regs); | 358 | pt_regs_clear_syscall(regs); |
359 | 359 | ||
360 | err |= __get_user(fpu_save, &sf->fpu_save); | 360 | err |= __get_user(fpu_save, &sf->fpu_save); |
361 | if (fpu_save) | 361 | if (fpu_save) |
@@ -406,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns | |||
406 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; | 406 | regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; |
407 | sp = regs->u_regs[UREG_FP]; | 407 | sp = regs->u_regs[UREG_FP]; |
408 | 408 | ||
409 | /* | ||
410 | * If we are on the alternate signal stack and would overflow it, don't. | ||
411 | * Return an always-bogus address instead so we will die with SIGSEGV. | ||
412 | */ | ||
413 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) | ||
414 | return (void __user *) -1L; | ||
415 | |||
409 | /* This is the X/Open sanctioned signal stack switching. */ | 416 | /* This is the X/Open sanctioned signal stack switching. */ |
410 | if (sa->sa_flags & SA_ONSTACK) { | 417 | if (sa->sa_flags & SA_ONSTACK) { |
411 | if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) | 418 | if (sas_ss_flags(sp) == 0) |
412 | sp = current->sas_ss_sp + current->sas_ss_size; | 419 | sp = current->sas_ss_sp + current->sas_ss_size; |
413 | } | 420 | } |
421 | |||
422 | /* Always align the stack frame. This handles two cases. First, | ||
423 | * sigaltstack need not be mindful of platform specific stack | ||
424 | * alignment. Second, if we took this signal because the stack | ||
425 | * is not aligned properly, we'd like to take the signal cleanly | ||
426 | * and report that. | ||
427 | */ | ||
428 | sp &= ~7UL; | ||
429 | |||
414 | return (void __user *)(sp - framesize); | 430 | return (void __user *)(sp - framesize); |
415 | } | 431 | } |
416 | 432 | ||
@@ -752,48 +768,55 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs | |||
752 | * mistake. | 768 | * mistake. |
753 | */ | 769 | */ |
754 | void do_signal32(sigset_t *oldset, struct pt_regs * regs, | 770 | void do_signal32(sigset_t *oldset, struct pt_regs * regs, |
755 | struct signal_deliver_cookie *cookie) | 771 | int restart_syscall, unsigned long orig_i0) |
756 | { | 772 | { |
757 | struct k_sigaction ka; | 773 | struct k_sigaction ka; |
758 | siginfo_t info; | 774 | siginfo_t info; |
759 | int signr; | 775 | int signr; |
760 | 776 | ||
761 | signr = get_signal_to_deliver(&info, &ka, regs, cookie); | 777 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
778 | |||
779 | /* If the debugger messes with the program counter, it clears | ||
780 | * the "in syscall" bit, directing us to not perform a syscall | ||
781 | * restart. | ||
782 | */ | ||
783 | if (restart_syscall && !pt_regs_is_syscall(regs)) | ||
784 | restart_syscall = 0; | ||
785 | |||
762 | if (signr > 0) { | 786 | if (signr > 0) { |
763 | if (cookie->restart_syscall) | 787 | if (restart_syscall) |
764 | syscall_restart32(cookie->orig_i0, regs, &ka.sa); | 788 | syscall_restart32(orig_i0, regs, &ka.sa); |
765 | handle_signal32(signr, &ka, &info, oldset, regs); | 789 | handle_signal32(signr, &ka, &info, oldset, regs); |
766 | 790 | ||
767 | /* a signal was successfully delivered; the saved | 791 | /* A signal was successfully delivered; the saved |
768 | * sigmask will have been stored in the signal frame, | 792 | * sigmask will have been stored in the signal frame, |
769 | * and will be restored by sigreturn, so we can simply | 793 | * and will be restored by sigreturn, so we can simply |
770 | * clear the TIF_RESTORE_SIGMASK flag. | 794 | * clear the TS_RESTORE_SIGMASK flag. |
771 | */ | 795 | */ |
772 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 796 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
773 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
774 | return; | 797 | return; |
775 | } | 798 | } |
776 | if (cookie->restart_syscall && | 799 | if (restart_syscall && |
777 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || | 800 | (regs->u_regs[UREG_I0] == ERESTARTNOHAND || |
778 | regs->u_regs[UREG_I0] == ERESTARTSYS || | 801 | regs->u_regs[UREG_I0] == ERESTARTSYS || |
779 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { | 802 | regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { |
780 | /* replay the system call when we are done */ | 803 | /* replay the system call when we are done */ |
781 | regs->u_regs[UREG_I0] = cookie->orig_i0; | 804 | regs->u_regs[UREG_I0] = orig_i0; |
782 | regs->tpc -= 4; | 805 | regs->tpc -= 4; |
783 | regs->tnpc -= 4; | 806 | regs->tnpc -= 4; |
784 | } | 807 | } |
785 | if (cookie->restart_syscall && | 808 | if (restart_syscall && |
786 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 809 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
787 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 810 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
788 | regs->tpc -= 4; | 811 | regs->tpc -= 4; |
789 | regs->tnpc -= 4; | 812 | regs->tnpc -= 4; |
790 | } | 813 | } |
791 | 814 | ||
792 | /* if there's no signal to deliver, we just put the saved sigmask | 815 | /* If there's no signal to deliver, we just put the saved sigmask |
793 | * back | 816 | * back |
794 | */ | 817 | */ |
795 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 818 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
796 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 819 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
797 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 820 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
798 | } | 821 | } |
799 | } | 822 | } |