static void
handle_signal(unsigned long sig, struct k_sigaction *ka,
	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{
	/* Are we from a system call? */
	if (PT_REGS_SYSCALL (regs)) {
		/* If so, check system call restarting.. */
		switch (regs->gpr[GPR_RVAL]) {
			case -ERESTARTNOHAND:
				regs->gpr[GPR_RVAL] = -EINTR;
				break;

			case -ERESTARTSYS:
				if (!(ka->sa.sa_flags & SA_RESTART)) {
					regs->gpr[GPR_RVAL] = -EINTR;
					break;
				}
			/* fallthrough */
			case -ERESTARTNOINTR:
				regs->gpr[12] = PT_REGS_SYSCALL (regs);
				/* offset of 8 bytes required = 4 for rtbd
				   offset, plus 4 for size of 
					"brki r14,8"
				   instruction. */
				regs->pc -= 8; 
		}

		PT_REGS_SET_SYSCALL (regs, 0);
	}

	/* Set up the stack frame */
	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_rt_frame(sig, ka, info, oldset, regs);
	else
		setup_frame(sig, ka, oldset, regs);

	if (ka->sa.sa_flags & SA_ONESHOT)
		ka->sa.sa_handler = SIG_DFL;

	if (!(ka->sa.sa_flags & SA_NODEFER)) {
		spin_lock_irq(&current->sigmask_lock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		sigaddset(&current->blocked,sig);
		recalc_sigpending(current);
		spin_unlock_irq(&current->sigmask_lock);
	}
}
Exemple #2
0
static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
          sigset_t *oldset,    struct pt_regs * regs)
{
    /* Are we from a system call? */
    if (PT_REGS_SYSCALL (regs)) {
        /* If so, check system call restarting.. */
        switch (regs->gpr[GPR_RVAL]) {
        case -ERESTART_RESTARTBLOCK:
            current_thread_info()->restart_block.fn =
                do_no_restart_syscall;
            /* fall through */
        case -ERESTARTNOHAND:
            regs->gpr[GPR_RVAL] = -EINTR;
            break;

        case -ERESTARTSYS:
            if (!(ka->sa.sa_flags & SA_RESTART)) {
                regs->gpr[GPR_RVAL] = -EINTR;
                break;
            }
            /* fallthrough */
        case -ERESTARTNOINTR:
            regs->gpr[12] = PT_REGS_SYSCALL (regs);
            regs->pc -= 4; /* Size of `trap 0' insn.  */
        }

        PT_REGS_SET_SYSCALL (regs, 0);
    }

    /* Set up the stack frame */
    if (ka->sa.sa_flags & SA_SIGINFO)
        setup_rt_frame(sig, ka, info, oldset, regs);
    else
        setup_frame(sig, ka, oldset, regs);

    spin_lock_irq(&current->sighand->siglock);
    sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
    if (!(ka->sa.sa_flags & SA_NODEFER))
        sigaddset(&current->blocked,sig);
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);
}