arch/mips/kernel/signal.c

Source file repositories/reference/linux-study-clean/arch/mips/kernel/signal.c

File Facts

System
Linux kernel
Corpus path
arch/mips/kernel/signal.c
Extension
.c
Size
23466 bytes
Lines
970
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: syscall or user/kernel boundary
Status
core implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

SYSCALL_DEFINE1(sigsuspend, sigset_t __user *, uset)
{
	return sys_rt_sigsuspend(uset, sizeof(sigset_t));
}
#endif

#ifdef CONFIG_TRAD_SIGNALS
SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act,
	struct sigaction __user *, oact)
{
	struct k_sigaction new_ka, old_ka;
	int ret;
	int err = 0;

	if (act) {
		old_sigset_t mask;

		if (!access_ok(act, sizeof(*act)))
			return -EFAULT;
		err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
		err |= __get_user(mask, &act->sa_mask.sig[0]);
		if (err)
			return -EFAULT;

		siginitset(&new_ka.sa.sa_mask, mask);
	}

	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

	if (!ret && oact) {
		if (!access_ok(oact, sizeof(*oact)))
			return -EFAULT;
		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
		err |= __put_user(0, &oact->sa_mask.sig[1]);
		err |= __put_user(0, &oact->sa_mask.sig[2]);
		err |= __put_user(0, &oact->sa_mask.sig[3]);
		if (err)
			return -EFAULT;
	}

	return ret;
}
#endif

#ifdef CONFIG_TRAD_SIGNALS
asmlinkage void sys_sigreturn(void)
{
	struct sigframe __user *frame;
	struct pt_regs *regs;
	sigset_t blocked;
	int sig;

	regs = current_pt_regs();
	frame = (struct sigframe __user *)regs->regs[29];
	if (!access_ok(frame, sizeof(*frame)))
		goto badframe;
	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
		goto badframe;

	set_current_blocked(&blocked);

	sig = restore_sigcontext(regs, &frame->sf_sc);
	if (sig < 0)
		goto badframe;
	else if (sig)
		force_sig(sig);

	/*
	 * Don't let your children do this ...
	 */
	__asm__ __volatile__(
		"move\t$29, %0\n\t"
		"j\tsyscall_exit"
		: /* no outputs */
		: "r" (regs));
	/* Unreached */

badframe:
	force_sig(SIGSEGV);
}
#endif /* CONFIG_TRAD_SIGNALS */

asmlinkage void sys_rt_sigreturn(void)
{
	struct rt_sigframe __user *frame;
	struct pt_regs *regs;
	sigset_t set;

Annotation

Implementation Notes