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;
}
Esempio n. 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;
}
Esempio n. 4
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(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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
/*
 * 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;
}
Esempio n. 13
0
static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
{
	struct fpsimd_state *fpsimd = &current->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;
}
Esempio n. 14
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;
}
Esempio n. 15
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
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;
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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;
}