Example #1
0
static int
setup_rt_frame(int usig, struct k_sigaction* ka,siginfo_t* info,
               sigset_t* set,struct pt_regs* regs)
{
    struct rt_sigframe __user *frame=get_sigframe(ka,regs,sizeof(*frame));
    stack_t stack;
    int err=0;

    if(!frame) {
        return 1;
    }

    err |= copy_siginfo_to_user(&frame->info,info);
    err |= __put_user(0,&frame->uc.uc_flags);
    err |= __put_user(NULL,&frame->uc.uc_link);

    memset(&stack,0,sizeof(stack));
    stack.ss_sp=(void __user*)current->sas_ss_sp;
    stack.ss_flags=sas_ss_flags(regs->sp);
    stack.ss_size=current->sas_ss_size;
    err |= __copy_to_user(&frame->uc.uc_stack,&stack,sizeof(stack));

    err |= setup_sigcontext(&frame->uc.uc_mcontext,regs,set->sig[0]);
    err |= __copy_to_user(&frame->uc.uc_sigmask,set,sizeof(*set));

    if(err==0) {
        err=setup_rt_return(regs,frame,ka,usig);
    }

    return err;
}
Example #2
0
static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
	       sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe __user *frame;
	int err = 0;

	frame = get_sigframe(ka, regs, sizeof(*frame));
	err = -EFAULT;
	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		goto out;

	/*
	 * Set up the return code:
	 *
	 *	mov	r8, __NR_rt_sigreturn
	 *	scall
	 *
	 * Note: This will blow up since we're using a non-executable
	 * stack. Better use SA_RESTORER.
	 */
#if __NR_rt_sigreturn > 127
# error __NR_rt_sigreturn must be < 127 to fit in a short mov
#endif
	err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20),
			 &frame->retcode);

	err |= copy_siginfo_to_user(&frame->info, info);

	/* Set up the ucontext */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	if (err)
		goto out;

	regs->r12 = sig;
	regs->r11 = (unsigned long) &frame->info;
	regs->r10 = (unsigned long) &frame->uc;
	regs->sp = (unsigned long) frame;
	if (ka->sa.sa_flags & SA_RESTORER)
		regs->lr = (unsigned long)ka->sa.sa_restorer;
	else {
		printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n",
		       current->comm, current->pid);
		regs->lr = (unsigned long) &frame->retcode;
	}

	pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n",
		 current->comm, current->pid, sig, regs->sp,
		 regs->pc, ka->sa.sa_handler, regs->lr);

	regs->pc = (unsigned long) ka->sa.sa_handler;

out:
	return err;
}
Example #3
0
static int
setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe __user *frame = get_sigframe(ksig, regs, sizeof(*frame));
	int err = 0;

	if (!frame)
		return 1;

	err |= copy_siginfo_to_user(&frame->info, &ksig->info);

	__put_user_error(0, &frame->sig.uc.uc_flags, err);
	__put_user_error(NULL, &frame->sig.uc.uc_link, err);

	err |= __save_altstack(&frame->sig.uc.uc_stack, regs->ARM_sp);
	err |= setup_sigframe(&frame->sig, regs, set);
	if (err == 0)
		err = setup_return(regs, ksig, frame->sig.retcode, frame);

	if (err == 0) {
		/*
		 * For realtime signals we must also set the second and third
		 * arguments for the signal handler.
		 *   -- Peter Maydell <*****@*****.**> 2000-12-06
		 */
		regs->ARM_r1 = (unsigned long)&frame->info;
		regs->ARM_r2 = (unsigned long)&frame->sig.uc;
	}

	return err;
}
Example #4
0
static int
setup_rt_frame(struct ksignal *ksig, sigset_t * set, struct pt_regs *regs)
{
	struct rt_sigframe __user *frame =
	    get_sigframe(ksig, regs, sizeof(*frame));
	int err = 0;

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

	__put_user_error(0, &frame->uc.uc_flags, err);
	__put_user_error(NULL, &frame->uc.uc_link, err);

	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
	err |= setup_sigframe(frame, regs, set);
	if (err == 0) {
		setup_return(regs, ksig, frame);
		if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
			err |= copy_siginfo_to_user(&frame->info, &ksig->info);
			regs->uregs[1] = (unsigned long)&frame->info;
			regs->uregs[2] = (unsigned long)&frame->uc;
		}
	}
	return err;
}
Example #5
0
static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
			  sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe __user *frame;
	int err = 0;

	frame = get_sigframe(ka, regs);
	if (!frame)
		return 1;

	__put_user_error(0, &frame->uc.uc_flags, err);
	__put_user_error(NULL, &frame->uc.uc_link, err);

	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
	err |= setup_sigframe(frame, regs, set);
	if (err == 0) {
		setup_return(regs, ka, frame, usig);
		if (ka->sa.sa_flags & SA_SIGINFO) {
			err |= copy_siginfo_to_user(&frame->info, info);
			regs->regs[1] = (unsigned long)&frame->info;
			regs->regs[2] = (unsigned long)&frame->uc;
		}
	}

	return err;
}
Example #6
0
/*
 * Set up a signal frame for a "real-time" signal handler
 * (one which gets siginfo).
 */
static void
handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
		 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
		 unsigned long newsp)
{
	struct rt_sigframe __user *rt_sf;
	struct mcontext __user *frame;
	unsigned long origsp = newsp;

	/* Set up Signal Frame */
	/* Put a Real Time Context onto stack */
	newsp -= sizeof(*rt_sf);
	rt_sf = (struct rt_sigframe __user *) newsp;

	/* create a stack frame for the caller of the handler */
	newsp -= __SIGNAL_FRAMESIZE + 16;

	if (verify_area(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
		goto badframe;

	/* Put the siginfo & fill in most of the ucontext */
	if (copy_siginfo_to_user(&rt_sf->info, info)
	    || __put_user(0, &rt_sf->uc.uc_flags)
	    || __put_user(0, &rt_sf->uc.uc_link)
	    || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
	    || __put_user(sas_ss_flags(regs->gpr[1]),
			  &rt_sf->uc.uc_stack.ss_flags)
	    || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
	    || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
	    || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
		goto badframe;

	/* Save user registers on the stack */
	frame = &rt_sf->uc.uc_mcontext;
	if (save_user_regs(regs, frame, __NR_rt_sigreturn))
		goto badframe;

	if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
		goto badframe;
	regs->gpr[1] = newsp;
	regs->gpr[3] = sig;
	regs->gpr[4] = (unsigned long) &rt_sf->info;
	regs->gpr[5] = (unsigned long) &rt_sf->uc;
	regs->gpr[6] = (unsigned long) rt_sf;
	regs->nip = (unsigned long) ka->sa.sa_handler;
	regs->link = (unsigned long) frame->tramp;
	regs->trap = 0;

	return;

badframe:
#ifdef DEBUG_SIG
	printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
	       regs, frame, newsp);
#endif
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;
	force_sig(SIGSEGV, current);
}
Example #7
0
static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
			  struct pt_regs *regs,	int signr, sigset_t *set,
			  siginfo_t *info)
{
	struct rt_sigframe __user *frame;
	int err = 0;

	frame = get_sigframe(ka, regs, sizeof(*frame));
	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		goto give_sigsegv;

	/* Create siginfo.  */
	err |= copy_siginfo_to_user(&frame->rs_info, info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->rs_uc.uc_flags);
	err |= __put_user(NULL, &frame->rs_uc.uc_link);
	err |= __put_user((void __user *)current->sas_ss_sp,
	                  &frame->rs_uc.uc_stack.ss_sp);
	err |= __put_user(sas_ss_flags(regs->regs[29]),
	                  &frame->rs_uc.uc_stack.ss_flags);
	err |= __put_user(current->sas_ss_size,
	                  &frame->rs_uc.uc_stack.ss_size);
	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));

	if (err)
		goto give_sigsegv;

	/*
	 * Arguments to signal handler:
	 *
	 *   a0 = signal number
	 *   a1 = 0 (should be cause)
	 *   a2 = pointer to ucontext
	 *
	 * $25 and c0_epc point to the signal handler, $29 points to
	 * the struct rt_sigframe.
	 */
	regs->regs[ 4] = signr;
	regs->regs[ 5] = (unsigned long) &frame->rs_info;
	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
	regs->regs[29] = (unsigned long) frame;
	regs->regs[31] = (unsigned long) sig_return;
	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;

	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
	       current->comm, current->pid,
	       frame, regs->cp0_epc, regs->regs[31]);

	return 0;

give_sigsegv:
#ifdef CONFIG_TIVO
    _log_user_fault(__FUNCTION__, SIGSEGV, regs, current);
#endif
	force_sigsegv(signr, current);
	return -EFAULT;
}
Example #8
0
File: signal.c Project: 7799/linux
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
			   sigset_t *set, struct pt_regs * regs)
{
	int err = 0;
	rt_sigframe __user *frame;

	frame = get_sigframe(ka, regs, sizeof(rt_sigframe));

	if (frame == (void __user *) -1UL)
		goto give_sigsegv;

	if (copy_siginfo_to_user(&frame->info, info))
		goto give_sigsegv;

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->gprs[15]);
	err |= save_sigregs(regs, &frame->uc.uc_mcontext);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		goto give_sigsegv;

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
	if (ka->sa.sa_flags & SA_RESTORER) {
                regs->gprs[14] = (unsigned long)
			ka->sa.sa_restorer | PSW_ADDR_AMODE;
	} else {
                regs->gprs[14] = (unsigned long)
			frame->retcode | PSW_ADDR_AMODE;
		if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
			       (u16 __user *)(frame->retcode)))
			goto give_sigsegv;
	}

	/* Set up backchain. */
	if (__put_user(regs->gprs[15], (addr_t __user *) frame))
		goto give_sigsegv;

	/* Set up registers for signal handler */
	regs->gprs[15] = (unsigned long) frame;
	/* Force default amode and default user address space control. */
	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
		(PSW_USER_BITS & PSW_MASK_ASC) |
		(regs->psw.mask & ~PSW_MASK_ASC);
	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;

	regs->gprs[2] = map_signal(sig);
	regs->gprs[3] = (unsigned long) &frame->info;
	regs->gprs[4] = (unsigned long) &frame->uc;
	regs->gprs[5] = task_thread_info(current)->last_break;
	return 0;

give_sigsegv:
	force_sigsegv(sig, current);
	return -EFAULT;
}
Example #9
0
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
			   sigset_t *set, struct pt_regs * regs)
{
	int err = 0;
	rt_sigframe __user *frame;

	frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
	if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
		goto give_sigsegv;

	if (frame == (void __user *) -1UL)
		goto give_sigsegv;

	if (copy_siginfo_to_user(&frame->info, info))
		goto give_sigsegv;

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
	err |= __put_user(sas_ss_flags(regs->gprs[15]),
			  &frame->uc.uc_stack.ss_flags);
	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
	err |= save_sigregs(regs, &frame->uc.uc_mcontext);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		goto give_sigsegv;

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
	if (ka->sa.sa_flags & SA_RESTORER) {
                regs->gprs[14] = (unsigned long)
			ka->sa.sa_restorer | PSW_ADDR_AMODE;
	} else {
                regs->gprs[14] = (unsigned long)
			frame->retcode | PSW_ADDR_AMODE;
		if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
			       (u16 __user *)(frame->retcode)))
			goto give_sigsegv;
	}

	/* Set up backchain. */
	if (__put_user(regs->gprs[15], (addr_t __user *) frame))
		goto give_sigsegv;

	/* Set up registers for signal handler */
	regs->gprs[15] = (unsigned long) frame;
	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;

	regs->gprs[2] = map_signal(sig);
	regs->gprs[3] = (unsigned long) &frame->info;
	regs->gprs[4] = (unsigned long) &frame->uc;
	return 0;

give_sigsegv:
	force_sigsegv(sig, current);
	return -EFAULT;
}
Example #10
0
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
			  struct pt_regs *regs)
{
	unsigned long restorer;
	struct rt_sigframe __user *frame;
	int err = 0, sig = ksig->sig;

	frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		goto err;

	/* Always write at least the signal number for the stack backtracer. */
	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
		/* At sigreturn time, restore the callee-save registers too. */
		err |= copy_siginfo_to_user(&frame->info, &ksig->info);
		regs->flags |= PT_FLAGS_RESTORE_REGS;
	} else {
		err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
	}

	/* Create the ucontext.  */
	err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		goto err;

	restorer = VDSO_SYM(&__vdso_rt_sigreturn);
	if (ksig->ka.sa.sa_flags & SA_RESTORER)
		restorer = (unsigned long) ksig->ka.sa.sa_restorer;

	/*
	 * Set up registers for signal handler.
	 * Registers that we don't modify keep the value they had from
	 * user-space at the time we took the signal.
	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
	 * since some things rely on this (e.g. glibc's debug/segfault.c).
	 */
	regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
	regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
	regs->sp = (unsigned long) frame;
	regs->lr = restorer;
	regs->regs[0] = (unsigned long) sig;
	regs->regs[1] = (unsigned long) &frame->info;
	regs->regs[2] = (unsigned long) &frame->uc;
	regs->flags |= PT_FLAGS_CALLER_SAVES;
	return 0;

err:
	trace_unhandled_signal("bad sigreturn frame", regs,
			      (unsigned long)frame, SIGSEGV);
	return -EFAULT;
}
Example #11
0
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
			   sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe *frame;
	unsigned long retcode;
	int err = 0;

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

	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		goto segv_and_exit;

	err |= __put_user(&frame->info, &frame->pinfo);
	err |= __put_user(&frame->uc, &frame->puc);
	err |= copy_siginfo_to_user(&frame->info, info);

	/* Clear all the bits of the ucontext we don't use.  */
	err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));

	err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
				regs, set->sig[0]);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
	if (ka->sa.sa_flags & SA_RESTORER) {
		retcode = (unsigned long)ka->sa.sa_restorer;
	} else {
		retcode = (unsigned long)&frame->retcode;
		err |= __put_user(SWI_SYS_RT_SIGRETURN, &frame->retcode);
		flush_icache_range(retcode, retcode + 4);
	}

	if (err)
		goto segv_and_exit;

	if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
		regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
	else
		regs->ARM_r0 = sig;
	regs->ARM_sp = (unsigned long)frame;
	regs->ARM_lr = retcode;
	regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
#if defined(CONFIG_CPU_32)
	/* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
	if (ka->sa.sa_flags & SA_THIRTYTWO)
		regs->ARM_cpsr = USR_MODE;
#endif
	if (valid_user_regs(regs))
		return;

segv_and_exit:
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;
	force_sig(SIGSEGV, current);
}
Example #12
0
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
			  struct pt_regs *regs)
{
	struct rt_sigframe __user *frame;
	int err;
	unsigned long code;

	frame = get_sigframe(&ksig->ka, regs->REG_SP, sizeof(*frame));
	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		return -EFAULT;

	err = copy_siginfo_to_user(&frame->info, &ksig->info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(0, (unsigned long __user *)&frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->REG_SP);
	err |= setup_sigcontext(&frame->uc.uc_mcontext,
				regs, set->sig[0]);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	if (err)
		return -EFAULT;

	/* Set up to return from userspace.  */

	/* MOV D1Re0 (D1.0), #__NR_rt_sigreturn */
	code = 0x03000004 | (__NR_rt_sigreturn << 3);
	err |= __put_user(code, (unsigned long __user *)(&frame->retcode[0]));

	/* SWITCH #__METAG_SW_SYS */
	code = __METAG_SW_ENCODING(SYS);
	err |= __put_user(code, (unsigned long __user *)(&frame->retcode[1]));

	if (err)
		return -EFAULT;

	/* Set up registers for signal handler */
	regs->REG_RTP = (unsigned long) frame->retcode;
	regs->REG_SP = (unsigned long) frame + sizeof(*frame);
	regs->REG_ARG1 = ksig->sig;
	regs->REG_ARG2 = (unsigned long) &frame->info;
	regs->REG_ARG3 = (unsigned long) &frame->uc;
	regs->REG_PC = (unsigned long) ksig->ka.sa.sa_handler;

	pr_debug("SIG deliver (%s:%d): sp=%p pc=%08x pr=%08x\n",
		 current->comm, current->pid, frame, regs->REG_PC,
		 regs->REG_RTP);

	/* Now pass size of 'new code' into sigtramp so we can do a more
	 * effective cache flush - directed rather than 'full flush'.
	 */
	flush_cache_sigtramp(regs->REG_RTP, sizeof(frame->retcode));

	return 0;
}
Example #13
0
static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
	       sigset_t *set, struct pt_regs *regs)
{
	unsigned long oldsp, r26, err = 0;
	struct rt_sigframe __user *frame;

	oldsp = rdusp();
	frame = get_sigframe(ka, oldsp, sizeof(*frame));
	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		return -EFAULT;

	err |= copy_siginfo_to_user(&frame->info, info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(0, &frame->uc.uc_link);
	err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
	err |= __save_altstack(&frame->uc.uc_stack, oldsp);
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, 
				set->sig[0], oldsp);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		return -EFAULT;

	/* Set up to return from userspace.  If provided, use a stub
	   already in userspace.  */
	if (ka->ka_restorer) {
		r26 = (unsigned long) ka->ka_restorer;
	} else {
		err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
		err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn,
				  frame->retcode+1);
		err |= __put_user(INSN_CALLSYS, frame->retcode+2);
		imb();
		r26 = (unsigned long) frame->retcode;
	}

	if (err)
		return -EFAULT;

	/* "Return" to the handler */
	regs->r26 = r26;
	regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
	regs->r16 = sig;			  /* a0: signal number */
	regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */
	regs->r18 = (unsigned long) &frame->uc;	  /* a2: ucontext pointer */
	wrusp((unsigned long) frame);

#if DEBUG_SIG
	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
		current->comm, current->pid, frame, regs->pc, regs->r26);
#endif

	return 0;
}
Example #14
0
int setup_signal_stack_si(unsigned long stack_top, int sig,
			  struct k_sigaction *ka, struct pt_regs *regs,
			  siginfo_t *info, sigset_t *mask)
{
	struct rt_sigframe __user *frame;
	void __user *restorer;
	unsigned long save_sp = PT_REGS_SP(regs);
	int err = 0;

	stack_top &= -8UL;
	frame = (struct rt_sigframe __user *) stack_top - 1;
	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		return 1;

	restorer = frame->retcode;
	if(ka->sa.sa_flags & SA_RESTORER)
		restorer = ka->sa.sa_restorer;

	/* See comment above about why this is here */
	PT_REGS_SP(regs) = (unsigned long) frame;

	err |= __put_user(restorer, &frame->pretcode);
	err |= __put_user(sig, &frame->sig);
	err |= __put_user(&frame->info, &frame->pinfo);
	err |= __put_user(&frame->uc, &frame->puc);
	err |= copy_siginfo_to_user(&frame->info, info);
	err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
				     save_sp);

	/*
	 * This is movl $,%eax ; int $0x80
	 *
	 * WE DO NOT USE IT ANY MORE! It's only left here for historical
	 * reasons and because gdb uses it as a signature to notice
	 * signal handler stack frames.
	 */
	err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
	err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
	err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));

	if(err)
		goto err;

	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
	PT_REGS_EAX(regs) = (unsigned long) sig;
	PT_REGS_EDX(regs) = (unsigned long) &frame->info;
	PT_REGS_ECX(regs) = (unsigned long) &frame->uc;

	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
		ptrace_notify(SIGTRAP);
	return 0;

err:
	PT_REGS_SP(regs) = save_sp;
	return err;
}
Example #15
0
static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
	       sigset_t * set, struct pt_regs *regs)
{
	struct rt_sigframe *frame;
	int err = 0;

	frame = get_sigframe(ka, regs, sizeof(*frame));

	err |= __put_user((current_thread_info()->exec_domain
			   && current_thread_info()->exec_domain->signal_invmap
			   && sig < 32
			   ? current_thread_info()->exec_domain->
			   signal_invmap[sig] : sig), &frame->sig);

	err |= __put_user(&frame->info, &frame->pinfo);
	err |= __put_user(&frame->uc, &frame->puc);
	err |= copy_siginfo_to_user(&frame->info, info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(0, &frame->uc.uc_link);
	err |=
	    __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
	err |= __put_user(sas_ss_flags(rdusp()), &frame->uc.uc_stack.ss_flags);
	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
	err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs);
	err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	if (err)
		goto give_sigsegv;

	/* Set up registers for signal handler */
	wrusp((unsigned long)frame);
	if (current->personality & FDPIC_FUNCPTRS) {
		struct fdpic_func_descriptor __user *funcptr =
			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
		__get_user(regs->pc, &funcptr->text);
		__get_user(regs->p3, &funcptr->GOT);
	} else
		regs->pc = (unsigned long)ka->sa.sa_handler;
	regs->rets = SIGRETURN_STUB;

	regs->r0 = frame->sig;
	regs->r1 = (unsigned long)(&frame->info);
	regs->r2 = (unsigned long)(&frame->uc);

	return 0;

 give_sigsegv:
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;
	force_sig(SIGSEGV, current);
	return -EFAULT;
}
Example #16
0
/* grab and setup a signal frame.
 *
 * basically we stack a lot of state info, and arrange for the
 * user-mode program to return to the kernel using either a
 * trampoline which performs the syscall sigreturn, or a provided
 * user-mode trampoline.
 */
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
			  struct pt_regs *regs)
{
	struct rt_sigframe *frame;
	unsigned long return_ip;
	int err = 0;

	frame = get_sigframe(ksig, regs, sizeof(*frame));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		return -EFAULT;

	/* Create siginfo.  */
	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
		err |= copy_siginfo_to_user(&frame->info, &ksig->info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
	err |= setup_sigcontext(regs, &frame->uc.uc_mcontext);

	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	if (err)
		return -EFAULT;

	/* trampoline - the desired return ip is the retcode itself */
	return_ip = (unsigned long)&frame->retcode;
	/* This is:
		l.ori r11,r0,__NR_sigreturn
		l.sys 1
	 */
	err |= __put_user(0xa960,             (short *)(frame->retcode + 0));
	err |= __put_user(__NR_rt_sigreturn,  (short *)(frame->retcode + 2));
	err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
	err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));

	if (err)
		return -EFAULT;

	/* TODO what is the current->exec_domain stuff and invmap ? */

	/* Set up registers for signal handler */
	regs->pc = (unsigned long)ksig->ka.sa.sa_handler; /* what we enter NOW */
	regs->gpr[9] = (unsigned long)return_ip;     /* what we enter LATER */
	regs->gpr[3] = (unsigned long)ksig->sig;           /* arg 1: signo */
	regs->gpr[4] = (unsigned long)&frame->info;  /* arg 2: (siginfo_t*) */
	regs->gpr[5] = (unsigned long)&frame->uc;    /* arg 3: ucontext */

	/* actually move the usp to reflect the stacked frame */
	regs->sp = (unsigned long)frame;

	return 0;
}
Example #17
0
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
			   sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe __user *frame;
	int err = 0;

	frame = get_sigframe(ka, regs->spu, sizeof(*frame));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		goto give_sigsegv;

	err |= __put_user(sig, &frame->sig);
	if (err)
		goto give_sigsegv;

	err |= __put_user(&frame->info, &frame->pinfo);
	err |= __put_user(&frame->uc, &frame->puc);
	err |= copy_siginfo_to_user(&frame->info, info);
	if (err)
		goto give_sigsegv;

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(0, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->spu);
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		goto give_sigsegv;

	/* Set up to return from userspace.  */
	regs->lr = (unsigned long)ka->sa.sa_restorer;

	/* Set up registers for signal handler */
	regs->spu = (unsigned long)frame;
	regs->r0 = sig;	/* Arg for signal handler */
	regs->r1 = (unsigned long)&frame->info;
	regs->r2 = (unsigned long)&frame->uc;
	regs->bpc = (unsigned long)ka->sa.sa_handler;

	set_fs(USER_DS);

#if DEBUG_SIG
	printk("SIG deliver (%s:%d): sp=%p pc=%p\n",
		current->comm, current->pid, frame, regs->pc);
#endif

	return 0;

give_sigsegv:
	force_sigsegv(sig, current);
	return -EFAULT;
}
Example #18
0
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
{
    int err = 0;
    rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
    if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
        goto give_sigsegv;

    if (copy_siginfo_to_user(&frame->info, info))
        goto give_sigsegv;

    /* Create the ucontext.  */
    err |= __put_user(0, &frame->uc.uc_flags);
    err |= __put_user(0, &frame->uc.uc_link);
    err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
    err |= __put_user(sas_ss_flags(regs->gprs[15]),
                      &frame->uc.uc_stack.ss_flags);
    err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
    err |= save_sigregs(regs, &frame->uc.uc_mcontext);
    err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
    if (err)
        goto give_sigsegv;

    /* Set up to return from userspace.  If provided, use a stub
       already in userspace.  */
    if (ka->sa.sa_flags & SA_RESTORER) {
        regs->gprs[14] = FIX_PSW(ka->sa.sa_restorer);
    } else {
        regs->gprs[14] = FIX_PSW(frame->retcode);
        err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
                          (u16 *)(frame->retcode));
    }

    /* Set up backchain. */
    if (__put_user(regs->gprs[15], (addr_t *) frame))
        goto give_sigsegv;

    /* Set up registers for signal handler */
    regs->gprs[15] = (addr_t)frame;
    regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
    regs->psw.mask = _USER_PSW_MASK;

    regs->gprs[2] = map_signal(sig);
    regs->gprs[3] = (addr_t)&frame->info;
    regs->gprs[4] = (addr_t)&frame->uc;
    return;

give_sigsegv:
    if (sig == SIGSEGV)
        ka->sa.sa_handler = SIG_DFL;
    force_sig(SIGSEGV, current);
}
Example #19
0
static int ptrace_getsiginfo(struct task_struct *child, siginfo_t __user * data)
{
	siginfo_t lastinfo;

	spin_lock_irq(&child->sighand->siglock);
	if (likely(child->last_siginfo != NULL)) {
		memcpy(&lastinfo, child->last_siginfo, sizeof (siginfo_t));
		spin_unlock_irq(&child->sighand->siglock);
		return copy_siginfo_to_user(data, &lastinfo);
	}
	spin_unlock_irq(&child->sighand->siglock);
	return -EINVAL;
}
Example #20
0
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
			  struct pt_regs *regs)
{
	struct rt_sigframe *frame;
	int err = 0;
	unsigned char *ret;

	frame = get_sigframe(ksig, regs, sizeof(*frame));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		return -EFAULT;

	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
		err |= copy_siginfo_to_user(&frame->info, &ksig->info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(0, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, rdusp());
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
	err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		return -EFAULT;

	/* Set up to return from userspace.  */
	ret = frame->retcode;
	if (ksig->ka.sa.sa_flags & SA_RESTORER)
		ret = (unsigned char *)(ksig->ka.sa.sa_restorer);
	else {
		/* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
		err |= __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
				  (unsigned long *)(frame->retcode + 0));
		err |= __put_user(0x5700,
				  (unsigned short *)(frame->retcode + 4));
	}
	err |= __put_user(ret, &frame->pretcode);

	if (err)
		return -EFAULT;

	/* Set up registers for signal handler */
	wrusp((unsigned long) frame);
	regs->pc  = (unsigned long) ksig->ka.sa.sa_handler;
	regs->er0 = ksig->sig;
	regs->er1 = (unsigned long)&(frame->info);
	regs->er2 = (unsigned long)&frame->uc;
	regs->er5 = current->mm->start_data;	/* GOT base */

	return 0;
}
Example #21
0
static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
			    sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe *frame;
	int err = 0;

	frame = get_sigframe(ka, regs, sizeof(*frame));

	err |= copy_siginfo_to_user(&frame->info, info);

	/* Create the ucontext.  */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(0, &frame->uc.uc_link);
	err |= __put_user((void *)current->sas_ss_sp,
			  &frame->uc.uc_stack.ss_sp);
	err |= __put_user(sas_ss_flags(rdusp()),
			  &frame->uc.uc_stack.ss_flags);
	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
	err |= rt_setup_ucontext(&frame->uc, regs);
	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));

	/* Set up to return from userspace.  */
	err |= __put_user(frame->retcode, &frame->pretcode);

	/* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
	err != __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
			(long *)(frame->retcode + 0));
	err |= __put_user(0x5700, (short *)(frame->retcode + 4));

	if (err)
		goto give_sigsegv;

	/* Set up registers for signal handler */
	wrusp ((unsigned long) frame);
	regs->pc  = (unsigned long) ka->sa.sa_handler;
	regs->er0 = (current_thread_info()->exec_domain
		     && current_thread_info()->exec_domain->signal_invmap
		     && sig < 32
		     ? current_thread_info()->exec_domain->signal_invmap[sig]
		     : sig);
	regs->er1 = (unsigned long)&(frame->info);
	regs->er2 = (unsigned long)&frame->uc;
	regs->er5 = current->mm->start_data;	/* GOT base */

	return;

give_sigsegv:
	force_sigsegv(sig, current);
}
Example #22
0
static int setup_rt_frame(void *sig_return, struct ksignal *ksig,
			  struct pt_regs *regs, sigset_t *set)
{
	struct rt_sigframe __user *frame;
	int err = 0;

	frame = get_sigframe(ksig, regs, sizeof(*frame));
	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		return -EFAULT;

	/* Create siginfo.  */
	err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);

	/* Create the ucontext.	 */
	err |= __put_user(0, &frame->rs_uc.uc_flags);
	err |= __put_user(NULL, &frame->rs_uc.uc_link);
	err |= __save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));

	if (err)
		return -EFAULT;

	/*
	 * Arguments to signal handler:
	 *
	 *   a0 = signal number
	 *   a1 = 0 (should be cause)
	 *   a2 = pointer to ucontext
	 *
	 * $25 and c0_epc point to the signal handler, $29 points to
	 * the struct rt_sigframe.
	 */
	regs->regs[ 4] = ksig->sig;
	regs->regs[ 5] = (unsigned long) &frame->rs_info;
	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
	regs->regs[29] = (unsigned long) frame;
	regs->regs[31] = (unsigned long) sig_return;
	regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;

	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
	       current->comm, current->pid,
	       frame, regs->cp0_epc, regs->regs[31]);

	return 0;
}
Example #23
0
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
	struct pt_regs *regs)
{
	struct rt_sigframe __user *frame;
	long err = 0;

	frame = get_sigframe(ksig, regs, sizeof(*frame));
	if (!access_ok(frame, sizeof(*frame)))
		return -EFAULT;

	err |= copy_siginfo_to_user(&frame->info, &ksig->info);

	/* Create the ucontext. */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
	err |= setup_sigcontext(frame, regs);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		return -EFAULT;

	/* Set up to return from userspace. */
	regs->ra = (unsigned long)VDSO_SYMBOL(
		current->mm->context.vdso, rt_sigreturn);

	/*
	 * Set up registers for signal handler.
	 * Registers that we don't modify keep the value they had from
	 * user-space at the time we took the signal.
	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
	 * since some things rely on this (e.g. glibc's debug/segfault.c).
	 */
	regs->sepc = (unsigned long)ksig->ka.sa.sa_handler;
	regs->sp = (unsigned long)frame;
	regs->a0 = ksig->sig;                     /* a0: signal number */
	regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
	regs->a2 = (unsigned long)(&frame->uc);   /* a2: ucontext pointer */

#if DEBUG_SIG
	pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
		current->comm, task_pid_nr(current), ksig->sig,
		(void *)regs->sepc, (void *)regs->ra, frame);
#endif

	return 0;
}
Example #24
0
static int
setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
               sigset_t *set, struct pt_regs *regs)
{
    struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
    stack_t stack;
    int err = 0;

    if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
        return 1;

    __put_user_error(&frame->info, &frame->pinfo, err);
    __put_user_error(&frame->uc, &frame->puc, err);
    err |= copy_siginfo_to_user(&frame->info, info);

    __put_user_error(0, &frame->uc.uc_flags, err);
    __put_user_error(NULL, &frame->uc.uc_link, err);

    memset(&stack, 0, sizeof(stack));
    stack.ss_sp = (void *)current->sas_ss_sp;
    stack.ss_flags = sas_ss_flags(regs->ARM_sp);
    stack.ss_size = current->sas_ss_size;
    err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack));

    err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
                            regs, set->sig[0]);
    err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

    if (err == 0)
        err = setup_return(regs, ka, &frame->retcode, frame, usig);

    if (err == 0) {
        /*
         * For realtime signals we must also set the second and third
         * arguments for the signal handler.
         *   -- Peter Maydell <*****@*****.**> 2000-12-06
         */
        regs->ARM_r1 = (unsigned long)&frame->info;
        regs->ARM_r2 = (unsigned long)&frame->uc;
    }

    return err;
}
Example #25
0
static int ptrace_getsiginfo(struct task_struct *child, siginfo_t __user * data)
{
	siginfo_t lastinfo;
	int error = -ESRCH;

	read_lock(&tasklist_lock);
	if (likely(child->sighand != NULL)) {
		error = -EINVAL;
		spin_lock_irq(&child->sighand->siglock);
		if (likely(child->last_siginfo != NULL)) {
			lastinfo = *child->last_siginfo;
			error = 0;
		}
		spin_unlock_irq(&child->sighand->siglock);
	}
	read_unlock(&tasklist_lock);
	if (!error)
		return copy_siginfo_to_user(data, &lastinfo);
	return error;
}
Example #26
0
/*
 * Setup signal stack frame with siginfo structure
 */
static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
			  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(ka, regs, sizeof(struct rt_sigframe));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe)))
		goto	sigsegv;

	if (copy_siginfo_to_user(&frame->info, info))
		goto	sigsegv;

	/* 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)
		goto sigsegv;

	/* Load r0/r1 pair with signumber/siginfo pointer... */
	regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32)
		| (unsigned long long)signr;
	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)ka->sa.sa_handler);

	return 0;

sigsegv:
	force_sigsegv(signr, current);
	return -EFAULT;
}
Example #27
0
static int
setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe *frame;
	int err = 0;
	struct csky_vdso *vdso = current->mm->context.vdso;

	frame = get_sigframe(ksig, regs, sizeof(*frame));
	if (!access_ok(frame, sizeof(*frame)))
		return -EFAULT;

	err |= copy_siginfo_to_user(&frame->info, &ksig->info);

	/* Create the ucontext. */
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->usp);
	err |= setup_sigcontext(frame, regs);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		return -EFAULT;

	/* Set up to return from userspace. */
	regs->lr = (unsigned long)(vdso->rt_signal_retcode);

	/*
	 * Set up registers for signal handler.
	 * Registers that we don't modify keep the value they had from
	 * user-space at the time we took the signal.
	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
	 * since some things rely on this (e.g. glibc's debug/segfault.c).
	 */
	regs->pc  = (unsigned long)ksig->ka.sa.sa_handler;
	regs->usp = (unsigned long)frame;
	regs->a0  = ksig->sig;				/* a0: signal number */
	regs->a1  = (unsigned long)(&(frame->info));	/* a1: siginfo pointer */
	regs->a2  = (unsigned long)(&(frame->uc));	/* a2: ucontext pointer */

	return 0;
}
Example #28
0
int setup_signal_stack_si(unsigned long stack_top, int sig, 
			  struct k_sigaction *ka, struct pt_regs *regs,
			  siginfo_t *info, sigset_t *mask)
{
	unsigned long start;
	void *restorer;
	void *sip, *ucp, *fp;

	start = stack_top - signal_frame_si.common.len;
	sip = (void *) (start + signal_frame_si.si_index);
	ucp = (void *) (start + signal_frame_si.uc_index);
	fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));

	restorer = NULL;
	if(ka->sa.sa_flags & SA_RESTORER)
		restorer = ka->sa.sa_restorer;

	if(restorer == NULL)
		panic("setup_signal_stack_si - no restorer");

	if(copy_to_user((void *) start, signal_frame_si.common.data,
			signal_frame_si.common.len) ||
	   copy_to_user((void *) (start + signal_frame_si.common.sig_index), 
			&sig, sizeof(sig)) ||
	   copy_siginfo_to_user(sip, info) ||
	   copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
			sizeof(sip)) ||
	   copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
	   copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
			sizeof(ucp)) ||
	   copy_restorer(restorer, start, signal_frame_si.common.sr_index,
			 signal_frame_si.common.sr_relative))
		return(1);
	
	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
	PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
	return(0);
}
Example #29
0
static int
setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
	       sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
	int err = 0;

	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		return 1;

	preempt_disable();
	__put_user_error(&frame->info, &frame->pinfo, err);
	__put_user_error(&frame->uc, &frame->puc, err);
	err |= copy_siginfo_to_user(&frame->info, info);

	/* Clear all the bits of the ucontext we don't use.  */
	err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));

	err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
				regs, set->sig[0]);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	if (err == 0)
		err = setup_return(regs, ka, &frame->retcode, frame, usig);

	if (err == 0) {
		/*
		 * For realtime signals we must also set the second and third
		 * arguments for the signal handler.
		 *   -- Peter Maydell <*****@*****.**> 2000-12-06
		 */
		regs->ARM_r1 = (unsigned long)&frame->info;
		regs->ARM_r2 = (unsigned long)&frame->uc;
	}
	preempt_enable();
	return err;
}
Example #30
0
static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
                          sigset_t *set, struct pt_regs *regs)
{
    struct rt_sigframe __user *frame =
        get_sigframe(ka, regs, sizeof(*frame));
    stack_t stack;
    int err = 0;

    if (!frame)
        return 1;

    err |= copy_siginfo_to_user(&frame->info, info);

    err |= __put_user(0, &frame->sig.uc.uc_flags);
    err |= __put_user(NULL, &frame->sig.uc.uc_link);

    memset(&stack, 0, sizeof(stack));
    stack.ss_sp = (void __user *)current->sas_ss_sp;
    stack.ss_flags = sas_ss_flags(regs->UCreg_sp);
    stack.ss_size = current->sas_ss_size;
    err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack));

    err |= setup_sigframe(&frame->sig, regs, set);
    if (err == 0)
        err |= setup_return(regs, ka, frame->sig.retcode, frame, usig);

    if (err == 0) {
        /*
         * For realtime signals we must also set the second and third
         * arguments for the signal handler.
         */
        regs->UCreg_01 = (unsigned long)&frame->info;
        regs->UCreg_02 = (unsigned long)&frame->sig.uc;
    }

    return err;
}