aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/signal32.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-05-15 03:34:44 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-15 03:34:44 -0400
commit63fe46da9c380b3f2bbdf3765044649517cc717c (patch)
tree9478c1aca1d692b408955aea20c9cd9a37e589c0 /arch/sparc64/kernel/signal32.c
parent99dd1a2b8347ac2ae802300b7862f6f7bcf17139 (diff)
parent066b2118976e6e7cc50eed39e2747c75343a23c4 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl-4965-rs.c drivers/net/wireless/rt2x00/rt61pci.c
Diffstat (limited to 'arch/sparc64/kernel/signal32.c')
-rw-r--r--arch/sparc64/kernel/signal32.c57
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 */
754void do_signal32(sigset_t *oldset, struct pt_regs * regs, 770void 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, &current->saved_sigmask, NULL); 820 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
798 } 821 }
799} 822}