예제 #1
0
파일: restore.c 프로젝트: virthub/virthub
int ckpt_restore_sigpending(struct sigpending *sigpending, int shared, ckpt_desc_t desc)
{
    int i;
    ckpt_sigqueue_t queue;
    ckpt_sigpending_t pending;
    struct siginfo *info = &queue.info;

    if (ckpt_read(desc, &pending, sizeof(ckpt_sigpending_t)) != sizeof(ckpt_sigpending_t)) {
        log_err("failed to get sigpending");
        return -EIO;
    }

    for (i = 0; i < pending.count; i++) {
        if (ckpt_read(desc, &queue, sizeof(ckpt_sigqueue_t)) != sizeof(ckpt_sigqueue_t)) {
            log_err("failed to get sigqueue");
            return -EIO;
        }

        if (shared) {
            read_lock((rwlock_t *)TASKLIST_LOCK);
            group_send_sig_info(info->si_signo, info, current);
            read_unlock((rwlock_t *)TASKLIST_LOCK);
        } else
            send_sig_info(info->si_signo, info, current);
    }

    spin_lock_irq(&current->sighand->siglock);
    sigorsets(&sigpending->signal, &sigpending->signal, &pending.signal);
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);
    return 0;
}
예제 #2
0
파일: signal.c 프로젝트: robcore/machinex
/*
 * OK, we're invoking a handler
 */
static int
handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
	      sigset_t *oldset, struct pt_regs *regs)
{
	int ret;

	/* are we from a system call? to see pt_regs->orig_p0 */
	if (regs->orig_p0 >= 0)
		/* If so, check system call restarting.. */
		handle_restart(regs, ka, 1);

	/* set up the stack frame */
	ret = setup_rt_frame(sig, ka, info, oldset, regs);

	if (ret == 0) {
		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);
	}
	return ret;
}
예제 #3
0
/*
 * OK, we're invoking a handler
 */
static void
handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
	      sigset_t *oldset, struct pt_regs *regs)
{
	/* are we from a system call? */
	if (regs->orig_er0 >= 0)
		/* If so, check system call restarting.. */
		handle_restart(regs, ka, 1);

	/* 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->sighand->siglock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		sigaddset(&current->blocked,sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}
}
예제 #4
0
static inline void handle_signal(unsigned long sig, siginfo_t *info,
	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
{
	switch(regs->regs[0]) {
	case ERESTARTNOHAND:
		regs->regs[2] = EINTR;
		break;
	case ERESTARTSYS:
		if(!(ka->sa.sa_flags & SA_RESTART)) {
			regs->regs[2] = EINTR;
			break;
		}
	/* fallthrough */
	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
		regs->cp0_epc -= 8;
	}

	regs->regs[0] = 0;		/* Don't deal with this again.  */

	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_irix_rt_frame(ka, regs, sig, oldset, info);
	else
		setup_irix_frame(ka, regs, sig, oldset);

	if (!(ka->sa.sa_flags & SA_NODEFER)) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		sigaddset(&current->blocked,sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}
}
예제 #5
0
static long
handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset,
	       struct sigscratch *scr)
{
	if (IS_IA32_PROCESS(&scr->pt)) {
		/* send signal to IA-32 process */
		if (!ia32_setup_frame1(sig, ka, info, oldset, &scr->pt))
			return 0;
	} else
		/* send signal to IA-64 process */
		if (!setup_frame(sig, ka, info, oldset, scr))
			return 0;

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

	if (!(ka->sa.sa_flags & SA_NODEFER)) {
		spin_lock_irq(&current->sighand->siglock);
		{
			sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
			sigaddset(&current->blocked, sig);
			recalc_sigpending();
		}
		spin_unlock_irq(&current->sighand->siglock);
	}
	return 1;
}
예제 #6
0
static inline int
handle_signal(unsigned long signr, struct k_sigaction *ka,
	      siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
	int err;

	if (ka->sa.sa_flags & SA_SIGINFO)
		err = setup_rt_frame(ka, regs, signr, oldset, info);
	else
		err = setup_frame(ka, regs, signr, oldset);

	if (err)
		return err;

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

	tracehook_signal_handler(signr, info, ka, regs, 0);

	return 0;
}
예제 #7
0
static void
handle_signal(unsigned long sig, struct k_sigaction *ka,
              siginfo_t *info, sigset_t *oldset,
              struct pt_regs * regs, int syscall)
{
    struct thread_info *thread = current_thread_info();
    struct task_struct *tsk = current;
    int usig = sig;
    int ret;

    /*
     * If we were from a system call, check for system call restarting...
     */
    if (syscall) {
        switch (regs->r5) {
        case -ERESTART_RESTARTBLOCK:
        case -ERESTARTNOHAND:
            regs->r5 = -EINTR;
            break;
        case -ERESTARTSYS:
            if (!(ka->sa.sa_flags & SA_RESTART)) {
                regs->r5 = -EINTR;
                break;
            }
        /* fallthrough */
        case -ERESTARTNOINTR:
            restart_syscall(regs);
        }
    }

    /*
     * translate the signal
     */
    if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
        usig = thread->exec_domain->signal_invmap[usig];

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

    if (ret != 0) {
        force_sigsegv(sig, tsk);
        return;
    }

    /*
     * Block the signal if we were successful.
     */
    spin_lock_irq(&tsk->sighand->siglock);
    sigorsets(&tsk->blocked, &tsk->blocked,
              &ka->sa.sa_mask);
    if (!(ka->sa.sa_flags & SA_NODEFER))
        sigaddset(&tsk->blocked, sig);
    recalc_sigpending();
    spin_unlock_irq(&tsk->sighand->siglock);
}
예제 #8
0
/*
 * OK, we're invoking a handler
 */
static int
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
	      sigset_t *oldset, struct pt_regs *regs, unsigned int save_r0)
{
	int ret;

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

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

	if (ret == 0) {
		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);
	}

	return ret;
}
예제 #9
0
static inline void
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
	      sigset_t *oldset, struct pt_regs *regs, int syscall)
{
	int ret;

	/*
	 * Set up the stack frame
	 */
	ret = setup_rt_frame(sig, ka, info, oldset, regs);

	/*
	 * Check that the resulting registers are sane
	 */
	ret |= !valid_user_regs(regs);

	/*
	 * Block the signal if we were unsuccessful.
	 */
	if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked, &current->blocked,
			  &ka->sa.sa_mask);
		sigaddset(&current->blocked, sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}

	if (ret == 0)
		return;

	force_sigsegv(sig, current);
}
예제 #10
0
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 (regs->tra >= 0) {
		/* If so, check system call restarting.. */
		switch (regs->regs[0]) {
			case -ERESTARTNOHAND:
				regs->regs[0] = -EINTR;
				break;

			case -ERESTARTSYS:
				if (!(ka->sa.sa_flags & SA_RESTART)) {
					regs->regs[0] = -EINTR;
					break;
				}
			/* fallthrough */
			case -ERESTARTNOINTR:
				regs->pc -= 2;
		}
	} else {
		/* gUSA handling */
#ifdef CONFIG_PREEMPT
		unsigned long flags;

		local_irq_save(flags);
#endif
		if (regs->regs[15] >= 0xc0000000) {
			int offset = (int)regs->regs[15];

			/* Reset stack pointer: clear critical region mark */
			regs->regs[15] = regs->regs[1];
			if (regs->pc < regs->regs[0])
				/* Go to rewind point #1 */
				regs->pc = regs->regs[0] + offset - 2;
		}
#ifdef CONFIG_PREEMPT
		local_irq_restore(flags);
#endif
	}

	/* 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->sighand->siglock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		sigaddset(&current->blocked,sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}
}
static int
handle_signal(unsigned long sig, struct k_sigaction *ka,
	      siginfo_t *info, sigset_t *oldset,
	      struct pt_regs * regs, int syscall)
{
	struct thread_info *thread = current_thread_info();
	struct task_struct *tsk = current;
	int usig = sig;
	int ret;

	
	if (syscall) {
		switch (regs->ARM_r0) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->ARM_r0 = -EINTR;
			break;
		case -ERESTARTSYS:
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				regs->ARM_r0 = -EINTR;
				break;
			}
			
		case -ERESTARTNOINTR:
			setup_syscall_restart(regs);
		}
	}

	
	if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
		usig = thread->exec_domain->signal_invmap[usig];

	
	if (ka->sa.sa_flags & SA_SIGINFO)
		ret = setup_rt_frame(usig, ka, info, oldset, regs);
	else
		ret = setup_frame(usig, ka, oldset, regs);

	
	ret |= !valid_user_regs(regs);

	if (ret != 0) {
		force_sigsegv(sig, tsk);
		return ret;
	}

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

	return 0;
}
예제 #12
0
static int
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
	      sigset_t *oldset,	struct pt_regs * regs)
{
	int ret;

	/* Are we from a system call? */
	if (regs->orig_eax >= 0) {
		/* If so, check system call restarting.. */
		switch (regs->eax) {
		        case -ERESTART_RESTARTBLOCK:
			case -ERESTARTNOHAND:
				regs->eax = -EINTR;
				break;

			case -ERESTARTSYS:
				if (!(ka->sa.sa_flags & SA_RESTART)) {
					regs->eax = -EINTR;
					break;
				}
			/* fallthrough */
			case -ERESTARTNOINTR:
				regs->eax = regs->orig_eax;
				regs->eip -= 2;
		}
	}

	/*
	 * If TF is set due to a debugger (PT_DTRACE), clear the TF flag so
	 * that register information in the sigcontext is correct.
	 */
	if (unlikely(regs->eflags & TF_MASK)
	    && likely(current->ptrace & PT_DTRACE)) {
		current->ptrace &= ~PT_DTRACE;
		regs->eflags &= ~TF_MASK;
	}

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

	if (ret == 0) {
		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);
	}

	return ret;
}
예제 #13
0
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals that
 * the kernel can handle, and then we build all the user-level signal handling
 * stack-frames in one go after that.
 */
int do_signal(struct pt_regs *regs, sigset_t *oldset)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;

	if (!oldset)
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);

	/* Are we from a system call? */
	if (regs->syscall >= 0) {
		/* If so, check system call restarting.. */
		switch (regs->areg[2]) {
			case ERESTARTNOHAND:
			case ERESTART_RESTARTBLOCK:
				regs->areg[2] = -EINTR;
				break;

			case ERESTARTSYS:
				if (!(ka.sa.sa_flags & SA_RESTART)) {
					regs->areg[2] = -EINTR;
					break;
				}
			/* fallthrough */
			case ERESTARTNOINTR:
				regs->areg[2] = regs->syscall;
				regs->pc -= 3;
		}
	}

	if (signr == 0)
		return 0;		/* no signals delivered */

	/* Whee!  Actually deliver the signal.  */

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

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

	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, signr);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
	return 1;
}
예제 #14
0
파일: signal.c 프로젝트: ANFS/ANFS-kernel
static int handle_signal(unsigned long sig, siginfo_t *info,
			 struct k_sigaction *ka, sigset_t *oldset,
			 struct pt_regs *regs)
{
	int ret;


	/* Are we from a system call? */
	if (regs->faultnum == INT_SWINT_1) {
		/* If so, check system call restarting.. */
		switch (regs->regs[0]) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->regs[0] = -EINTR;
			break;

		case -ERESTARTSYS:
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				regs->regs[0] = -EINTR;
				break;
			}
			/* fallthrough */
		case -ERESTARTNOINTR:
			/* Reload caller-saves to restore r0..r5 and r10. */
			regs->flags |= PT_FLAGS_CALLER_SAVES;
			regs->regs[0] = regs->orig_r0;
			regs->pc -= 8;
		}
	}

	/* Set up the stack frame */
#ifdef CONFIG_COMPAT
	if (is_compat_task())
		ret = compat_setup_rt_frame(sig, ka, info, oldset, regs);
	else
#endif
		ret = setup_rt_frame(sig, ka, info, oldset, regs);
	if (ret == 0) {
		/* This code is only called from system calls or from
		 * the work_pending path in the return-to-user code, and
		 * either way we can re-enable interrupts unconditionally.
		 */
		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);
	}

	return ret;
}
예제 #15
0
static void handle_signal(unsigned long sig, siginfo_t *info,
		struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
{
	setup_rt_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);
}
예제 #16
0
파일: signal.c 프로젝트: 08opt/linux
/*
 * Setup invocation of signal handler
 */
static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
			 sigset_t *oldset, struct pt_regs *regs)
{
	int rc;

	/*
	 * If we're handling a signal that aborted a system call,
	 * set up the error return value before adding the signal
	 * frame to the stack.
	 */

	if (regs->syscall_nr >= 0) {
		switch (regs->r00) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->r00 = -EINTR;
			break;
		case -ERESTARTSYS:
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				regs->r00 = -EINTR;
				break;
			}
			/* Fall through */
		case -ERESTARTNOINTR:
			regs->r06 = regs->syscall_nr;
			pt_set_elr(regs, pt_elr(regs) - 4);
			regs->r00 = regs->restart_r0;
			break;
		default:
			break;
		}
	}

	/*
	 * Set up the stack frame; not doing the SA_SIGINFO thing.  We
	 * only set up the rt_frame flavor.
	 */
	rc = setup_rt_frame(sig, ka, info, oldset, regs);

	/* If there was an error on setup, no signal was delivered. */
	if (rc)
		return rc;

	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);

	return 0;
}
예제 #17
0
static inline int handle_signal(int canrestart, unsigned long sig,
	siginfo_t *info, struct k_sigaction *ka,
	struct pt_regs *regs)
{
	sigset_t *oldset = sigmask_to_save();
	int ret;

	/* Are we from a system call? */
	if (canrestart) {
		/* If so, check system call restarting.. */
		switch (regs->r10) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			/* ERESTARTNOHAND means that the syscall should
			 * only be restarted if there was no handler for
			 * the signal, and since we only get here if there
			 * is a handler, we don't restart */
			regs->r10 = -EINTR;
			break;
		case -ERESTARTSYS:
			/* ERESTARTSYS means to restart the syscall if
			 * there is no handler or the handler was
			 * registered with SA_RESTART */
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				regs->r10 = -EINTR;
				break;
			}
		/* fallthrough */
		case -ERESTARTNOINTR:
			/* ERESTARTNOINTR means that the syscall should
			 * be called again after the signal handler returns. */
			RESTART_CRIS_SYS(regs);
		}
	}

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

	if (ret == 0) {
		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);
	}
	return ret;
}
예제 #18
0
static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
				 siginfo_t *info,
				 sigset_t *oldset, struct pt_regs *regs)
{
	setup_rt_frame(ka, regs, signr, oldset,
		       (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
	spin_lock_irq(&current->sighand->siglock);
	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
	if (!(ka->sa.sa_flags & SA_NOMASK))
		sigaddset(&current->blocked,signr);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
}
예제 #19
0
/*
 * OK, we're invoking a handler
 */	
static int
handle_signal(unsigned long sig, struct k_sigaction *ka,
	      siginfo_t *info, sigset_t *oldset,
	      struct pt_regs * regs)
{
	struct thread_info *thread = current_thread_info();
	struct task_struct *tsk = current;
	int usig = sig;
	int ret;

	/*
	 * translate the signal
	 */
	if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
		usig = thread->exec_domain->signal_invmap[usig];

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

	/*
	 * Check that the resulting registers are actually sane.
	 */
	ret |= !valid_user_regs(regs);

	if (ret != 0) {
		force_sigsegv(sig, tsk);
		return ret;
	}

	/*
	 * Block the signal if we were successful.
	 */
	spin_lock_irq(&tsk->sighand->siglock);
	sigorsets(&tsk->blocked, &tsk->blocked,
		  &ka->sa.sa_mask);
	if (!(ka->sa.sa_flags & SA_NODEFER))
		sigaddset(&tsk->blocked, sig);
	recalc_sigpending();
	spin_unlock_irq(&tsk->sighand->siglock);

	return 0;
}
예제 #20
0
/*
 * OK, we're invoking a handler
 */
static int handle_signal(unsigned long sig, siginfo_t *info,
			 struct k_sigaction *ka, sigset_t *oldset)
{
	int ret;

	/* Are we from a system call? */
	if (__frame->syscallno != -1) {
		/* If so, check system call restarting.. */
		switch (__frame->gr8) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			__frame->gr8 = -EINTR;
			break;

		case -ERESTARTSYS:
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				__frame->gr8 = -EINTR;
				break;
			}

			/* fallthrough */
		case -ERESTARTNOINTR:
			__frame->gr8 = __frame->orig_gr8;
			__frame->pc -= 4;
		}
		__frame->syscallno = -1;
	}

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

	if (ret == 0) {
		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);
	}

	return ret;

} /* end handle_signal() */
예제 #21
0
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);
	}
}
예제 #22
0
int SCOPE
post_rt_sigprocmask(const struct syscall_regs * regs)
{
	write_eax(regs);
	if (regs->eax == 0) {
		int how = regs->ebx;
		int set = regs->ecx;
		int oset = regs->edx;
		int sigsetsize = regs->esi;
		write_obj(sigsetsize);
		if (sigsetsize != sizeof(k_sigset_t)) {
			INJ_WARNING("sigsetsize %d != %d\n",
					sigsetsize, sizeof(k_sigset_t));
			return 0;
		}

		if (set) {
			k_sigset_t mask;
			__dup_mem(&mask, set, sigsetsize);

			sigdelsetmask(&mask, sigmask(SIGKILL)|sigmask(SIGSTOP));
			if (how == SIG_BLOCK) {
				sigorsets(&state_vector.sigmask,
					&state_vector.sigmask,
					&mask);
			} else if (how == SIG_UNBLOCK) {
				signandsets(&state_vector.sigmask,
					&state_vector.sigmask,
					&mask);
			} else {
				/*  SIG_SETMASK */
				state_vector.sigmask = mask;
			}
		}
		
		write_obj(oset);
		if (oset) {
			if (set == 0) {
				k_sigset_t mask;
				__dup_mem(&mask, oset, sigsetsize);
				state_vector.sigmask = mask;
			}
			write_mem(oset, sigsetsize);
		}
	}
	return 0;
}
예제 #23
0
파일: signal.c 프로젝트: IgnasD/Tomato-RAF
static int handle_signal(unsigned long sig, siginfo_t *info,
	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
{
	int ret;
	struct mips_abi *abi = current->thread.abi;
	void *vdso = current->mm->context.vdso;

	if (regs->regs[0]) {
		switch(regs->regs[2]) {
		case ERESTART_RESTARTBLOCK:
		case ERESTARTNOHAND:
			regs->regs[2] = EINTR;
			break;
		case ERESTARTSYS:
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				regs->regs[2] = EINTR;
				break;
			}
		/* fallthrough */
		case ERESTARTNOINTR:
			regs->regs[7] = regs->regs[26];
			regs->regs[2] = regs->regs[0];
			regs->cp0_epc -= 4;
		}

		regs->regs[0] = 0;		/* Don't deal with this again.  */
	}

	if (sig_uses_siginfo(ka))
		ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
					  ka, regs, sig, oldset, info);
	else
		ret = abi->setup_frame(vdso + abi->signal_return_offset,
				       ka, regs, sig, oldset);

	if (ret)
		return ret;

	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);

	return ret;
}
예제 #24
0
/*
 * OK, we're invoking a handler
 */	
static void
handle_signal(unsigned long sig, struct k_sigaction *ka,
	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{
	struct task_struct *tsk = current;
	int usig = sig;
	int ret;

	/*
	 * translate the signal
	 */
	if (usig < 32 && tsk->exec_domain && tsk->exec_domain->signal_invmap)
		usig = tsk->exec_domain->signal_invmap[usig];

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

	/*
	 * Check that the resulting registers are actually sane.
	 */
	ret |= !valid_user_regs(regs);

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

		if (!(ka->sa.sa_flags & SA_NODEFER)) {
			spin_lock_irq(&tsk->sigmask_lock);
			sigorsets(&tsk->blocked, &tsk->blocked,
				  &ka->sa.sa_mask);
			sigaddset(&tsk->blocked, sig);
			recalc_sigpending(tsk);
			spin_unlock_irq(&tsk->sigmask_lock);
		}
		return;
	}

	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;
	force_sig(SIGSEGV, tsk);
}
/*
 * handle the actual delivery of a signal to userspace
 */
static int handle_signal(int sig,
			 siginfo_t *info, struct k_sigaction *ka,
			 sigset_t *oldset, struct pt_regs *regs)
{
	int ret;

	/* Are we from a system call? */
	if (regs->orig_d0 >= 0) {
		/* If so, check system call restarting.. */
		switch (regs->d0) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->d0 = -EINTR;
			break;

		case -ERESTARTSYS:
			if (!(ka->sa.sa_flags & SA_RESTART)) {
				regs->d0 = -EINTR;
				break;
			}

			/* fallthrough */
		case -ERESTARTNOINTR:
			regs->d0 = regs->orig_d0;
			stepback(regs);
		}
	}

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

	if (ret == 0) {
		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);
	}

	return ret;
}
예제 #26
0
static void
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
	      sigset_t *oldset, struct pt_regs *regs)
{
	unsigned short inst;

	/* Are we from a system call? */
	if (regs->syscall_nr >= 0) {
		/* If so, check system call restarting.. */
		switch (regs->r0) {
		        case -ERESTART_RESTARTBLOCK:
			case -ERESTARTNOHAND:
				regs->r0 = -EINTR;
				break;

			case -ERESTARTSYS:
				if (!(ka->sa.sa_flags & SA_RESTART)) {
					regs->r0 = -EINTR;
					break;
				}
			/* fallthrough */
			case -ERESTARTNOINTR:
				regs->r0 = regs->orig_r0;
				inst = *(unsigned short *)(regs->bpc - 2);
				if ((inst & 0xfff0) == 0x10f0)	/* trap ? */
					regs->bpc -= 2;
				else
					regs->bpc -= 4;
		}
	}

	/* 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_NODEFER)) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		sigaddset(&current->blocked,sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}
}
예제 #27
0
static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
        siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{
	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_irix_rt_frame(ka, regs, sig, oldset, info);
	else
		setup_irix_frame(ka, regs, sig, oldset);

	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);
	}
}
예제 #28
0
void
handle_signal32(unsigned long sig, struct k_sigaction *ka,
		siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{
	/* Set up the stack frame */
	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_rt_frame32(sig, ka, info, oldset, regs);
	else
		setup_frame32(sig, ka, oldset, regs);

	if (!(ka->sa.sa_flags & SA_NODEFER)) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		sigaddset(&current->blocked,sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}
}
예제 #29
0
파일: signal.c 프로젝트: 274914765/C
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);
}
예제 #30
0
/*
 * OK, we're invoking a handler.
 */
static inline void
handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
	      sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
{
	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_rt_frame(sig, ka, info, oldset, regs, sw);
	else
		setup_frame(sig, ka, oldset, regs, sw);

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

	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);
}