示例#1
0
unsigned long
search_exception_table(unsigned long addr)
{
	unsigned long ret;

#ifndef CONFIG_MODULES
        addr &= 0x7fffffff;  /* remove amode bit from address */
	/* There is only the kernel to search.  */
	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
	if (ret) return FIX_PSW(ret);
#else
	/* The kernel is the last "module" -- no need to treat it special.  */
	struct module *mp;
        addr &= 0x7fffffff;  /* remove amode bit from address */
	for (mp = module_list; mp != NULL; mp = mp->next) {
		if (mp->ex_table_start == NULL)
			continue;
		ret = search_one_table(mp->ex_table_start,
				       mp->ex_table_end - 1, addr);
		if (ret) return FIX_PSW(ret);
	}
#endif

	return 0;
}
示例#2
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);
}
示例#3
0
static void setup_frame(int sig, struct k_sigaction *ka,
                        sigset_t *set, struct pt_regs * regs)
{
    sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
    if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
        goto give_sigsegv;

    if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
        goto give_sigsegv;

    if (save_sigregs(regs, &frame->sregs))
        goto give_sigsegv;
    if (__put_user(&frame->sregs, &frame->sc.sregs))
        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);
        if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
                       (u16 *)(frame->retcode)))
            goto give_sigsegv;
    }

    /* 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->sc;

    /* We forgot to include these in the sigcontext.
       To avoid breaking binary compatibility, they are passed as args. */
    regs->gprs[4] = current->thread.trap_no;
    regs->gprs[5] = current->thread.prot_addr;
    return;

give_sigsegv:
    if (sig == SIGSEGV)
        ka->sa.sa_handler = SIG_DFL;
    force_sig(SIGSEGV, current);
}
示例#4
0
static void *setup_frame_common(int sig, struct k_sigaction *ka,
			sigset_t *set, struct pt_regs * regs,
				int frame_size,u16 retcode)
	{
	sigframe *frame;
	int err;

	frame = get_sigframe(ka, regs,frame_size);
	if (!access_ok(VERIFY_WRITE, frame,frame_size))
		return 0;
	err = save_sigregs(regs,&frame->sregs);
	if(!err)
		err=__put_user(&frame->sregs,&frame->sc.sregs);
	if(!err)

		err=__copy_to_user(&frame->sc.oldmask,&set->sig,SIGMASK_COPY_SIZE);
	if(!err)
	{
		regs->gprs[2]=(current->exec_domain
		           && current->exec_domain->signal_invmap
		           && sig < 32
		           ? current->exec_domain->signal_invmap[sig]
		           : sig);
		/* Set up registers for signal handler */
		regs->gprs[15] = (addr_t)frame;
		regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
	}
	/* 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(retcode, (u16 *)(frame->retcode));
	}
	return(err ? 0:frame);
}