Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72b22bba authored by Paul Burton's avatar Paul Burton Committed by Ralf Baechle
Browse files

MIPS: Don't assume 64-bit FP registers for FP regset



When we want to access 64-bit FP register values we can only treat
consecutive registers as being consecutive in memory when the width of
an FP register equals 64 bits. This assumption will not remain true once
MSA support is introduced, so provide a code path which copies each 64
bit FP register value in turn when the width of an FP register differs
from 64 bits.

Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6427/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 6cec7c4a
Loading
Loading
Loading
Loading
+40 −6
Original line number Diff line number Diff line
@@ -304,10 +304,27 @@ static int fpr_get(struct task_struct *target,
		   unsigned int pos, unsigned int count,
		   void *kbuf, void __user *ubuf)
{
	unsigned i;
	int err;
	u64 fpr_val;

	/* 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));
	/* XXX fcr31  */

	for (i = 0; i < NUM_FPU_REGS; i++) {
		fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
		err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  &fpr_val, i * sizeof(elf_fpreg_t),
					  (i + 1) * sizeof(elf_fpreg_t));
		if (err)
			return err;
	}

	return 0;
}

static int fpr_set(struct task_struct *target,
@@ -315,10 +332,27 @@ static int fpr_set(struct task_struct *target,
		   unsigned int pos, unsigned int count,
		   const void *kbuf, const void __user *ubuf)
{
	unsigned i;
	int err;
	u64 fpr_val;

	/* XXX fcr31  */

	if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
		return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
					  &target->thread.fpu,
					  0, sizeof(elf_fpregset_t));
	/* XXX fcr31  */

	for (i = 0; i < NUM_FPU_REGS; i++) {
		err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
					 &fpr_val, i * sizeof(elf_fpreg_t),
					 (i + 1) * sizeof(elf_fpreg_t));
		if (err)
			return err;
		set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val);
	}

	return 0;
}

enum mips_regset {