/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = sig; int ret; /* * translate the signal */ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) usig = thread->exec_domain->signal_invmap[usig]; /* * Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); if (ret != 0) { force_sigsegv(sig, tsk); return; } signal_delivered(sig, info, ka, regs, 0); }
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) { int err = 0; __get_user_error(regs->ARM_r0, &sc->arm_r0, err); __get_user_error(regs->ARM_r1, &sc->arm_r1, err); __get_user_error(regs->ARM_r2, &sc->arm_r2, err); __get_user_error(regs->ARM_r3, &sc->arm_r3, err); __get_user_error(regs->ARM_r4, &sc->arm_r4, err); __get_user_error(regs->ARM_r5, &sc->arm_r5, err); __get_user_error(regs->ARM_r6, &sc->arm_r6, err); __get_user_error(regs->ARM_r7, &sc->arm_r7, err); __get_user_error(regs->ARM_r8, &sc->arm_r8, err); __get_user_error(regs->ARM_r9, &sc->arm_r9, err); __get_user_error(regs->ARM_r10, &sc->arm_r10, err); __get_user_error(regs->ARM_fp, &sc->arm_fp, err); __get_user_error(regs->ARM_ip, &sc->arm_ip, err); __get_user_error(regs->ARM_sp, &sc->arm_sp, err); __get_user_error(regs->ARM_lr, &sc->arm_lr, err); __get_user_error(regs->ARM_pc, &sc->arm_pc, err); __get_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); err |= !valid_user_regs(regs); return err; }
static int restore_sigframe(struct pt_regs *regs, struct rt_sigframe __user *sf) { sigset_t set; int i, err; struct aux_context __user *aux = (struct aux_context __user *)sf->uc.uc_mcontext.__reserved; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) set_current_blocked(&set); for (i = 0; i < 31; i++) __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], err); __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); /* * Avoid sys_rt_sigreturn() restarting. */ regs->syscallno = ~0UL; err |= !valid_user_regs(®s->user_regs); if (err == 0) err |= restore_fpsimd_context(&aux->fpsimd); return err; }
static inline void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, int syscall) { int ret; /* * Set up the stack frame */ ret = setup_rt_frame(sig, ka, info, oldset, regs); /* * Check that the resulting registers are sane */ ret |= !valid_user_regs(regs); /* * Block the signal if we were unsuccessful. */ if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); sigaddset(¤t->blocked, sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } if (ret == 0) return; force_sigsegv(sig, current); }
static int compat_gpr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { struct pt_regs newregs; int ret = 0; unsigned int i, start, num_regs; /* Calculate the number of AArch32 registers contained in count */ num_regs = count / regset->size; /* Convert pos into an register number */ start = pos / regset->size; if (start + num_regs > regset->n) return -EIO; newregs = *task_pt_regs(target); for (i = 0; i < num_regs; ++i) { unsigned int idx = start + i; compat_ulong_t reg; if (kbuf) { memcpy(®, kbuf, sizeof(reg)); kbuf += sizeof(reg); } else { ret = copy_from_user(®, ubuf, sizeof(reg)); if (ret) { ret = -EFAULT; break; } ubuf += sizeof(reg); } switch (idx) { case 15: newregs.pc = reg; break; case 16: newregs.pstate = reg; break; case 17: newregs.orig_x0 = reg; break; default: newregs.regs[idx] = reg; } } if (valid_user_regs(&newregs.user_regs)) *task_pt_regs(target) = newregs; else ret = -EINVAL; return ret; }
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) { int err = 0; #define COPY(x) err |= __get_user(regs->x, &sc->x) COPY(sr); COPY(pc); COPY(lr); COPY(sp); COPY(r12); COPY(r11); COPY(r10); COPY(r9); COPY(r8); COPY(r7); COPY(r6); COPY(r5); COPY(r4); COPY(r3); COPY(r2); COPY(r1); COPY(r0); #undef COPY /* * Don't allow anyone to pretend they're running in supervisor * mode or something... */ err |= !valid_user_regs(regs); return err; }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* * Increment event counter and perform fixup for the pre-signal * frame. */ rseq_signal_deliver(ksig, regs); /* * Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(ksig, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); signal_setup_done(ret, ksig, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = ksig->sig; int ret; /* * Set up the stack frame */ if (is_compat_task()) { if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = compat_setup_rt_frame(usig, ksig, oldset, regs); else ret = compat_setup_frame(usig, ksig, oldset, regs); } else { ret = setup_rt_frame(usig, ksig, oldset, regs); } /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(®s->user_regs, current); /* * Fast forward the stepping logic so we step into the signal * handler. */ if (!ret) user_fastforward_single_step(tsk); signal_setup_done(ret, ksig, 0); }
static int handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, int syscall) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; int usig = sig; int ret; if (syscall) { switch (regs->ARM_r0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->ARM_r0 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->ARM_r0 = -EINTR; break; } case -ERESTARTNOINTR: setup_syscall_restart(regs); } } if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) usig = thread->exec_domain->signal_invmap[usig]; if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); ret |= !valid_user_regs(regs); if (ret != 0) { force_sigsegv(sig, tsk); return ret; } spin_lock_irq(&tsk->sighand->siglock); sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(&tsk->blocked, sig); recalc_sigpending(); spin_unlock_irq(&tsk->sighand->siglock); return 0; }
/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs, int syscall) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = sig; int ret; /* * If we were from a system call, check for system call restarting... */ if (syscall) { switch (regs->UCreg_00) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->UCreg_00 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->UCreg_00 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: setup_syscall_restart(regs); } } /* * translate the signal */ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) usig = thread->exec_domain->signal_invmap[usig]; /* * Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); if (ret != 0) { force_sigsegv(sig, tsk); return; } signal_delivered(sig, info, ka, regs, 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); }
static int compat_gpr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { struct pt_regs newregs; int ret = 0; unsigned int i, start, num_regs; /* Calculate the number of AArch32 registers contained in count */ num_regs = count / regset->size; /* Convert pos into an register number */ start = pos / regset->size; if (start + num_regs > regset->n) return -EIO; newregs = *task_pt_regs(target); for (i = 0; i < num_regs; ++i) { unsigned int idx = start + i; void *reg; switch (idx) { case 15: reg = (void *)&newregs.pc; break; case 16: reg = (void *)&newregs.pstate; break; case 17: reg = (void *)&newregs.orig_x0; break; default: reg = (void *)&newregs.regs[idx]; } ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t)); if (ret) goto out; else ubuf += sizeof(compat_ulong_t); } if (valid_user_regs(&newregs.user_regs)) *task_pt_regs(target) = newregs; else ret = -EINVAL; out: return ret; }
static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) { struct aux_sigframe __user *aux; sigset_t set; int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) { sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); __get_user_error(regs->ARM_ORIG_r0, &sf->uc.uc_mcontext.arm_old_r0, err); __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); err |= !valid_user_regs(regs); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; #ifdef CONFIG_CRUNCH if (err == 0) err |= restore_crunch_context(&aux->crunch); #endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= restore_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP if (err == 0) err |= restore_vfp_context(&aux->vfp); #endif return err; }
static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) { sigset_t set; int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) { sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); } err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00); err |= __get_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01); err |= __get_user(regs->UCreg_02, &sf->uc.uc_mcontext.regs.UCreg_02); err |= __get_user(regs->UCreg_03, &sf->uc.uc_mcontext.regs.UCreg_03); err |= __get_user(regs->UCreg_04, &sf->uc.uc_mcontext.regs.UCreg_04); err |= __get_user(regs->UCreg_05, &sf->uc.uc_mcontext.regs.UCreg_05); err |= __get_user(regs->UCreg_06, &sf->uc.uc_mcontext.regs.UCreg_06); err |= __get_user(regs->UCreg_07, &sf->uc.uc_mcontext.regs.UCreg_07); err |= __get_user(regs->UCreg_08, &sf->uc.uc_mcontext.regs.UCreg_08); err |= __get_user(regs->UCreg_09, &sf->uc.uc_mcontext.regs.UCreg_09); err |= __get_user(regs->UCreg_10, &sf->uc.uc_mcontext.regs.UCreg_10); err |= __get_user(regs->UCreg_11, &sf->uc.uc_mcontext.regs.UCreg_11); err |= __get_user(regs->UCreg_12, &sf->uc.uc_mcontext.regs.UCreg_12); err |= __get_user(regs->UCreg_13, &sf->uc.uc_mcontext.regs.UCreg_13); err |= __get_user(regs->UCreg_14, &sf->uc.uc_mcontext.regs.UCreg_14); err |= __get_user(regs->UCreg_15, &sf->uc.uc_mcontext.regs.UCreg_15); err |= __get_user(regs->UCreg_16, &sf->uc.uc_mcontext.regs.UCreg_16); err |= __get_user(regs->UCreg_17, &sf->uc.uc_mcontext.regs.UCreg_17); err |= __get_user(regs->UCreg_18, &sf->uc.uc_mcontext.regs.UCreg_18); err |= __get_user(regs->UCreg_19, &sf->uc.uc_mcontext.regs.UCreg_19); err |= __get_user(regs->UCreg_20, &sf->uc.uc_mcontext.regs.UCreg_20); err |= __get_user(regs->UCreg_21, &sf->uc.uc_mcontext.regs.UCreg_21); err |= __get_user(regs->UCreg_22, &sf->uc.uc_mcontext.regs.UCreg_22); err |= __get_user(regs->UCreg_23, &sf->uc.uc_mcontext.regs.UCreg_23); err |= __get_user(regs->UCreg_24, &sf->uc.uc_mcontext.regs.UCreg_24); err |= __get_user(regs->UCreg_25, &sf->uc.uc_mcontext.regs.UCreg_25); err |= __get_user(regs->UCreg_26, &sf->uc.uc_mcontext.regs.UCreg_26); err |= __get_user(regs->UCreg_fp, &sf->uc.uc_mcontext.regs.UCreg_fp); err |= __get_user(regs->UCreg_ip, &sf->uc.uc_mcontext.regs.UCreg_ip); err |= __get_user(regs->UCreg_sp, &sf->uc.uc_mcontext.regs.UCreg_sp); err |= __get_user(regs->UCreg_lr, &sf->uc.uc_mcontext.regs.UCreg_lr); err |= __get_user(regs->UCreg_pc, &sf->uc.uc_mcontext.regs.UCreg_pc); err |= __get_user(regs->UCreg_asr, &sf->uc.uc_mcontext.regs.UCreg_asr); err |= !valid_user_regs(regs); return err; }
/* * this routine will put a word on the processes privileged stack. * the offset is how far from the base addr as stored in the THREAD. * this routine assumes that all the privileged stacks are in our * data space. */ static inline int put_user_reg(struct task_struct *task, int offset, long data) { struct pt_regs newregs, *regs = task_pt_regs(task); int ret = -EINVAL; newregs = *regs; newregs.uregs[offset] = data; if (valid_user_regs(&newregs)) { regs->uregs[offset] = data; ret = 0; } return ret; }
/* * OK, we're invoking a handler */ static int handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; int usig = sig; int ret; /* * translate the signal */ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) usig = thread->exec_domain->signal_invmap[usig]; /* * Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); if (ret != 0) { force_sigsegv(sig, tsk); return ret; } /* * Block the signal if we were successful. */ spin_lock_irq(&tsk->sighand->siglock); sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(&tsk->blocked, sig); recalc_sigpending(); spin_unlock_irq(&tsk->sighand->siglock); return 0; }
static int gpr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { int ret; struct user_pt_regs newregs; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1); if (ret) return ret; if (!valid_user_regs(&newregs)) return -EINVAL; task_pt_regs(target)->user_regs = newregs; return 0; }
/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { struct task_struct *tsk = current; int usig = sig; int ret; /* * translate the signal */ if (usig < 32 && tsk->exec_domain && tsk->exec_domain->signal_invmap) usig = tsk->exec_domain->signal_invmap[usig]; /* * Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); if (ret == 0) { if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { spin_lock_irq(&tsk->sigmask_lock); sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask); sigaddset(&tsk->blocked, sig); recalc_sigpending(tsk); spin_unlock_irq(&tsk->sigmask_lock); } return; } if (sig == SIGSEGV) ka->sa.sa_handler = SIG_DFL; force_sig(SIGSEGV, tsk); }
static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) { char __user *aux; sigset_t set; int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) set_current_blocked(&set); __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); err |= !valid_user_regs(regs); aux = (char __user *) sf->uc.uc_regspace; #ifdef CONFIG_CRUNCH if (err == 0) err |= restore_crunch_context(&aux); #endif #ifdef CONFIG_IWMMXT if (err == 0) err |= restore_iwmmxt_context(&aux); #endif #ifdef CONFIG_VFP if (err == 0) err |= restore_vfp_context(&aux); #endif return err; }
static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs) { struct pt_regs newregs; int ret; ret = -EFAULT; if (copy_from_user(&newregs, uregs, sizeof(newregs)) == 0) { struct pt_regs *regs = get_user_regs(tsk); ret = -EINVAL; if (valid_user_regs(&newregs)) { *regs = newregs; ret = 0; } } return ret; }
/* * OK, we're invoking a handler */ static int handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; int usig = sig; int ret; /* * translate the signal */ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) usig = thread->exec_domain->signal_invmap[usig]; /* * Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); if (ret != 0) { #ifdef CONFIG_SHLOG_SYSTEM rlog_app_start( current, 0, 0, sig, 0, regs ); #endif /* CONFIG_SHLOG_SYSTEM */ force_sigsegv(sig, tsk); return ret; } /* * Block the signal if we were successful. */ block_sigmask(ka, sig); return 0; }
/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs) { struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = sig; int ret; /* * Set up the stack frame */ if (is_compat_task()) { if (ka->sa.sa_flags & SA_SIGINFO) ret = compat_setup_rt_frame(usig, ka, info, oldset, regs); else ret = compat_setup_frame(usig, ka, oldset, regs); } else { ret = setup_rt_frame(usig, ka, info, oldset, regs); } /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(®s->user_regs); if (ret != 0) { force_sigsegv(sig, tsk); return; } /* * Fast forward the stepping logic so we step into the signal * handler. */ user_fastforward_single_step(tsk); signal_delivered(sig, info, ka, regs, 0); }
static inline void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs *regs, int syscall) { int ret; /* * Set up the stack frame */ ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); /* * Check that the resulting registers are sane */ ret |= !valid_user_regs(regs); /* * Block the signal if we were successful. */ if (ret != 0) force_sigsegv(sig, current); else signal_delivered(sig, info, ka, regs, 0); }
/* * OK, we're invoking a handler */ static int handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, int syscall) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; int usig = sig; int ret; /* * If we were from a system call, check for system call restarting... */ if (syscall) { switch (regs->ARM_r0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->ARM_r0 = -EINTR; break; case -ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->ARM_r0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: setup_syscall_restart(regs); } } /* * translate the signal */ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) usig = thread->exec_domain->signal_invmap[usig]; /* * Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(usig, ka, info, oldset, regs); else ret = setup_frame(usig, ka, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); if (ret != 0) { force_sigsegv(sig, tsk); return ret; } /* * Block the signal if we were successful. */ spin_lock_irq(&tsk->sighand->siglock); sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(&tsk->blocked, sig); recalc_sigpending(); spin_unlock_irq(&tsk->sighand->siglock); return 0; }