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); __put_user_error(0, &frame->sig.uc.uc_flags, err); __put_user_error(NULL, &frame->sig.uc.uc_link, err); memset(&stack, 0, sizeof(stack)); stack.ss_sp = (void __user *)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->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) { regs->ARM_r1 = (unsigned long)&frame->info; regs->ARM_r2 = (unsigned long)&frame->sig.uc; } return err; }
int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, struct user_vfp_exc __user *ufp_exc) { struct thread_info *thread = current_thread_info(); struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; int err = 0; vfp_sync_hwstate(thread); err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs, sizeof(hwstate->fpregs)); __put_user_error(hwstate->fpscr, &ufp->fpscr, err); __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err); __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); if (err) return -EFAULT; vfp_flush_hwstate(thread); hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); return 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; }
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(0, &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; }
asmlinkage long sys_oabi_epoll_wait(int epfd, struct oabi_epoll_event __user *events, int maxevents, int timeout) { struct epoll_event *kbuf; mm_segment_t fs; long ret, err, i; if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event))) return -EINVAL; kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL); if (!kbuf) return -ENOMEM; fs = get_fs(); set_fs(KERNEL_DS); ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout); set_fs(fs); err = 0; for (i = 0; i < ret; i++) { __put_user_error(kbuf[i].events, &events->events, err); __put_user_error(kbuf[i].data, &events->data, err); events++; } kfree(kbuf); return err ? -EFAULT : ret; }
static int preserve_iwmmxt_context(struct iwmmxt_sigframe __user *frame) { char kbuf[sizeof(*frame) + 8]; struct iwmmxt_sigframe *kframe; int err = 0; /* the iWMMXt context must be 64 bit aligned */ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); if (test_thread_flag(TIF_USING_IWMMXT)) { kframe->magic = IWMMXT_MAGIC; kframe->size = IWMMXT_STORAGE_SIZE; iwmmxt_task_copy(current_thread_info(), &kframe->storage); err = __copy_to_user(frame, kframe, sizeof(*frame)); } else { /* * For bug-compatibility with older kernels, some space * has to be reserved for iWMMXt even if it's not used. * Set the magic and size appropriately so that properly * written userspace can skip it reliably: */ __put_user_error(DUMMY_MAGIC, &frame->magic, err); __put_user_error(IWMMXT_STORAGE_SIZE, &frame->size, err); } return err; }
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; }
static int copy_locked(void __user *uptr, void *kptr, size_t size, int write, void (*copyfn)(void *, void __user *)) { unsigned char v, __user *userptr = uptr; int err = 0; do { struct mm_struct *mm; if (write) { __put_user_error(0, userptr, err); __put_user_error(0, userptr + size - 1, err); } else { __get_user_error(v, userptr, err); __get_user_error(v, userptr + size - 1, err); } if (err) break; mm = current->mm; spin_lock(&mm->page_table_lock); if (page_present(mm, userptr, write) && page_present(mm, userptr + size - 1, write)) { copyfn(kptr, uptr); } else err = 1; spin_unlock(&mm->page_table_lock); } while (err); return err; }
static int setup_sigframe(struct rt_sigframe __user *sf, struct pt_regs *regs, sigset_t *set) { int i, err = 0; struct aux_context __user *aux = (struct aux_context __user *)sf->uc.uc_mcontext.__reserved; /* set up the stack frame for unwinding */ __put_user_error(regs->regs[29], &sf->fp, err); __put_user_error(regs->regs[30], &sf->lr, err); for (i = 0; i < 31; i++) __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], err); __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); if (err == 0) err |= preserve_fpsimd_context(&aux->fpsimd); /* set the "end" magic */ __put_user_error(0, &aux->end.magic, err); __put_user_error(0, &aux->end.size, err); return err; }
static int preserve_vfp_context(struct vfp_sigframe __user *frame) { const unsigned long magic = VFP_MAGIC; const unsigned long size = VFP_STORAGE_SIZE; int err = 0; __put_user_error(magic, &frame->magic, err); __put_user_error(size, &frame->size, err); if (err) return -EFAULT; return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc); }
static int restore_sigcontext(struct sigcontext *sc) { int err = 0; struct exregs_regs regs; struct restore_sigframe __user *restore; printk_dbg("%s called\n", __func__); /* User registers are saved/restored in user.S (__wombat_user_xxx) */ __get_user_error(regs.sp, &sc->arm_sp, err); __get_user_error(regs.ip, &sc->arm_pc, err); __get_user_error(regs.flags, &sc->arm_cpsr, err); restore = (void*)(regs.sp - sizeof(struct restore_sigframe)); __put_user_error(regs.ip, &restore->ret_ip, err); if (!err) { set_need_restart(current_thread_info(), (unsigned long)TASK_SIG_BASE + (((unsigned long)&__wombat_user_sigrestore) & ~PAGE_MASK), (unsigned long)sc, regs.flags); L4_Stop_Thread(current_thread_info()->user_tid); set_user_ipc_cancelled(current_thread_info()); } return err; }
/* * Save the current VFP state into the provided structures and prepare * for entry into a new function (signal handler). */ int vfp_preserve_user_hwstate(struct user_vfp __user *ufp, struct user_vfp_exc __user *ufp_exc) { struct thread_info *thread = current_thread_info(); struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; int err = 0; /* Ensure that the saved hwstate is up-to-date. */ vfp_sync_hwstate(thread); /* * Copy the floating point registers. There can be unused * registers see asm/hwcap.h for details. */ err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs, sizeof(hwstate->fpregs)); /* * Copy the status and control register. */ __put_user_error(hwstate->fpscr, &ufp->fpscr, err); /* * Copy the exception registers. */ __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err); __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); if (err) return -EFAULT; /* Ensure that VFP is disabled. */ vfp_flush_hwstate(thread); /* * As per the PCS, clear the length and stride bits before entry * to the signal handler. */ hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); /* * Disable VFP in the hwstate so that we can detect if it was * used by the signal handler. */ hwstate->fpexc &= ~FPEXC_EN; return 0; }
static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) { struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; int err; /* dump the hardware registers to the fpsimd_state structure */ fpsimd_preserve_current_state(); /* copy the FP and status/control registers */ err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); __put_user_error(fpsimd->fpsr, &ctx->fpsr, err); __put_user_error(fpsimd->fpcr, &ctx->fpcr, err); /* copy the magic/size information */ __put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err); __put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err); return err ? -EFAULT : 0; }
static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) { int err = 0; /* the iWMMXt context must be 64 bit aligned */ WARN_ON((unsigned long)frame & 7); __put_user_error(IWMMXT_MAGIC0, &frame->magic0, err); __put_user_error(IWMMXT_MAGIC1, &frame->magic1, err); /* * iwmmxt_task_copy() doesn't check user permissions. * Let's do a dummy write on the upper boundary to ensure * access to user mem is OK all way up. */ err |= copy_locked(&frame->storage, current_thread_info(), sizeof(frame->storage), 1, iwmmxt_task_copy); return err; }
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; }
static int preserve_vfp_context(struct vfp_sigframe __user *frame) { struct thread_info *thread = current_thread_info(); struct vfp_hard_struct *h = &thread->vfpstate.hard; const unsigned long magic = VFP_MAGIC; const unsigned long size = VFP_STORAGE_SIZE; int err = 0; vfp_sync_hwstate(thread); __put_user_error(magic, &frame->magic, err); __put_user_error(size, &frame->size, err); /* * Copy the floating point registers. There can be unused * registers see asm/hwcap.h for details. */ err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, sizeof(h->fpregs)); /* * Copy the status and control register. */ __put_user_error(h->fpscr, &frame->ufp.fpscr, err); /* * Copy the exception registers. */ __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); return err ? -EFAULT : 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; }
static int setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); int err = 0; if (!frame) return 1; __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err); err |= setup_sigframe(frame, regs, set); if (err == 0) err = setup_return(regs, ka, frame->retcode, frame, usig); return err; }
static int setup_sigframe(struct rt_sigframe __user *sf, struct pt_regs *regs, sigset_t *set) { int i, err = 0; void *aux = sf->uc.uc_mcontext.__reserved; struct _aarch64_ctx *end; /* set up the stack frame for unwinding */ __put_user_error(regs->regs[29], &sf->fp, err); __put_user_error(regs->regs[30], &sf->lr, err); for (i = 0; i < 31; i++) __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], err); __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); if (err == 0) { struct fpsimd_context *fpsimd_ctx = container_of(aux, struct fpsimd_context, head); err |= preserve_fpsimd_context(fpsimd_ctx); aux += sizeof(*fpsimd_ctx); } /* set the "end" magic */ end = aux; __put_user_error(0, &end->magic, err); __put_user_error(0, &end->size, err); return err; }
static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame = get_sigframe(ksig, regs, sizeof(*frame)); int err = 0; if (!frame) return 1; /* * Set uc.uc_flags to a value which sc.trap_no would never have. */ __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err); err |= setup_sigframe(frame, regs, set); if (err == 0) err = setup_return(regs, ksig, frame->retcode, frame); return err; }
static int setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/ struct exregs_regs *regs, unsigned long mask) { int err; err = 0; if (regs->syscall_action == 1) /* continue syscall */ __put_user_error(ARM_r0(current_regs()), &sc->arm_r0, err); /* User registers are saved/restored in user.S (__wombat_user_xxx) */ __put_user_error(regs->sp, &sc->arm_sp, err); __put_user_error(regs->ip, &sc->arm_pc, err); __put_user_error(regs->flags, &sc->arm_cpsr, err); __put_user_error(/*current->thread.trap_no*/ 0, &sc->trap_no, err); __put_user_error(/*current->thread.error_code*/ 0, &sc->error_code, err); __put_user_error(/*current->thread.address*/ 0, &sc->fault_address, err); __put_user_error(mask, &sc->oldmask, err); return err; }
static inline int setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) { struct task_struct *tsk = current; int ret = 0; __put_user_error(used_math(), &sc->used_math_flag, ret); if (!used_math()) return ret; preempt_disable(); #if IS_ENABLED(CONFIG_LAZY_FPU) if (last_task_used_math == tsk) save_fpu(last_task_used_math); #else unlazy_fpu(tsk); #endif ret = __copy_to_user(&sc->fpu, &tsk->thread.fpu, sizeof(struct fpu_struct)); preempt_enable(); return ret; }
static int setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) { struct aux_sigframe __user *aux; int err = 0; __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); __put_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); __put_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); __put_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); __put_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); __put_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); __put_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); __put_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); __put_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); __put_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); __put_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); __put_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); __put_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); __put_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); __put_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); __put_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); __put_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err); __put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err); __put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err); __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; #ifdef CONFIG_CRUNCH if (err == 0) err |= preserve_crunch_context(&aux->crunch); #endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= preserve_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP if (err == 0) err |= preserve_vfp_context(&aux->vfp); #endif __put_user_error(0, &aux->end_magic, err); return err; }
static int setup_sigcontext(struct sigcontext __user *sc, /*struct _fpstate *fpstate,*/ struct pt_regs *regs, unsigned long mask) { int err = 0; __put_user_error(regs->ARM_r0, &sc->arm_r0, err); __put_user_error(regs->ARM_r1, &sc->arm_r1, err); __put_user_error(regs->ARM_r2, &sc->arm_r2, err); __put_user_error(regs->ARM_r3, &sc->arm_r3, err); __put_user_error(regs->ARM_r4, &sc->arm_r4, err); __put_user_error(regs->ARM_r5, &sc->arm_r5, err); __put_user_error(regs->ARM_r6, &sc->arm_r6, err); __put_user_error(regs->ARM_r7, &sc->arm_r7, err); __put_user_error(regs->ARM_r8, &sc->arm_r8, err); __put_user_error(regs->ARM_r9, &sc->arm_r9, err); __put_user_error(regs->ARM_r10, &sc->arm_r10, err); __put_user_error(regs->ARM_fp, &sc->arm_fp, err); __put_user_error(regs->ARM_ip, &sc->arm_ip, err); __put_user_error(regs->ARM_sp, &sc->arm_sp, err); __put_user_error(regs->ARM_lr, &sc->arm_lr, err); __put_user_error(regs->ARM_pc, &sc->arm_pc, err); __put_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); __put_user_error(current->thread.trap_no, &sc->trap_no, err); __put_user_error(current->thread.error_code, &sc->error_code, err); __put_user_error(current->thread.address, &sc->fault_address, err); __put_user_error(mask, &sc->oldmask, err); return err; }
static void setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct exregs_regs *regs) { struct rt_sigframe *frame = get_sigframe(ka, regs, sizeof(*frame)); unsigned long handler = (unsigned long)ka->sa.sa_handler; int err = 0; printk_dbg("%s called\n", __func__); if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto badframe; __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)); err |= __put_user(handler, &frame->sig_ip); printk_dbg("%s frame->sig_ip = %lx\n", __func__, handler); if (!err) err = setup_return(regs, ka, &frame->retcode, frame, &frame->lr, &frame->usig, usig); if (!err) { /* * For realtime signals we must also set the second and third * arguments for the signal handler. * -- Peter Maydell <*****@*****.**> 2000-12-06 */ // ARM_put_r1(regs, (unsigned long)frame->pinfo); // ARM_put_r2(regs, (unsigned long)frame->puc); } if (err) goto badframe; regs->ip = TASK_SIG_BASE; switch (regs->syscall_action) { case 1: /* Syscall */ regs->ip += ((unsigned long)&__wombat_user_rt_sigentry) & ~PAGE_MASK; break; case 0: /* Fault */ case 2: /* Restart syscall */ regs->ip += ((unsigned long)&__wombat_user_rt_sigentry_restart) & ~PAGE_MASK; break; case 4: /* Interrupt syscall */ regs->ip += ((unsigned long)&__wombat_user_rt_sigentry_int) & ~PAGE_MASK; break; default: BUG(); } set_need_restart(current_thread_info(), regs->ip, regs->sp, regs->flags); printk_dbg("SIG rt deliver (%s:%d:%lx): sp=%p pc=%p\n", current->comm, current->pid, current_thread_info()->user_tid.raw, frame, (void*)regs->ip); return; badframe: force_sigsegv(usig, current); return; }
static int setup_sigframe(struct rt_sigframe __user * sf, struct pt_regs *regs, sigset_t * set) { int err = 0; __put_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err); __put_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err); __put_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err); __put_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err); __put_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err); __put_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err); __put_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err); __put_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err); __put_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err); __put_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err); __put_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err); __put_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err); __put_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err); __put_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err); __put_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err); __put_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err); __put_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err); __put_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err); __put_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err); __put_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err); __put_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err); __put_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err); __put_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err); __put_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err); __put_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err); __put_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err); __put_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err); __put_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err); __put_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err); __put_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err); __put_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err); #if defined(CONFIG_HWZOL) __put_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err); __put_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err); __put_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err); #endif #if IS_ENABLED(CONFIG_FPU) err |= setup_sigcontext_fpu(regs, &sf->uc.uc_mcontext); #endif __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err); __put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err); __put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err); __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); return err; }