Ejemplo n.º 1
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, int in_syscall)
{
	struct ksignal ksig;

#ifdef DEBUG_SIG
	pr_info("do signal: %p %d\n", regs, in_syscall);
	pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
			regs->r12, current_thread_info()->flags);
#endif

	if (get_signal(&ksig)) {
		/* Whee! Actually deliver the signal. */
		if (in_syscall)
			handle_restart(regs, &ksig.ka, 1);
		handle_signal(&ksig, regs);
		return;
	}

	if (in_syscall)
		handle_restart(regs, NULL, 0);

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 2
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, int in_syscall)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
#ifdef DEBUG_SIG
	pr_info("do signal: %p %d\n", regs, in_syscall);
	pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
			regs->r12, current_thread_info()->flags);
#endif

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee! Actually deliver the signal. */
		if (in_syscall)
			handle_restart(regs, &ka, 1);
		handle_signal(signr, &ka, &info, regs);
		return;
	}

	if (in_syscall)
		handle_restart(regs, NULL, 0);

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 3
0
static void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

	if (get_signal(&ksig)) {
		/* Actually deliver the signal */
		handle_signal(&ksig, regs);
		return;
	}

	/* Did we come from a system call? */
	if (regs->cause == EXC_SYSCALL) {
		/* Restart the system call - no handlers present */
		switch (regs->v[0]) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->v[0] = regs->syscallno;
			regs->epc -= 0x4;
			break;
		case -ERESTART_RESTARTBLOCK:
			regs->v[0] = __NR_restart_syscall;
			regs->epc -= 0x4;
			break;
		}
	}

	/* If there is no signal to deliver, we just put the saved
	   sigmask back. */
	restore_saved_sigmask();
}
Ejemplo n.º 4
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)
{
	struct ksignal ksig;

	if (get_signal(&ksig)) {
		handle_signal(&ksig, regs);
		return;
	}

	/*
	 * If we were from a system call, check for system call restarting...
	 */
	if (in_syscall(regs)) {
		/* Restart the system call - no handlers present */

		/* Avoid additional syscall restarting via ret_slow_syscall. */
		forget_syscall(regs);

		switch (regs->uregs[0]) {
		case -ERESTART_RESTARTBLOCK:
			regs->uregs[15] = __NR_restart_syscall;
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->uregs[0] = regs->orig_r0;
			regs->ipc -= 0x4;
			break;
		}
	}
	restore_saved_sigmask();
}
Ejemplo n.º 5
0
/*
 * handle a potential signal
 */
static void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

	if (get_signal(&ksig)) {
		handle_signal(&ksig, regs);
		return;
	}

	/* did we come from a system call? */
	if (regs->orig_d0 >= 0) {
		/* restart the system call - no handlers present */
		switch (regs->d0) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->d0 = regs->orig_d0;
			stepback(regs);
			break;

		case -ERESTART_RESTARTBLOCK:
			regs->d0 = __NR_restart_syscall;
			stepback(regs);
			break;
		}
	}

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	restore_saved_sigmask();
}
Ejemplo n.º 6
0
static void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

	if (get_signal(&ksig)) {
		/* Whee!  Actually deliver the signal.	*/
		handle_signal(&ksig, regs);
		return;
	}

	if (regs->regs[0]) {
		switch (regs->regs[2]) {
		case ERESTARTNOHAND:
		case ERESTARTSYS:
		case ERESTARTNOINTR:
			regs->regs[2] = regs->regs[0];
			regs->regs[7] = regs->regs[26];
			regs->cp0_epc -= 4;
			break;

		case ERESTART_RESTARTBLOCK:
			regs->regs[2] = current->thread.abi->restart;
			regs->regs[7] = regs->regs[26];
			regs->cp0_epc -= 4;
			break;
		}
		regs->regs[0] = 0;	/* Don't deal with this again.	*/
	}

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back
	 */
	restore_saved_sigmask();
}
/*
 * 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 ksignal ksig;

	if (get_signal(&ksig)) {
		handle_signal(&ksig);
		return;
	}

	/* 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 */
	restore_saved_sigmask();
} /* end do_signal() */
Ejemplo n.º 8
0
static int kern_do_signal(struct pt_regs *regs)
{
	struct k_sigaction ka_copy;
	siginfo_t info;
	sigset_t *oldset;
	int sig, handled_sig = 0;

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

	while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
		handled_sig = 1;
		/* Whee!  Actually deliver the signal.  */
		handle_signal(regs, sig, &ka_copy, &info);
	}

	/* Did we come from a system call? */
	if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) {
		/* Restart the system call - no handlers present */
		switch (PT_REGS_SYSCALL_RET(regs)) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
			PT_REGS_RESTART_SYSCALL(regs);
			break;
		case -ERESTART_RESTARTBLOCK:
			PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
			PT_REGS_RESTART_SYSCALL(regs);
			break;
		}
	}

	/*
	 * This closes a way to execute a system call on the host.  If
	 * you set a breakpoint on a system call instruction and singlestep
	 * from it, the tracing thread used to PTRACE_SINGLESTEP the process
	 * rather than PTRACE_SYSCALL it, allowing the system call to execute
	 * on the host.  The tracing thread will check this flag and
	 * PTRACE_SYSCALL if necessary.
	 */
	if (current->ptrace & PT_DTRACE)
		current->thread.singlestep_syscall =
			is_syscall(PT_REGS_IP(&current->thread.regs));

	/*
	 * if there's no signal to deliver, we just put the saved sigmask
	 * back
	 */
	if (!handled_sig)
		restore_saved_sigmask();
	return handled_sig;
}
Ejemplo n.º 9
0
static int do_signal(struct pt_regs *regs)
{
	sigset_t *oldset = sigmask_to_save();
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	int ret;
	int is32 = is_32bit_task();

	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) {
		/* No signal to deliver -- put the saved sigmask back */
		restore_saved_sigmask();
		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.hw_brk.address &&
		current->thread.hw_brk.type)
		set_breakpoint(&current->thread.hw_brk);
#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) {
		signal_delivered(signr, &info, &ka, regs,
					 test_thread_flag(TIF_SINGLESTEP));
	}

	return ret;
}
Ejemplo n.º 10
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, int syscall)
{
	struct k_sigaction ka;
	siginfo_t info;
	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(regs))
		return;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		handle_signal(signr, &ka, &info, regs, syscall);
		return;
	}

	/*
	 * No signal to deliver to the process - restart the syscall.
	 */
	if (syscall) {
		if (regs->UCreg_00 == -ERESTART_RESTARTBLOCK) {
				u32 __user *usp;

				regs->UCreg_sp -= 4;
				usp = (u32 __user *)regs->UCreg_sp;

				if (put_user(regs->UCreg_pc, usp) == 0) {
					regs->UCreg_pc = KERN_RESTART_CODE;
				} else {
					regs->UCreg_sp += 4;
					force_sigsegv(0, current);
				}
		}
		if (regs->UCreg_00 == -ERESTARTNOHAND ||
		    regs->UCreg_00 == -ERESTARTSYS ||
		    regs->UCreg_00 == -ERESTARTNOINTR) {
			setup_syscall_restart(regs);
		}
	}
	/* If there's no signal to deliver, we just put the saved
	 * sigmask back.
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 11
0
void do_signal(int canrestart, 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 (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		if (handle_signal(canrestart, signr, &info, &ka,
				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);
		}
		return;
	}

	/* Did we come from a system call? */
	if (canrestart) {
		/* Restart the system call - no handlers present */
		if (regs->r10 == -ERESTARTNOHAND ||
		    regs->r10 == -ERESTARTSYS ||
		    regs->r10 == -ERESTARTNOINTR) {
			RESTART_CRIS_SYS(regs);
		}
		if (regs->r10 == -ERESTART_RESTARTBLOCK) {
			regs->r9 = __NR_restart_syscall;
			regs->irp -= 2;
		}
	}

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	restore_saved_sigmask();
}
Ejemplo n.º 12
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 in_syscall)
{
	struct ksignal ksig;

	/* Did we come from a system call? */

	if (get_signal(&ksig)) {
		if (in_syscall) {
			switch (regs->r1) {
			case -ERESTART_RESTARTBLOCK:
			case -ERESTARTNOHAND:
				regs->r1 = -EINTR;
				break;
			case -ERESTARTSYS:
				if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
					regs->r1 = -EINTR;
					break;
				}
				/* fallthrough */
			case -ERESTARTNOINTR:
				regs->ea -= 4; /* Size of scall insn.  */
				regs->r1 = regs->orig_r1;
				break;
			default:
				break;
			}
		}
		handle_signal(&ksig, regs);
	} else {
		/* If there is no handler always restart */
		if (in_syscall) {
			switch (regs->r1) {
			case -ERESTART_RESTARTBLOCK:
				regs->r8 = __NR_restart_syscall;
				/* fallthrough */
			case -ERESTARTNOHAND:
			case -ERESTARTSYS:
			case -ERESTARTNOINTR:
				regs->ea -= 4; /* Size of scall insn.  */
				regs->r1 = regs->orig_r1;
				break;
			default:
				break;
			}
		}
		restore_saved_sigmask();
	}
}
Ejemplo n.º 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.
 *
 * "r0" and "r19" are the registers we need to restore for system call
 * restart. "r0" is also used as an indicator whether we can restart at
 * all (if we get here from anything but a syscall return, it will be 0)
 */
static void
do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19)
{
	siginfo_t info;
	int signr;
	unsigned long single_stepping = ptrace_cancel_bpt(current);
	struct k_sigaction ka;

	/* This lets the debugger run, ... */
	signr = get_signal_to_deliver(&info, &ka, regs, NULL);

	/* ... so re-check the single stepping. */
	single_stepping |= ptrace_cancel_bpt(current);

	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		if (r0)
			syscall_restart(r0, r19, regs, &ka);
		handle_signal(signr, &ka, &info, regs);
		if (single_stepping) 
			ptrace_set_bpt(current); /* re-set bpt */
		return;
	}

	if (r0) {
	  	switch (regs->r0) {
		case ERESTARTNOHAND:
		case ERESTARTSYS:
		case ERESTARTNOINTR:
			/* Reset v0 and a3 and replay syscall.  */
			regs->r0 = r0;
			regs->r19 = r19;
			regs->pc -= 4;
			break;
		case ERESTART_RESTARTBLOCK:
			/* Force v0 to the restart syscall and reply.  */
			regs->r0 = __NR_restart_syscall;
			regs->pc -= 4;
			break;
		}
	}

	/* If there's no signal to deliver, we just restore the saved mask.  */
	restore_saved_sigmask();
	if (single_stepping)
		ptrace_set_bpt(current);	/* re-set breakpoint */
}
Ejemplo n.º 14
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)
{
    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, 0);
    if (signr > 0) {
        handle_syscall_restart(regs, &ka.sa);

        /* Whee!  Actually deliver the signal.  */
        handle_signal(signr, &info, &ka, regs);
        return;
    }

    /* 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 */
    restore_saved_sigmask();
}
Ejemplo n.º 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.
 */
static 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 (signr > 0) {
		/* Re-enable any watchpoints before delivering the
		 * signal to user space. The processor register will
		 * have been cleared if the watchpoint triggered
		 * inside the kernel.
		 */

		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &ka, &info, regs);

		return;
	}

	/* Did we come from a system call? */
	if (regs->syscall_nr >= 0) {
		/* Restart the system call - no handlers present */
		if (regs->r0 == -ERESTARTNOHAND ||
		    regs->r0 == -ERESTARTSYS ||
		    regs->r0 == -ERESTARTNOINTR) {
			regs->r0 = regs->orig_r0;
			prev_insn(regs);
		} else if (regs->r0 == -ERESTART_RESTARTBLOCK){
			regs->r0 = regs->orig_r0;
			regs->r7 = __NR_restart_syscall;
			prev_insn(regs);
		}
	}
	restore_saved_sigmask();
}
Ejemplo n.º 16
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.
 */
static void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

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

	if (get_signal(&ksig)) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(&ksig, regs);
		return;
	}
	/* Did we come from a system call? */
	if (regs->orig_er0 >= 0)
		handle_restart(regs, NULL);

	/* If there's no signal to deliver, we just restore the saved mask.  */
	restore_saved_sigmask();
}
Ejemplo n.º 17
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;

	/*
	 * 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 (signr > 0) {
		handle_syscall_restart(save_r0, regs, &ka.sa);

		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &ka, &info, regs, save_r0);
		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.
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 18
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.
 */
void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

	/*
	 * i386 will check if we're coming from kernel mode and bail out
	 * here.  In my experience this just turns weird crashes into
	 * weird spin-hangs.  But if we find a case where this seems
	 * helpful, we can reinstate the check on "!user_mode(regs)".
	 */

	if (get_signal(&ksig)) {
		/* Whee! Actually deliver the signal.  */
		handle_signal(&ksig, regs);
		goto done;
	}

	/* Did we come from a system call? */
	if (regs->faultnum == INT_SWINT_1) {
		/* Restart the system call - no handlers present */
		switch (regs->regs[0]) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->flags |= PT_FLAGS_CALLER_SAVES;
			regs->regs[0] = regs->orig_r0;
			regs->pc -= 8;
			break;

		case -ERESTART_RESTARTBLOCK:
			regs->flags |= PT_FLAGS_CALLER_SAVES;
			regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall;
			regs->pc -= 8;
			break;
		}
	}

	/* If there's no signal to deliver, just put the saved sigmask back. */
	restore_saved_sigmask();

done:
	/* Avoid double syscall restart if there are nested signals. */
	regs->faultnum = INT_SWINT_1_SIGRETURN;
}
Ejemplo n.º 19
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.
 */
static void do_signal(struct pt_regs *regs, int syscall)
{
	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 (syscall) {
		switch (regs->r12) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			if (signr > 0) {
				regs->r12 = -EINTR;
				break;
			}
			/* fall through */
		case -ERESTARTSYS:
			if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) {
				regs->r12 = -EINTR;
				break;
			}
			/* fall through */
		case -ERESTARTNOINTR:
			setup_syscall_restart(regs);
		}
	}

	if (signr == 0) {
		/* No signal to deliver -- put the saved sigmask back */
		restore_saved_sigmask();
		return;
	}

	handle_signal(signr, &ka, &info, regs, syscall);
}
Ejemplo n.º 20
0
static void do_signal(struct pt_regs *regs)
{
	struct k_sigaction ka;
	siginfo_t info;
	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(regs))
		return;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &info, &ka, regs);
		return;
	}

	if (regs->regs[0]) {
		if (regs->regs[2] == ERESTARTNOHAND ||
		    regs->regs[2] == ERESTARTSYS ||
		    regs->regs[2] == ERESTARTNOINTR) {
			regs->regs[2] = regs->regs[0];
			regs->regs[7] = regs->regs[26];
			regs->cp0_epc -= 4;
		}
		if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
			regs->regs[2] = current->thread.abi->restart;
			regs->regs[7] = regs->regs[26];
			regs->cp0_epc -= 4;
		}
		regs->regs[0] = 0;	/* Don't deal with this again.  */
	}

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 21
0
Archivo: signal.c Proyecto: 7L/pi_plus
/*
 * 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)
{
	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 ((regs->ccr & 0x10))
		return;

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

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &info, &ka, regs);
		return;
	}
	/* Did we come from a system call? */
	if (regs->orig_er0 >= 0) {
		/* Restart the system call - no handlers present */
		if (regs->er0 == -ERESTARTNOHAND ||
		    regs->er0 == -ERESTARTSYS ||
		    regs->er0 == -ERESTARTNOINTR) {
			regs->er0 = regs->orig_er0;
			regs->pc -= 2;
		}
		if (regs->er0 == -ERESTART_RESTARTBLOCK){
			regs->er0 = __NR_restart_syscall;
			regs->pc -= 2;
		}
	}

	/* If there's no signal to deliver, we just restore the saved mask.  */
	restore_saved_sigmask();
}
Ejemplo n.º 22
0
Archivo: signal.c Proyecto: 4atty/linux
void do_signal(int canrestart, 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 (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(canrestart, signr, &info, &ka, regs);
		return;
	}

	/* Did we come from a system call? */
	if (canrestart) {
		/* Restart the system call - no handlers present */
		if (regs->r10 == -ERESTARTNOHAND ||
		    regs->r10 == -ERESTARTSYS ||
		    regs->r10 == -ERESTARTNOINTR) {
			RESTART_CRIS_SYS(regs);
		}
		if (regs->r10 == -ERESTART_RESTARTBLOCK) {
			regs->r9 = __NR_restart_syscall;
			regs->irp -= 2;
		}
	}

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	restore_saved_sigmask();
}
Ejemplo n.º 23
0
/*
 * handle a potential signal
 */
static void do_signal(struct pt_regs *regs, int syscall)
{
	struct k_sigaction ka;
	siginfo_t info;
	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;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		handle_signal(signr, &info, &ka, regs, syscall);
		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 */
	restore_saved_sigmask();
}
Ejemplo n.º 24
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;

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

	if (signo > 0) {
		handle_signal(signo, &info, &sigact, regs);
		return;
	}

	/*
	 * 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 */
	restore_saved_sigmask();
}
Ejemplo n.º 25
0
static void do_signal(struct pt_regs *regs)
{
	struct k_sigaction ka;
	siginfo_t info;
	int signr;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.	*/
		handle_signal(signr, &info, &ka, regs);
		return;
	}

	if (regs->regs[0]) {
		switch (regs->regs[2]) {
		case ERESTARTNOHAND:
		case ERESTARTSYS:
		case ERESTARTNOINTR:
			regs->regs[2] = regs->regs[0];
			regs->regs[7] = regs->regs[26];
			regs->cp0_epc -= 4;
			break;

		case ERESTART_RESTARTBLOCK:
			regs->regs[2] = current->thread.abi->restart;
			regs->regs[7] = regs->regs[26];
			regs->cp0_epc -= 4;
			break;
		}
		regs->regs[0] = 0;	/* Don't deal with this again.	*/
	}

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 26
0
static void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

	if (get_signal(&ksig)) {
		/* Actually deliver the signal */
		handle_signal(&ksig, regs);
		return;
	}

	/* Did we come from a system call? */
	if (in_syscall(regs)) {
		/* Avoid additional syscall restarting via ret_from_exception */
		forget_syscall(regs);

		/* Restart the system call - no handlers present */
		switch (regs->a0) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->a0 = regs->orig_a0;
			regs->pc -= TRAP0_SIZE;
			break;
		case -ERESTART_RESTARTBLOCK:
			regs->a0 = regs->orig_a0;
			regs_syscallid(regs) = __NR_restart_syscall;
			regs->pc -= TRAP0_SIZE;
			break;
		}
	}

	/*
	 * If there is no signal to deliver, we just put the saved
	 * sigmask back.
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 27
0
/*
 * handle a potential signal
 */
static void do_signal(struct pt_regs *regs)
{
	struct k_sigaction ka;
	siginfo_t info;
	int signr;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		if (handle_signal(signr, &info, &ka, regs) == 0) {
		}

		return;
	}

	/* did we come from a system call? */
	if (regs->orig_d0 >= 0) {
		/* restart the system call - no handlers present */
		switch (regs->d0) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->d0 = regs->orig_d0;
			stepback(regs);
			break;

		case -ERESTART_RESTARTBLOCK:
			regs->d0 = __NR_restart_syscall;
			stepback(regs);
			break;
		}
	}

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	restore_saved_sigmask();
}
Ejemplo n.º 28
0
Archivo: signal.c Proyecto: 4atty/linux
/*
 * 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;

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

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &info, &ka, regs);
		return;
	}

	/* 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 */
	restore_saved_sigmask();
}
void do_signal(struct pt_regs *regs)
{
	struct k_sigaction ka;
	siginfo_t info;
	int signr;
	int restart_scall;

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

	restart_scall = in_syscall(regs) && syscall_restartable(regs);

	if (signr > 0) {
		if (restart_scall) {
			arc_restart_syscall(&ka, regs);
			syscall_wont_restart(regs);	/* No more restarts */
		}
		handle_signal(signr, &ka, &info, regs);
		return;
	}

	if (restart_scall) {
		/* No handler for syscall: restart it */
		if (regs->r0 == -ERESTARTNOHAND ||
		    regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) {
			regs->r0 = regs->orig_r0;
			regs->ret -= 4;
		} else if (regs->r0 == -ERESTART_RESTARTBLOCK) {
			regs->r8 = __NR_restart_syscall;
			regs->ret -= 4;
		}
		syscall_wont_restart(regs);	/* No more restarts */
	}

	/* If there's no signal to deliver, restore the saved sigmask back */
	restore_saved_sigmask();
}
Ejemplo n.º 30
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.
 */
static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
{
	struct k_sigaction ka;
	int restart_syscall;
	sigset_t *oldset = sigmask_to_save();
	siginfo_t info;
	int signr;
	
	/* It's a lot of work and synchronization to add a new ptrace
	 * register for GDB to save and restore in order to get
	 * orig_i0 correct for syscall restarts when debugging.
	 *
	 * Although it should be the case that most of the global
	 * registers are volatile across a system call, glibc already
	 * depends upon that fact that we preserve them.  So we can't
	 * just use any global register to save away the orig_i0 value.
	 *
	 * In particular %g2, %g3, %g4, and %g5 are all assumed to be
	 * preserved across a system call trap by various pieces of
	 * code in glibc.
	 *
	 * %g7 is used as the "thread register".   %g6 is not used in
	 * any fixed manner.  %g6 is used as a scratch register and
	 * a compiler temporary, but it's value is never used across
	 * a system call.  Therefore %g6 is usable for orig_i0 storage.
	 */
	if (pt_regs_is_syscall(regs) &&
	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
		regs->u_regs[UREG_G6] = orig_i0;

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

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

	restart_syscall = 0;
	if (pt_regs_is_syscall(regs) &&
	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
		restart_syscall = 1;
		orig_i0 = regs->u_regs[UREG_G6];
	}

	if (signr > 0) {
		if (restart_syscall)
			syscall_restart(orig_i0, regs, &ka.sa);
		handle_signal(signr, &ka, &info, oldset, regs);
		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;
		pt_regs_clear_syscall(regs);
	}
	if (restart_syscall &&
	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
		regs->u_regs[UREG_G1] = __NR_restart_syscall;
		regs->tpc -= 4;
		regs->tnpc -= 4;
		pt_regs_clear_syscall(regs);
	}

	/* If there's no signal to deliver, we just put the saved sigmask
	 * back
	 */
	restore_saved_sigmask();
}