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; }
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); }
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); }
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); }