mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	MIPS: Factor out NT_PRFPREG regset access helpers
In preparation to fix a commit72b22bbad1("MIPS: Don't assume 64-bit FP registers for FP regset") FCSR access regression factor out NT_PRFPREG regset access helpers for the non-MSA and the MSA variants respectively, to avoid having to deal with excessive indentation in the actual fix. No functional change, however use `target->thread.fpu.fpr[0]' rather than `target->thread.fpu.fpr[i]' for FGR holding type size determination as there's no `i' variable to refer to anymore, and for the factored out `i' variable declaration use `unsigned int' rather than `unsigned' as its type, following the common style. Signed-off-by: Maciej W. Rozycki <macro@mips.com> Fixes:72b22bbad1("MIPS: Don't assume 64-bit FP registers for FP regset") Cc: James Hogan <james.hogan@mips.com> Cc: Paul Burton <Paul.Burton@mips.com> Cc: Alex Smith <alex@alex-smith.me.uk> Cc: Dave Martin <Dave.Martin@arm.com> Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # v3.15+ Patchwork: https://patchwork.linux-mips.org/patch/17925/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
		
							parent
							
								
									17278a91e0
								
							
						
					
					
						commit
						a03fe72572
					
				
					 1 changed files with 83 additions and 25 deletions
				
			
		| 
						 | 
					@ -419,25 +419,36 @@ static int gpr64_set(struct task_struct *target,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CONFIG_64BIT */
 | 
					#endif /* CONFIG_64BIT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fpr_get(struct task_struct *target,
 | 
					/*
 | 
				
			||||||
		   const struct user_regset *regset,
 | 
					 * Copy the floating-point context to the supplied NT_PRFPREG buffer,
 | 
				
			||||||
		   unsigned int pos, unsigned int count,
 | 
					 * !CONFIG_CPU_HAS_MSA variant.  FP context's general register slots
 | 
				
			||||||
		   void *kbuf, void __user *ubuf)
 | 
					 * correspond 1:1 to buffer slots.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int fpr_get_fpa(struct task_struct *target,
 | 
				
			||||||
 | 
							       unsigned int *pos, unsigned int *count,
 | 
				
			||||||
 | 
							       void **kbuf, void __user **ubuf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned i;
 | 
						return user_regset_copyout(pos, count, kbuf, ubuf,
 | 
				
			||||||
	int err;
 | 
									   &target->thread.fpu,
 | 
				
			||||||
 | 
									   0, sizeof(elf_fpregset_t));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copy the floating-point context to the supplied NT_PRFPREG buffer,
 | 
				
			||||||
 | 
					 * CONFIG_CPU_HAS_MSA variant.  Only lower 64 bits of FP context's
 | 
				
			||||||
 | 
					 * general register slots are copied to buffer slots.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int fpr_get_msa(struct task_struct *target,
 | 
				
			||||||
 | 
							       unsigned int *pos, unsigned int *count,
 | 
				
			||||||
 | 
							       void **kbuf, void __user **ubuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
	u64 fpr_val;
 | 
						u64 fpr_val;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
	/* XXX fcr31  */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
 | 
					 | 
				
			||||||
		return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
 | 
					 | 
				
			||||||
					   &target->thread.fpu,
 | 
					 | 
				
			||||||
					   0, sizeof(elf_fpregset_t));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < NUM_FPU_REGS; i++) {
 | 
						for (i = 0; i < NUM_FPU_REGS; i++) {
 | 
				
			||||||
		fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
 | 
							fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
 | 
				
			||||||
		err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
 | 
							err = user_regset_copyout(pos, count, kbuf, ubuf,
 | 
				
			||||||
					  &fpr_val, i * sizeof(elf_fpreg_t),
 | 
										  &fpr_val, i * sizeof(elf_fpreg_t),
 | 
				
			||||||
					  (i + 1) * sizeof(elf_fpreg_t));
 | 
										  (i + 1) * sizeof(elf_fpreg_t));
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
| 
						 | 
					@ -447,27 +458,54 @@ static int fpr_get(struct task_struct *target,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fpr_set(struct task_struct *target,
 | 
					/* Copy the floating-point context to the supplied NT_PRFPREG buffer.  */
 | 
				
			||||||
 | 
					static int fpr_get(struct task_struct *target,
 | 
				
			||||||
		   const struct user_regset *regset,
 | 
							   const struct user_regset *regset,
 | 
				
			||||||
		   unsigned int pos, unsigned int count,
 | 
							   unsigned int pos, unsigned int count,
 | 
				
			||||||
		   const void *kbuf, const void __user *ubuf)
 | 
							   void *kbuf, void __user *ubuf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned i;
 | 
					 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	u64 fpr_val;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* XXX fcr31  */
 | 
						/* XXX fcr31  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_fp_ctx(target);
 | 
						if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
 | 
				
			||||||
 | 
							err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
 | 
						return err;
 | 
				
			||||||
		return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 | 
					}
 | 
				
			||||||
					  &target->thread.fpu,
 | 
					
 | 
				
			||||||
					  0, sizeof(elf_fpregset_t));
 | 
					/*
 | 
				
			||||||
 | 
					 * Copy the supplied NT_PRFPREG buffer to the floating-point context,
 | 
				
			||||||
 | 
					 * !CONFIG_CPU_HAS_MSA variant.   Buffer slots correspond 1:1 to FP
 | 
				
			||||||
 | 
					 * context's general register slots.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int fpr_set_fpa(struct task_struct *target,
 | 
				
			||||||
 | 
							       unsigned int *pos, unsigned int *count,
 | 
				
			||||||
 | 
							       const void **kbuf, const void __user **ubuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return user_regset_copyin(pos, count, kbuf, ubuf,
 | 
				
			||||||
 | 
									  &target->thread.fpu,
 | 
				
			||||||
 | 
									  0, sizeof(elf_fpregset_t));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copy the supplied NT_PRFPREG buffer to the floating-point context,
 | 
				
			||||||
 | 
					 * CONFIG_CPU_HAS_MSA variant.  Buffer slots are copied to lower 64
 | 
				
			||||||
 | 
					 * bits only of FP context's general register slots.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int fpr_set_msa(struct task_struct *target,
 | 
				
			||||||
 | 
							       unsigned int *pos, unsigned int *count,
 | 
				
			||||||
 | 
							       const void **kbuf, const void __user **ubuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						u64 fpr_val;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
 | 
						BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
 | 
				
			||||||
	for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) {
 | 
						for (i = 0; i < NUM_FPU_REGS && *count >= sizeof(elf_fpreg_t); i++) {
 | 
				
			||||||
		err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 | 
							err = user_regset_copyin(pos, count, kbuf, ubuf,
 | 
				
			||||||
					 &fpr_val, i * sizeof(elf_fpreg_t),
 | 
										 &fpr_val, i * sizeof(elf_fpreg_t),
 | 
				
			||||||
					 (i + 1) * sizeof(elf_fpreg_t));
 | 
										 (i + 1) * sizeof(elf_fpreg_t));
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
| 
						 | 
					@ -478,6 +516,26 @@ static int fpr_set(struct task_struct *target,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copy the supplied NT_PRFPREG buffer to the floating-point context.  */
 | 
				
			||||||
 | 
					static int fpr_set(struct task_struct *target,
 | 
				
			||||||
 | 
							   const struct user_regset *regset,
 | 
				
			||||||
 | 
							   unsigned int pos, unsigned int count,
 | 
				
			||||||
 | 
							   const void *kbuf, const void __user *ubuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* XXX fcr31  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						init_fp_ctx(target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
 | 
				
			||||||
 | 
							err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum mips_regset {
 | 
					enum mips_regset {
 | 
				
			||||||
	REGSET_GPR,
 | 
						REGSET_GPR,
 | 
				
			||||||
	REGSET_FPR,
 | 
						REGSET_FPR,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue