diff options
Diffstat (limited to 'arch/s390/kernel/signal.c')
| -rw-r--r-- | arch/s390/kernel/signal.c | 47 | 
1 files changed, 14 insertions, 33 deletions
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c551f22ce066..9549af102d75 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -105,32 +105,13 @@ struct rt_sigframe  static void store_sigregs(void)  {  	save_access_regs(current->thread.acrs); -	save_fp_ctl(¤t->thread.fp_regs.fpc); -	if (current->thread.vxrs) { -		int i; - -		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); +	save_fpu_regs();  }  /* Load registers after signal return */  static void load_sigregs(void)  {  	restore_access_regs(current->thread.acrs); -	/* restore_fp_ctl is done in restore_sigregs */ -	if (current->thread.vxrs) { -		int i; - -		for (i = 0; i < __NUM_FPRS; i++) -			*(freg_t *)(current->thread.vxrs + i) = -				current->thread.fp_regs.fprs[i]; -		restore_vx_regs(current->thread.vxrs); -	} else -		restore_fp_regs(current->thread.fp_regs.fprs);  }  /* Returns non-zero on fault. */ @@ -146,8 +127,7 @@ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)  	memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs));  	memcpy(&user_sregs.regs.acrs, current->thread.acrs,  	       sizeof(user_sregs.regs.acrs)); -	memcpy(&user_sregs.fpregs, ¤t->thread.fp_regs, -	       sizeof(user_sregs.fpregs)); +	fpregs_store(&user_sregs.fpregs, ¤t->thread.fpu);  	if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs)))  		return -EFAULT;  	return 0; @@ -166,8 +146,8 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)  	if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW_MASK_RI))  		return -EINVAL; -	/* Loading the floating-point-control word can fail. Do that first. */ -	if (restore_fp_ctl(&user_sregs.fpregs.fpc)) +	/* Test the floating-point-control word. */ +	if (test_fp_ctl(user_sregs.fpregs.fpc))  		return -EINVAL;  	/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ @@ -185,8 +165,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)  	memcpy(¤t->thread.acrs, &user_sregs.regs.acrs,  	       sizeof(current->thread.acrs)); -	memcpy(¤t->thread.fp_regs, &user_sregs.fpregs, -	       sizeof(current->thread.fp_regs)); +	fpregs_load(&user_sregs.fpregs, ¤t->thread.fpu);  	clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */  	return 0; @@ -200,13 +179,13 @@ static int save_sigregs_ext(struct pt_regs *regs,  	int i;  	/* Save vector registers to signal stack */ -	if (current->thread.vxrs) { +	if (is_vx_task(current)) {  		for (i = 0; i < __NUM_VXRS_LOW; i++) -			vxrs[i] = *((__u64 *)(current->thread.vxrs + i) + 1); +			vxrs[i] = *((__u64 *)(current->thread.fpu.vxrs + i) + 1);  		if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,  				   sizeof(sregs_ext->vxrs_low)) ||  		    __copy_to_user(&sregs_ext->vxrs_high, -				   current->thread.vxrs + __NUM_VXRS_LOW, +				   current->thread.fpu.vxrs + __NUM_VXRS_LOW,  				   sizeof(sregs_ext->vxrs_high)))  			return -EFAULT;  	} @@ -220,15 +199,15 @@ static int restore_sigregs_ext(struct pt_regs *regs,  	int i;  	/* Restore vector registers from signal stack */ -	if (current->thread.vxrs) { +	if (is_vx_task(current)) {  		if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,  				     sizeof(sregs_ext->vxrs_low)) || -		    __copy_from_user(current->thread.vxrs + __NUM_VXRS_LOW, +		    __copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW,  				     &sregs_ext->vxrs_high,  				     sizeof(sregs_ext->vxrs_high)))  			return -EFAULT;  		for (i = 0; i < __NUM_VXRS_LOW; i++) -			*((__u64 *)(current->thread.vxrs + i) + 1) = vxrs[i]; +			*((__u64 *)(current->thread.fpu.vxrs + i) + 1) = vxrs[i];  	}  	return 0;  } @@ -243,6 +222,7 @@ SYSCALL_DEFINE0(sigreturn)  	if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))  		goto badframe;  	set_current_blocked(&set); +	save_fpu_regs();  	if (restore_sigregs(regs, &frame->sregs))  		goto badframe;  	if (restore_sigregs_ext(regs, &frame->sregs_ext)) @@ -266,6 +246,7 @@ SYSCALL_DEFINE0(rt_sigreturn)  	set_current_blocked(&set);  	if (restore_altstack(&frame->uc.uc_stack))  		goto badframe; +	save_fpu_regs();  	if (restore_sigregs(regs, &frame->uc.uc_mcontext))  		goto badframe;  	if (restore_sigregs_ext(regs, &frame->uc.uc_mcontext_ext)) @@ -400,7 +381,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,  	uc_flags = 0;  	if (MACHINE_HAS_VX) {  		frame_size += sizeof(_sigregs_ext); -		if (current->thread.vxrs) +		if (is_vx_task(current))  			uc_flags |= UC_VXRS;  	}  	frame = get_sigframe(&ksig->ka, regs, frame_size);  |