Beispiel #1
0
/* Returns non-zero on fault. */
static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
{
	_sigregs user_sregs;

	save_access_regs(current->thread.acrs);

	/* Copy a 'clean' PSW mask to the user to avoid leaking
	   information about whether PER is currently on.  */
	user_sregs.regs.psw.mask = PSW_USER_BITS |
		(regs->psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
	user_sregs.regs.psw.addr = regs->psw.addr;
	memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs));
	memcpy(&user_sregs.regs.acrs, current->thread.acrs,
	       sizeof(user_sregs.regs.acrs));
	/* 
	 * We have to store the fp registers to current->thread.fp_regs
	 * to merge them with the emulated registers.
	 */
	save_fp_ctl(&current->thread.fp_regs.fpc);
	save_fp_regs(current->thread.fp_regs.fprs);
	memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
	       sizeof(user_sregs.fpregs));
	if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs)))
		return -EFAULT;
	return 0;
}
Beispiel #2
0
/* Returns non-zero on fault. */
static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
{
	unsigned long old_mask = regs->psw.mask;
	int err;
  
	save_access_regs(current->thread.acrs);

	/* Copy a 'clean' PSW mask to the user to avoid leaking
	   information about whether PER is currently on.  */
	regs->psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask);
	err = __copy_to_user(&sregs->regs.psw, &regs->psw,
			     sizeof(sregs->regs.psw)+sizeof(sregs->regs.gprs));
	regs->psw.mask = old_mask;
	if (err != 0)
		return err;
	err = __copy_to_user(&sregs->regs.acrs, current->thread.acrs,
			     sizeof(sregs->regs.acrs));
	if (err != 0)
		return err;
	/* 
	 * We have to store the fp registers to current->thread.fp_regs
	 * to merge them with the emulated registers.
	 */
	save_fp_regs(&current->thread.fp_regs);
	return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
			      sizeof(s390_fp_regs));
}
Beispiel #3
0
static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
{
	if (tsk == current)
		save_fp_regs((s390_fp_regs *)fpregs);
	else
		memcpy(fpregs, &tsk->thread.fp_regs, sizeof(elf_fpregset_t));
	return 1;
}
/* Store registers needed to create the signal frame */
static void store_sigregs(void)
{
    int i;

    save_access_regs(current->thread.acrs);
    save_fp_ctl(&current->thread.fp_regs.fpc);
    if (current->thread.vxrs) {
        save_vx_regs(current->thread.vxrs);
        for (i = 0; i < __NUM_FPRS; i++)
            current->thread.fp_regs.fprs[i] =
                *(freg_t *)(current->thread.vxrs + i);
    } else
        save_fp_regs(current->thread.fp_regs.fprs);
}
Beispiel #5
0
static int save_sigregs(struct pt_regs *regs,sigregs *sregs)
{
	int err;
	s390_fp_regs fpregs;
  
	err = __copy_to_user(&sregs->regs,regs,sizeof(s390_regs_common));
	if(!err)
	{
		save_fp_regs(&fpregs);
		err=__copy_to_user(&sregs->fpregs,&fpregs,sizeof(fpregs));
	}
	return(err);
	
}
static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
{
	_s390_regs_common32 regs32;
	int err, i;

	regs32.psw.mask = PSW32_MASK_MERGE(psw32_user_bits,
					   (__u32)(regs->psw.mask >> 32));
	regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
	for (i = 0; i < NUM_GPRS; i++)
		regs32.gprs[i] = (__u32) regs->gprs[i];
	save_access_regs(current->thread.acrs);
	memcpy(regs32.acrs, current->thread.acrs, sizeof(regs32.acrs));
	err = __copy_to_user(&sregs->regs, &regs32, sizeof(regs32));
	if (err)
		return err;
	save_fp_regs(&current->thread.fp_regs);
	/* s390_fp_regs and _s390_fp_regs32 are the same ! */
	return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
			      sizeof(_s390_fp_regs32));
}
Beispiel #7
0
/* Returns non-zero on fault. */
static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
{
	_sigregs user_sregs;

	save_access_regs(current->thread.acrs);

	/* Copy a 'clean' PSW mask to the user to avoid leaking
	   information about whether PER is currently on.  */
	user_sregs.regs.psw.mask = PSW_MASK_MERGE(psw_user_bits, regs->psw.mask);
	user_sregs.regs.psw.addr = regs->psw.addr;
	memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs));
	memcpy(&user_sregs.regs.acrs, current->thread.acrs,
	       sizeof(sregs->regs.acrs));
	/* 
	 * We have to store the fp registers to current->thread.fp_regs
	 * to merge them with the emulated registers.
	 */
	save_fp_regs(&current->thread.fp_regs);
	memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
	       sizeof(s390_fp_regs));
	return __copy_to_user(sregs, &user_sregs, sizeof(_sigregs));
}
static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
{
	int err = 0;
	s390_fp_regs fpregs;
	int i;

	for(i=0; i<NUM_GPRS; i++) 
		err |= __put_user(regs->gprs[i], &sregs->regs.gprs[i]);  
	for(i=0; i<NUM_ACRS; i++)
		err |= __put_user(regs->acrs[i], &sregs->regs.acrs[i]);  
	err |= __copy_to_user(&sregs->regs.psw.mask, &regs->psw.mask, 4);
	err |= __copy_to_user(&sregs->regs.psw.addr, ((char*)&regs->psw.addr)+4, 4);
	if(!err)
	{
		save_fp_regs(&fpregs);
		__put_user(fpregs.fpc, &sregs->fpregs.fpc);
		for(i=0; i<NUM_FPRS; i++)
			err |= __put_user(fpregs.fprs[i].ui, &sregs->fpregs.fprs[i].d);  
	}
	return(err);
	
}
Beispiel #9
0
static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
{
	_sigregs32 user_sregs;
	int i;

	user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32);
	user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI;
	user_sregs.regs.psw.mask |= psw32_user_bits;
	user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
		(__u32)(regs->psw.mask & PSW_MASK_BA);
	for (i = 0; i < NUM_GPRS; i++)
		user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
	save_access_regs(current->thread.acrs);
	memcpy(&user_sregs.regs.acrs, current->thread.acrs,
	       sizeof(user_sregs.regs.acrs));
	save_fp_ctl(&current->thread.fp_regs.fpc);
	save_fp_regs(current->thread.fp_regs.fprs);
	memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
	       sizeof(user_sregs.fpregs));
	if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
		return -EFAULT;
	return 0;
}
Beispiel #10
0
int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
		unsigned long arg, struct task_struct *p)
{
	struct thread_info *ti;
	struct fake_frame
	{
		struct stack_frame sf;
		struct pt_regs childregs;
	} *frame;

	frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
	p->thread.ksp = (unsigned long) frame;
	/* Save access registers to new thread structure. */
	save_access_regs(&p->thread.acrs[0]);
	/* start new process with ar4 pointing to the correct address space */
	p->thread.mm_segment = get_fs();
	/* Don't copy debug registers */
	memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
	memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
	clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
	/* Initialize per thread user and system timer values */
	ti = task_thread_info(p);
	ti->user_timer = 0;
	ti->system_timer = 0;

	frame->sf.back_chain = 0;
	/* new return point is ret_from_fork */
	frame->sf.gprs[8] = (unsigned long) ret_from_fork;
	/* fake return stack for resume(), don't go back to schedule */
	frame->sf.gprs[9] = (unsigned long) frame;

	/* Store access registers to kernel stack of new process. */
	if (unlikely(p->flags & PF_KTHREAD)) {
		/* kernel thread */
		memset(&frame->childregs, 0, sizeof(struct pt_regs));
		frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT |
				PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
		frame->childregs.psw.addr = PSW_ADDR_AMODE |
				(unsigned long) kernel_thread_starter;
		frame->childregs.gprs[9] = new_stackp; /* function */
		frame->childregs.gprs[10] = arg;
		frame->childregs.gprs[11] = (unsigned long) do_exit;
		frame->childregs.orig_gpr2 = -1;

		return 0;
	}
	frame->childregs = *current_pt_regs();
	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
	frame->childregs.flags = 0;
	if (new_stackp)
		frame->childregs.gprs[15] = new_stackp;

	/* Don't copy runtime instrumentation info */
	p->thread.ri_cb = NULL;
	p->thread.ri_signum = 0;
	frame->childregs.psw.mask &= ~PSW_MASK_RI;

#ifndef CONFIG_64BIT
	/*
	 * save fprs to current->thread.fp_regs to merge them with
	 * the emulated registers and then copy the result to the child.
	 */
	save_fp_ctl(&current->thread.fp_regs.fpc);
	save_fp_regs(current->thread.fp_regs.fprs);
	memcpy(&p->thread.fp_regs, &current->thread.fp_regs,
	       sizeof(s390_fp_regs));
	/* Set a new TLS ?  */
	if (clone_flags & CLONE_SETTLS)
		p->thread.acrs[0] = frame->childregs.gprs[6];
#else /* CONFIG_64BIT */
	/* Save the fpu registers to new thread structure. */
	save_fp_ctl(&p->thread.fp_regs.fpc);
	save_fp_regs(p->thread.fp_regs.fprs);
	p->thread.fp_regs.pad = 0;
	/* Set a new TLS ?  */
	if (clone_flags & CLONE_SETTLS) {
		unsigned long tls = frame->childregs.gprs[6];
		if (is_compat_task()) {
			p->thread.acrs[0] = (unsigned int)tls;
		} else {
			p->thread.acrs[0] = (unsigned int)(tls >> 32);
			p->thread.acrs[1] = (unsigned int)tls;
		}
	}