aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/signal.c')
-rw-r--r--arch/sparc64/kernel/signal.c102
1 files changed, 50 insertions, 52 deletions
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 45d6bf632daa..6e4dc67d16af 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -247,7 +247,9 @@ static long _sigpause_common(old_sigset_t set)
247 247
248 current->state = TASK_INTERRUPTIBLE; 248 current->state = TASK_INTERRUPTIBLE;
249 schedule(); 249 schedule();
250 set_thread_flag(TIF_RESTORE_SIGMASK); 250
251 set_restore_sigmask();
252
251 return -ERESTARTNOHAND; 253 return -ERESTARTNOHAND;
252} 254}
253 255
@@ -333,7 +335,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
333 regs->tnpc = tnpc; 335 regs->tnpc = tnpc;
334 336
335 /* Prevent syscall restart. */ 337 /* Prevent syscall restart. */
336 pt_regs_clear_trap_type(regs); 338 pt_regs_clear_syscall(regs);
337 339
338 sigdelsetmask(&set, ~_BLOCKABLE); 340 sigdelsetmask(&set, ~_BLOCKABLE);
339 spin_lock_irq(&current->sighand->siglock); 341 spin_lock_irq(&current->sighand->siglock);
@@ -376,16 +378,29 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
376 378
377static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) 379static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
378{ 380{
379 unsigned long sp; 381 unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
380 382
381 sp = regs->u_regs[UREG_FP] + STACK_BIAS; 383 /*
384 * If we are on the alternate signal stack and would overflow it, don't.
385 * Return an always-bogus address instead so we will die with SIGSEGV.
386 */
387 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
388 return (void __user *) -1L;
382 389
383 /* This is the X/Open sanctioned signal stack switching. */ 390 /* This is the X/Open sanctioned signal stack switching. */
384 if (ka->sa.sa_flags & SA_ONSTACK) { 391 if (ka->sa.sa_flags & SA_ONSTACK) {
385 if (!on_sig_stack(sp) && 392 if (sas_ss_flags(sp) == 0)
386 !((current->sas_ss_sp + current->sas_ss_size) & 7))
387 sp = current->sas_ss_sp + current->sas_ss_size; 393 sp = current->sas_ss_sp + current->sas_ss_size;
388 } 394 }
395
396 /* Always align the stack frame. This handles two cases. First,
397 * sigaltstack need not be mindful of platform specific stack
398 * alignment. Second, if we took this signal because the stack
399 * is not aligned properly, we'd like to take the signal cleanly
400 * and report that.
401 */
402 sp &= ~7UL;
403
389 return (void __user *)(sp - framesize); 404 return (void __user *)(sp - framesize);
390} 405}
391 406
@@ -486,7 +501,7 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
486} 501}
487 502
488static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, 503static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
489 struct sigaction *sa) 504 struct sigaction *sa)
490{ 505{
491 switch (regs->u_regs[UREG_I0]) { 506 switch (regs->u_regs[UREG_I0]) {
492 case ERESTART_RESTARTBLOCK: 507 case ERESTART_RESTARTBLOCK:
@@ -512,21 +527,19 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
512 */ 527 */
513static void do_signal(struct pt_regs *regs, unsigned long orig_i0) 528static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
514{ 529{
515 struct signal_deliver_cookie cookie;
516 struct k_sigaction ka; 530 struct k_sigaction ka;
531 int restart_syscall;
517 sigset_t *oldset; 532 sigset_t *oldset;
518 siginfo_t info; 533 siginfo_t info;
519 int signr; 534 int signr;
520 535
521 if (pt_regs_is_syscall(regs) && 536 if (pt_regs_is_syscall(regs) &&
522 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { 537 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
523 pt_regs_clear_trap_type(regs); 538 restart_syscall = 1;
524 cookie.restart_syscall = 1;
525 } else 539 } else
526 cookie.restart_syscall = 0; 540 restart_syscall = 0;
527 cookie.orig_i0 = orig_i0;
528 541
529 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 542 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
530 oldset = &current->saved_sigmask; 543 oldset = &current->saved_sigmask;
531 else 544 else
532 oldset = &current->blocked; 545 oldset = &current->blocked;
@@ -534,77 +547,62 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
534#ifdef CONFIG_COMPAT 547#ifdef CONFIG_COMPAT
535 if (test_thread_flag(TIF_32BIT)) { 548 if (test_thread_flag(TIF_32BIT)) {
536 extern void do_signal32(sigset_t *, struct pt_regs *, 549 extern void do_signal32(sigset_t *, struct pt_regs *,
537 struct signal_deliver_cookie *); 550 int restart_syscall,
538 do_signal32(oldset, regs, &cookie); 551 unsigned long orig_i0);
552 do_signal32(oldset, regs, restart_syscall, orig_i0);
539 return; 553 return;
540 } 554 }
541#endif 555#endif
542 556
543 signr = get_signal_to_deliver(&info, &ka, regs, &cookie); 557 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
558
559 /* If the debugger messes with the program counter, it clears
560 * the software "in syscall" bit, directing us to not perform
561 * a syscall restart.
562 */
563 if (restart_syscall && !pt_regs_is_syscall(regs))
564 restart_syscall = 0;
565
544 if (signr > 0) { 566 if (signr > 0) {
545 if (cookie.restart_syscall) 567 if (restart_syscall)
546 syscall_restart(cookie.orig_i0, regs, &ka.sa); 568 syscall_restart(orig_i0, regs, &ka.sa);
547 handle_signal(signr, &ka, &info, oldset, regs); 569 handle_signal(signr, &ka, &info, oldset, regs);
548 570
549 /* a signal was successfully delivered; the saved 571 /* A signal was successfully delivered; the saved
550 * sigmask will have been stored in the signal frame, 572 * sigmask will have been stored in the signal frame,
551 * and will be restored by sigreturn, so we can simply 573 * and will be restored by sigreturn, so we can simply
552 * clear the TIF_RESTORE_SIGMASK flag. 574 * clear the TS_RESTORE_SIGMASK flag.
553 */ 575 */
554 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 576 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
555 clear_thread_flag(TIF_RESTORE_SIGMASK);
556 return; 577 return;
557 } 578 }
558 if (cookie.restart_syscall && 579 if (restart_syscall &&
559 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 580 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
560 regs->u_regs[UREG_I0] == ERESTARTSYS || 581 regs->u_regs[UREG_I0] == ERESTARTSYS ||
561 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { 582 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
562 /* replay the system call when we are done */ 583 /* replay the system call when we are done */
563 regs->u_regs[UREG_I0] = cookie.orig_i0; 584 regs->u_regs[UREG_I0] = orig_i0;
564 regs->tpc -= 4; 585 regs->tpc -= 4;
565 regs->tnpc -= 4; 586 regs->tnpc -= 4;
566 } 587 }
567 if (cookie.restart_syscall && 588 if (restart_syscall &&
568 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { 589 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
569 regs->u_regs[UREG_G1] = __NR_restart_syscall; 590 regs->u_regs[UREG_G1] = __NR_restart_syscall;
570 regs->tpc -= 4; 591 regs->tpc -= 4;
571 regs->tnpc -= 4; 592 regs->tnpc -= 4;
572 } 593 }
573 594
574 /* if there's no signal to deliver, we just put the saved sigmask 595 /* If there's no signal to deliver, we just put the saved sigmask
575 * back 596 * back
576 */ 597 */
577 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 598 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
578 clear_thread_flag(TIF_RESTORE_SIGMASK); 599 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
579 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 600 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
580 } 601 }
581} 602}
582 603
583void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) 604void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
584{ 605{
585 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 606 if (thread_info_flags & _TIF_SIGPENDING)
586 do_signal(regs, orig_i0); 607 do_signal(regs, orig_i0);
587} 608}
588
589void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
590{
591 struct signal_deliver_cookie *cp = cookie;
592
593 if (cp->restart_syscall &&
594 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
595 regs->u_regs[UREG_I0] == ERESTARTSYS ||
596 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
597 /* replay the system call when we are done */
598 regs->u_regs[UREG_I0] = cp->orig_i0;
599 regs->tpc -= 4;
600 regs->tnpc -= 4;
601 cp->restart_syscall = 0;
602 }
603 if (cp->restart_syscall &&
604 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
605 regs->u_regs[UREG_G1] = __NR_restart_syscall;
606 regs->tpc -= 4;
607 regs->tnpc -= 4;
608 cp->restart_syscall = 0;
609 }
610}