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…
Add table
Reference in a new issue