static int setup_rt_frame()

in kernel/signal.c [96:132]


static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
			  struct pt_regs *regs)
{
	int err = 0;
	struct rt_sigframe __user *frame;
	struct hexagon_vdso *vdso = current->mm->context.vdso;

	frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));

	if (!access_ok(frame, sizeof(struct rt_sigframe)))
		return -EFAULT;

	if (copy_siginfo_to_user(&frame->info, &ksig->info))
		return -EFAULT;

	/* The on-stack signal trampoline is no longer executed;
	 * however, the libgcc signal frame unwinding code checks for
	 * the presence of these two numeric magic values.
	 */
	err |= __put_user(0x7800d166, &frame->tramp[0]);
	err |= __put_user(0x5400c004, &frame->tramp[1]);
	err |= setup_sigcontext(regs, &frame->uc.uc_mcontext);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs));
	if (err)
		return -EFAULT;

	/* Load r0/r1 pair with signumber/siginfo pointer... */
	regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32)
		| (unsigned long long)ksig->sig;
	regs->r02 = (unsigned long) &frame->uc;
	regs->r31 = (unsigned long) vdso->rt_signal_trampoline;
	pt_psp(regs) = (unsigned long) frame;
	pt_set_elr(regs, (unsigned long)ksig->ka.sa.sa_handler);

	return 0;
}