Beispiel #1
0
static int do_signal(struct pt_regs *regs)
{
	sigset_t *oldset;
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	int ret;
	int is32 = is_32bit_task();

	if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

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

	
	check_syscall_restart(regs, &ka, signr > 0);

	if (signr <= 0) {
		struct thread_info *ti = current_thread_info();
		
		if (ti->local_flags & _TLF_RESTORE_SIGMASK) {
			ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
		}
		regs->trap = 0;
		return 0;               
	}

#ifndef CONFIG_PPC_ADV_DEBUG_REGS
	if (current->thread.dabr)
		set_dabr(current->thread.dabr);
#endif
	
	thread_change_pc(current, regs);

	if (is32) {
        	if (ka.sa.sa_flags & SA_SIGINFO)
			ret = handle_rt_signal32(signr, &ka, &info, oldset,
					regs);
		else
			ret = handle_signal32(signr, &ka, &info, oldset,
					regs);
	} else {
		ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
	}

	regs->trap = 0;
	if (ret) {
		block_sigmask(&ka, signr);

		current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;

		tracehook_signal_handler(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLESTEP));
	}

	return ret;
}
Beispiel #2
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;
}
Beispiel #3
0
/*
 * handle a potential signal
 */
static void do_signal(struct pt_regs *regs, int syscall)
{
	struct k_sigaction ka;
	siginfo_t info;
	sigset_t *oldset;
	int signr;

	/* we want the common case to go fast, which is why we may in certain
	 * cases get here from kernel mode */
	if (!user_mode(regs))
		return;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		if (handle_signal(signr, &info, &ka, oldset,
				  regs, syscall) == 0) {
			/* a signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);

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

		return;
	}

	/* did we come from a system call? */
	if (syscall) {
		/* restart the system call - no handlers present */
		switch (regs->a4) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->a4 = regs->orig_a4;
			regs->pc -= 4;
			break;

		case -ERESTART_RESTARTBLOCK:
			regs->a4 = regs->orig_a4;
			regs->b0 = __NR_restart_syscall;
			regs->pc -= 4;
			break;
		}
	}

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
Beispiel #4
0
static void do_signal(struct pt_regs *regs)
{
	struct k_sigaction sigact;
	siginfo_t info;
	int signo;

	if (!user_mode(regs))
		return;

	if (try_to_freeze())
		goto no_signal;

	signo = get_signal_to_deliver(&info, &sigact, regs, NULL);

	if (signo > 0) {
		sigset_t *oldset;

		if (test_thread_flag(TIF_RESTORE_SIGMASK))
			oldset = &current->saved_sigmask;
		else
			oldset = &current->blocked;

		if (handle_signal(signo, &info, &sigact, oldset, regs) == 0) {
			clear_thread_flag(TIF_RESTORE_SIGMASK);

			tracehook_signal_handler(signo, &info, &sigact, regs,
				test_thread_flag(TIF_SINGLESTEP));
		}
		return;
	}

no_signal:
	if (regs->syscall_nr >= 0) {
		switch (regs->r00) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->r06 = regs->syscall_nr;
			break;
		case -ERESTART_RESTARTBLOCK:
			regs->r06 = __NR_restart_syscall;
			break;
		default:
			goto no_restart;
		}
		pt_set_elr(regs, pt_elr(regs) - 4);
		regs->r00 = regs->restart_r0;
	}

no_restart:
	
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
Beispiel #5
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.
 */
asmlinkage void do_signal(struct pt_regs *regs)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	sigset_t *oldset;

	current->thread.esp0 = (unsigned long)regs;

	if (try_to_freeze())
		goto no_signal;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
			/* a signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);

			tracehook_signal_handler(signr, &info, &ka, regs,
				test_thread_flag(TIF_SINGLESTEP));
		}

		return;
	}

 no_signal:
	/* Did we come from a system call? */
	if (regs->orig_p0 >= 0)
		/* Restart the system call - no handlers present */
		handle_restart(regs, NULL, 0);

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
				siginfo_t *info,
				sigset_t *oldset, struct pt_regs *regs)
{
	int err;

	err = setup_rt_frame(ka, regs, signr, oldset,
			     (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
	if (err)
		return err;

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

	return 0;
}
Beispiel #7
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.
	 */
	block_sigmask(ka, sig);

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

	return 0;
}
static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
				siginfo_t *info,
				sigset_t *oldset, struct pt_regs *regs)
{
	sigset_t blocked;
	int err;

	err = setup_rt_frame(ka, regs, signr, oldset,
			     (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
	if (err)
		return err;
	sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
	if (!(ka->sa.sa_flags & SA_NOMASK))
		sigaddset(&blocked, signr);
	set_current_blocked(&blocked);

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

	return 0;
}
static long
handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
	       struct sigscratch *scr)
{
	if (!setup_frame(sig, ka, info, sigmask_to_save(), scr))
		return 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);

	/*
	 * Let tracing know that we've done the handler setup.
	 */
	tracehook_signal_handler(sig, info, ka, &scr->pt,
				 test_thread_flag(TIF_SINGLESTEP));

	return 1;
}
Beispiel #10
0
static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	int ret;
	int is32 = is_32bit_task();

#ifdef CONFIG_PREEMPT_RT
	/*
	 * Fully-preemptible kernel does not need interrupts disabled:
	 */
	local_irq_enable();
	preempt_check_resched();
#endif

	if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
		oldset = &current->saved_sigmask;
	else if (!oldset)
		oldset = &current->blocked;

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

	/* Is there any syscall restart business here ? */
	check_syscall_restart(regs, &ka, signr > 0);

	if (signr <= 0) {
		struct thread_info *ti = current_thread_info();
		/* No signal to deliver -- put the saved sigmask back */
		if (ti->local_flags & _TLF_RESTORE_SIGMASK) {
			ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
		}
		return 0;               /* no signals delivered */
	}

        /*
	 * Reenable the DABR before delivering the signal to
	 * user space. The DABR will have been cleared if it
	 * triggered inside the kernel.
	 */
	if (current->thread.dabr) {
		set_dabr(current->thread.dabr);
#if defined(CONFIG_BOOKE)
		mtspr(SPRN_DBCR0, current->thread.dbcr0);
#endif
	}

	if (is32) {
        	if (ka.sa.sa_flags & SA_SIGINFO)
			ret = handle_rt_signal32(signr, &ka, &info, oldset,
					regs);
		else
			ret = handle_signal32(signr, &ka, &info, oldset,
					regs);
	} else {
		ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
	}

	if (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, signr);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);

		/*
		 * A signal was successfully delivered; the saved sigmask is in
		 * its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
		 */
		current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;

		/*
		 * Let tracing know that we've done the handler setup.
		 */
		tracehook_signal_handler(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLESTEP));
	}

	return ret;
}
Beispiel #11
0
void do_signal(struct pt_regs *regs)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(regs))
		return;

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

	/* If we are coming out of a syscall then we need
	 * to check if the syscall was interrupted and wants to be
	 * restarted after handling the signal.  If so, the original
	 * syscall number is put back into r11 and the PC rewound to
	 * point at the l.sys instruction that resulted in the
	 * original syscall.  Syscall results other than the four
	 * below mean that the syscall executed to completion and no
	 * restart is necessary.
	 */
	if (regs->syscallno) {
		int restart = 0;

		switch (regs->gpr[11]) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			/* Restart if there is no signal handler */
			restart = (signr <= 0);
			break;
		case -ERESTARTSYS:
			/* Restart if there no signal handler or
			 * SA_RESTART flag is set */
			restart = (signr <= 0 || (ka.sa.sa_flags & SA_RESTART));
			break;
		case -ERESTARTNOINTR:
			/* Always restart */
			restart = 1;
			break;
		}

		if (restart) {
			if (regs->gpr[11] == -ERESTART_RESTARTBLOCK)
				regs->gpr[11] = __NR_restart_syscall;
			else
				regs->gpr[11] = regs->orig_gpr11;
			regs->pc -= 4;
		} else {
			regs->gpr[11] = -EINTR;
		}
	}

	if (signr <= 0) {
		/* no signal to deliver so we just put the saved sigmask
		 * back */
		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
			clear_thread_flag(TIF_RESTORE_SIGMASK);
			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
		}

	} else {		/* signr > 0 */
		sigset_t *oldset;

		if (current_thread_info()->flags & _TIF_RESTORE_SIGMASK)
			oldset = &current->saved_sigmask;
		else
			oldset = &current->blocked;

		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &info, &ka, oldset, regs);
		/* a signal was successfully delivered; the saved
		 * sigmask will have been stored in the signal frame,
		 * and will be restored by sigreturn, so we can simply
		 * clear the TIF_RESTORE_SIGMASK flag */
		if (test_thread_flag(TIF_RESTORE_SIGMASK))
			clear_thread_flag(TIF_RESTORE_SIGMASK);

		tracehook_signal_handler(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLESTEP));
	}

	return;
}
Beispiel #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 (syscall_get_nr(current, regs) >= 0) {
		/* If so, check system call restarting.. */
		switch (syscall_get_error(current, regs)) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->ax = -EINTR;
			break;

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

	/*
	 * If TF is set due to a debugger (TIF_FORCED_TF), clear the TF
	 * flag so that register information in the sigcontext is correct.
	 */
	if (unlikely(regs->flags & X86_EFLAGS_TF) &&
	    likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
		regs->flags &= ~X86_EFLAGS_TF;

	ret = setup_rt_frame(sig, ka, info, oldset, regs);

	if (ret)
		return ret;

#ifdef CONFIG_X86_64
	/*
	 * This has nothing to do with segment registers,
	 * despite the name.  This magic affects uaccess.h
	 * macros' behavior.  Reset it to the normal setting.
	 */
	set_fs(USER_DS);
#endif

	/*
	 * Clear the direction flag as per the ABI for function entry.
	 */
	regs->flags &= ~X86_EFLAGS_DF;

	/*
	 * Clear TF when entering the signal handler, but
	 * notify any tracer that was single-stepping it.
	 * The tracer may want to single-step inside the
	 * handler too.
	 */
	regs->flags &= ~X86_EFLAGS_TF;

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

	tracehook_signal_handler(sig, info, ka, regs,
				 test_thread_flag(TIF_SINGLESTEP));

	return 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.
 */
static void do_signal(struct pt_regs *regs, unsigned int save_r0)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	sigset_t *oldset;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(regs))
		return;

	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		handle_syscall_restart(save_r0, regs, &ka.sa);

		/* Whee!  Actually deliver the signal.  */
		if (handle_signal(signr, &ka, &info, oldset,
				  regs, save_r0) == 0) {
			/*
			 * A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TS_RESTORE_SIGMASK flag
			 */
			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;

			tracehook_signal_handler(signr, &info, &ka, regs,
					test_thread_flag(TIF_SINGLESTEP));
		}

		return;
	}

	/* Did we come from a system call? */
	if (regs->tra >= 0) {
		/* Restart the system call - no handlers present */
		if (regs->regs[0] == -ERESTARTNOHAND ||
		    regs->regs[0] == -ERESTARTSYS ||
		    regs->regs[0] == -ERESTARTNOINTR) {
			regs->regs[0] = save_r0;
			regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
		} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
			regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
			regs->regs[3] = __NR_restart_syscall;
		}
	}

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
/*
 * 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.
 */
static void do_signal(void)
{
	struct k_sigaction ka;
	siginfo_t info;
	sigset_t *oldset;
	int signr;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(__frame))
		return;

	if (try_to_freeze())
		goto no_signal;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
	if (signr > 0) {
		if (handle_signal(signr, &info, &ka, oldset) == 0) {
			/* a signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);

			tracehook_signal_handler(signr, &info, &ka, __frame,
						 test_thread_flag(TIF_SINGLESTEP));
		}

		return;
	}

no_signal:
	/* Did we come from a system call? */
	if (__frame->syscallno != -1) {
		/* Restart the system call - no handlers present */
		switch (__frame->gr8) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			__frame->gr8 = __frame->orig_gr8;
			__frame->pc -= 4;
			break;

		case -ERESTART_RESTARTBLOCK:
			__frame->gr7 = __NR_restart_syscall;
			__frame->pc -= 4;
			break;
		}
		__frame->syscallno = -1;
	}

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}

} /* end do_signal() */
Beispiel #15
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.
 */
void do_signal(struct pt_regs *regs)
{
	unsigned long retval = 0, continue_addr = 0, restart_addr = 0;
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	sigset_t *oldset;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(regs))
		return;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	/* Are we from a system call? */
	if (regs->svcnr) {
		continue_addr = regs->psw.addr;
		restart_addr = continue_addr - regs->ilc;
		retval = regs->gprs[2];

		/* Prepare for system call restart.  We do this here so that a
		   debugger will see the already changed PSW. */
		switch (retval) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->gprs[2] = regs->orig_gpr2;
			regs->psw.addr = restart_addr;
			break;
		case -ERESTART_RESTARTBLOCK:
			regs->gprs[2] = -EINTR;
		}
		regs->svcnr = 0;	/* Don't deal with this again. */
	}

	/* Get signal to deliver.  When running under ptrace, at this point
	   the debugger may change all our registers ... */
	signr = get_signal_to_deliver(&info, &ka, regs, NULL);

	/* Depending on the signal settings we may need to revert the
	   decision to restart the system call. */
	if (signr > 0 && regs->psw.addr == restart_addr) {
		if (retval == -ERESTARTNOHAND
		    || (retval == -ERESTARTSYS
			 && !(current->sighand->action[signr-1].sa.sa_flags
			      & SA_RESTART))) {
			regs->gprs[2] = -EINTR;
			regs->psw.addr = continue_addr;
		}
	}

	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		int ret;
#ifdef CONFIG_COMPAT
		if (test_thread_flag(TIF_31BIT)) {
			ret = handle_signal32(signr, &ka, &info, oldset, regs);
	        }
		else
#endif
			ret = handle_signal(signr, &ka, &info, oldset, regs);
		if (!ret) {
			/*
			 * A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag.
			 */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);

			/*
			 * If we would have taken a single-step trap
			 * for a normal instruction, act like we took
			 * one for the handler setup.
			 */
			if (current->thread.per_info.single_step)
				set_thread_flag(TIF_SINGLE_STEP);

			/*
			 * Let tracing know that we've done the handler setup.
			 */
			tracehook_signal_handler(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLE_STEP));
		}
		return;
	}

	/*
	 * If there's no signal to deliver, we just put the saved sigmask back.
	 */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}

	/* Restart a different system call. */
	if (retval == -ERESTART_RESTARTBLOCK
	    && regs->psw.addr == continue_addr) {
		regs->gprs[2] = __NR_restart_syscall;
		set_thread_flag(TIF_RESTART_SVC);
	}
}
Beispiel #16
0
static int do_signal(struct pt_regs *regs)
{
	sigset_t *oldset;
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	int ret;
	int is32 = is_32bit_task();

	if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

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

	/* Is there any syscall restart business here ? */
	check_syscall_restart(regs, &ka, signr > 0);

	if (signr <= 0) {
		struct thread_info *ti = current_thread_info();
		/* No signal to deliver -- put the saved sigmask back */
		if (ti->local_flags & _TLF_RESTORE_SIGMASK) {
			ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
		}
		regs->trap = 0;
		return 0;               /* no signals delivered */
	}

#ifndef CONFIG_PPC_ADV_DEBUG_REGS
        /*
	 * Reenable the DABR before delivering the signal to
	 * user space. The DABR will have been cleared if it
	 * triggered inside the kernel.
	 */
	if (current->thread.dabr)
		set_dabr(current->thread.dabr);
#endif
	/* Re-enable the breakpoints for the signal stack */
	thread_change_pc(current, regs);

	if (is32) {
        	if (ka.sa.sa_flags & SA_SIGINFO)
			ret = handle_rt_signal32(signr, &ka, &info, oldset,
					regs);
		else
			ret = handle_signal32(signr, &ka, &info, oldset,
					regs);
	} else {
		ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
	}

	regs->trap = 0;
	if (ret) {
		block_sigmask(&ka, signr);

		/*
		 * A signal was successfully delivered; the saved sigmask is in
		 * its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
		 */
		current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;

		/*
		 * Let tracing know that we've done the handler setup.
		 */
		tracehook_signal_handler(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLESTEP));
	}

	return ret;
}
/* 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.
 */
static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
{
	struct k_sigaction ka;
	int restart_syscall;
	sigset_t *oldset;
	siginfo_t info;
	int signr;
	
	if (pt_regs_is_syscall(regs) &&
	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
		restart_syscall = 1;
	} else
		restart_syscall = 0;

	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

#ifdef CONFIG_COMPAT
	if (test_thread_flag(TIF_32BIT)) {
		extern void do_signal32(sigset_t *, struct pt_regs *,
					int restart_syscall,
					unsigned long orig_i0);
		do_signal32(oldset, regs, restart_syscall, orig_i0);
		return;
	}
#endif	

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

	/* If the debugger messes with the program counter, it clears
	 * the software "in syscall" bit, directing us to not perform
	 * a syscall restart.
	 */
	if (restart_syscall && !pt_regs_is_syscall(regs))
		restart_syscall = 0;

	if (signr > 0) {
		if (restart_syscall)
			syscall_restart(orig_i0, regs, &ka.sa);
		handle_signal(signr, &ka, &info, oldset, regs);

		/* A signal was successfully delivered; the saved
		 * sigmask will have been stored in the signal frame,
		 * and will be restored by sigreturn, so we can simply
		 * clear the TS_RESTORE_SIGMASK flag.
		 */
		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;

		tracehook_signal_handler(signr, &info, &ka, regs, 0);
		return;
	}
	if (restart_syscall &&
	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
		/* replay the system call when we are done */
		regs->u_regs[UREG_I0] = orig_i0;
		regs->tpc -= 4;
		regs->tnpc -= 4;
	}
	if (restart_syscall &&
	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
		regs->u_regs[UREG_G1] = __NR_restart_syscall;
		regs->tpc -= 4;
		regs->tnpc -= 4;
	}

	/* If there's no signal to deliver, we just put the saved sigmask
	 * back
	 */
	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
/*
 * 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.
 */
void do_signal(struct pt_regs *regs)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	sigset_t *oldset;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(regs))
		return;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	/*
	 * Get signal to deliver. When running under ptrace, at this point
	 * the debugger may change all our registers, including the system
	 * call information.
	 */
	current_thread_info()->system_call =
		test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0;
	signr = get_signal_to_deliver(&info, &ka, regs, NULL);

	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		if (current_thread_info()->system_call) {
			regs->int_code = current_thread_info()->system_call;
			/* Check for system call restarting. */
			switch (regs->gprs[2]) {
			case -ERESTART_RESTARTBLOCK:
			case -ERESTARTNOHAND:
				regs->gprs[2] = -EINTR;
				break;
			case -ERESTARTSYS:
				if (!(ka.sa.sa_flags & SA_RESTART)) {
					regs->gprs[2] = -EINTR;
					break;
				}
			/* fallthrough */
			case -ERESTARTNOINTR:
				regs->gprs[2] = regs->orig_gpr2;
				regs->psw.addr =
					__rewind_psw(regs->psw,
						     regs->int_code >> 16);
				break;
			}
		}
		/* No longer in a system call */
		clear_thread_flag(TIF_SYSCALL);

		if ((is_compat_task() ?
		     handle_signal32(signr, &ka, &info, oldset, regs) :
		     handle_signal(signr, &ka, &info, oldset, regs)) == 0) {
			/*
			 * A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag.
			 */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);

			/*
			 * Let tracing know that we've done the handler setup.
			 */
			tracehook_signal_handler(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLE_STEP));
		}
		return;
	}
Beispiel #19
0
/*
 * Called from return-from-event code.
 */
static void do_signal(struct pt_regs *regs)
{
	struct k_sigaction sigact;
	siginfo_t info;
	int signo;

	if (!user_mode(regs))
		return;

	if (try_to_freeze())
		goto no_signal;

	signo = get_signal_to_deliver(&info, &sigact, regs, NULL);

	if (signo > 0) {
		sigset_t *oldset;

		if (test_thread_flag(TIF_RESTORE_SIGMASK))
			oldset = &current->saved_sigmask;
		else
			oldset = &current->blocked;

		if (handle_signal(signo, &info, &sigact, oldset, regs) == 0) {
			/*
			 * Successful delivery case.  The saved sigmask is
			 * stored in the signal frame, and will be restored
			 * by sigreturn.  We can clear the TIF flag.
			 */
			clear_thread_flag(TIF_RESTORE_SIGMASK);

			tracehook_signal_handler(signo, &info, &sigact, regs,
				test_thread_flag(TIF_SINGLESTEP));
		}
		return;
	}

no_signal:
	/*
	 * If we came from a system call, handle the restart.
	 */
	if (regs->syscall_nr >= 0) {
		switch (regs->r00) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->r06 = regs->syscall_nr;
			break;
		case -ERESTART_RESTARTBLOCK:
			regs->r06 = __NR_restart_syscall;
			break;
		default:
			goto no_restart;
		}
		pt_set_elr(regs, pt_elr(regs) - 4);
		regs->r00 = regs->restart_r0;
	}

no_restart:
	/* If there's no signal to deliver, put the saved sigmask back */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
/*
 * 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.
 */
static int do_signal(struct pt_regs *regs, sigset_t *oldset)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(regs))
		return 1;

	if (try_to_freeze())
		goto no_signal;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else if (!oldset)
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, 0);
	if (signr > 0) {
		handle_syscall_restart(regs, &ka.sa);

		/* Whee!  Actually deliver the signal.  */
		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
			/*
			 * If a signal was successfully delivered, the
			 * saved sigmask is in its frame, and we can
			 * clear the TIF_RESTORE_SIGMASK flag.
			 */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);

			tracehook_signal_handler(signr, &info, &ka, regs, 0);
			return 1;
		}
	}

no_signal:
	/* Did we come from a system call? */
	if (regs->syscall_nr >= 0) {
		/* Restart the system call - no handlers present */
		switch (regs->regs[REG_RET]) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			/* Decode Syscall # */
			regs->regs[REG_RET] = regs->syscall_nr;
			regs->pc -= 4;
			break;

		case -ERESTART_RESTARTBLOCK:
			regs->regs[REG_RET] = __NR_restart_syscall;
			regs->pc -= 4;
			break;
		}
	}

	/* No signal to deliver -- put the saved sigmask back */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}

	return 0;
}
void do_signal(struct pt_regs *regs)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;

	/*
                                             
                                                
                                                   
          
  */
	if (!user_mode(regs))
		return;

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

	/*                                               
                                                           
                                                             
                                                             
                                                       
                                                          
                                                             
                         
  */
	if (regs->orig_gpr11) {
		int restart = 0;

		switch (regs->gpr[11]) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			/*                                       */
			restart = (signr <= 0);
			break;
		case -ERESTARTSYS:
			/*                                      
                             */
			restart = (signr <= 0 || (ka.sa.sa_flags & SA_RESTART));
			break;
		case -ERESTARTNOINTR:
			/*                */
			restart = 1;
			break;
		}

		if (restart) {
			if (regs->gpr[11] == -ERESTART_RESTARTBLOCK)
				regs->gpr[11] = __NR_restart_syscall;
			else
				regs->gpr[11] = regs->orig_gpr11;
			regs->pc -= 4;
		} else {
			regs->gpr[11] = -EINTR;
		}
	}

	if (signr <= 0) {
		/*                                                      
          */
		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
			clear_thread_flag(TIF_RESTORE_SIGMASK);
			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
		}

	} else {		/*           */
		sigset_t *oldset;

		if (current_thread_info()->flags & _TIF_RESTORE_SIGMASK)
			oldset = &current->saved_sigmask;
		else
			oldset = &current->blocked;

		/*                                      */
		if (!handle_signal(signr, &info, &ka, oldset, regs)) {
			/*                                               
                                                        
                                                         
                                         */
			clear_thread_flag(TIF_RESTORE_SIGMASK);
		}

		tracehook_signal_handler(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLESTEP));
	}

	return;
}