aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@mips.com>2017-12-11 17:51:35 -0500
committerRalf Baechle <ralf@linux-mips.org>2017-12-12 13:11:26 -0500
commita03fe72572c12e98f4173f8a535f32468e48b6ec (patch)
tree2361d979b2baec7d3bb0e05273ae7e065f71ad82
parent17278a91e04f858155d54bee5528ba4fbcec6f87 (diff)
MIPS: Factor out NT_PRFPREG regset access helpers
In preparation to fix a commit 72b22bbad1e7 ("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: 72b22bbad1e7 ("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>
-rw-r--r--arch/mips/kernel/ptrace.c108
1 files changed, 83 insertions, 25 deletions
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index efbd8df8b665..62e8ffd9370a 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -419,25 +419,36 @@ static int gpr64_set(struct task_struct *target,
419 419
420#endif /* CONFIG_64BIT */ 420#endif /* CONFIG_64BIT */
421 421
422static int fpr_get(struct task_struct *target, 422/*
423 const struct user_regset *regset, 423 * Copy the floating-point context to the supplied NT_PRFPREG buffer,
424 unsigned int pos, unsigned int count, 424 * !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
425 void *kbuf, void __user *ubuf) 425 * correspond 1:1 to buffer slots.
426 */
427static int fpr_get_fpa(struct task_struct *target,
428 unsigned int *pos, unsigned int *count,
429 void **kbuf, void __user **ubuf)
426{ 430{
427 unsigned i; 431 return user_regset_copyout(pos, count, kbuf, ubuf,
428 int err; 432 &target->thread.fpu,
429 u64 fpr_val; 433 0, sizeof(elf_fpregset_t));
430 434}
431 /* XXX fcr31 */
432 435
433 if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) 436/*
434 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 437 * Copy the floating-point context to the supplied NT_PRFPREG buffer,
435 &target->thread.fpu, 438 * CONFIG_CPU_HAS_MSA variant. Only lower 64 bits of FP context's
436 0, sizeof(elf_fpregset_t)); 439 * general register slots are copied to buffer slots.
440 */
441static int fpr_get_msa(struct task_struct *target,
442 unsigned int *pos, unsigned int *count,
443 void **kbuf, void __user **ubuf)
444{
445 unsigned int i;
446 u64 fpr_val;
447 int err;
437 448
438 for (i = 0; i < NUM_FPU_REGS; i++) { 449 for (i = 0; i < NUM_FPU_REGS; i++) {
439 fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0); 450 fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
440 err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 451 err = user_regset_copyout(pos, count, kbuf, ubuf,
441 &fpr_val, i * sizeof(elf_fpreg_t), 452 &fpr_val, i * sizeof(elf_fpreg_t),
442 (i + 1) * sizeof(elf_fpreg_t)); 453 (i + 1) * sizeof(elf_fpreg_t));
443 if (err) 454 if (err)
@@ -447,27 +458,54 @@ static int fpr_get(struct task_struct *target,
447 return 0; 458 return 0;
448} 459}
449 460
450static int fpr_set(struct task_struct *target, 461/* Copy the floating-point context to the supplied NT_PRFPREG buffer. */
462static int fpr_get(struct task_struct *target,
451 const struct user_regset *regset, 463 const struct user_regset *regset,
452 unsigned int pos, unsigned int count, 464 unsigned int pos, unsigned int count,
453 const void *kbuf, const void __user *ubuf) 465 void *kbuf, void __user *ubuf)
454{ 466{
455 unsigned i;
456 int err; 467 int err;
457 u64 fpr_val;
458 468
459 /* XXX fcr31 */ 469 /* XXX fcr31 */
460 470
461 init_fp_ctx(target); 471 if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
472 err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
473 else
474 err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
475
476 return err;
477}
462 478
463 if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) 479/*
464 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 480 * Copy the supplied NT_PRFPREG buffer to the floating-point context,
465 &target->thread.fpu, 481 * !CONFIG_CPU_HAS_MSA variant. Buffer slots correspond 1:1 to FP
466 0, sizeof(elf_fpregset_t)); 482 * context's general register slots.
483 */
484static int fpr_set_fpa(struct task_struct *target,
485 unsigned int *pos, unsigned int *count,
486 const void **kbuf, const void __user **ubuf)
487{
488 return user_regset_copyin(pos, count, kbuf, ubuf,
489 &target->thread.fpu,
490 0, sizeof(elf_fpregset_t));
491}
492
493/*
494 * Copy the supplied NT_PRFPREG buffer to the floating-point context,
495 * CONFIG_CPU_HAS_MSA variant. Buffer slots are copied to lower 64
496 * bits only of FP context's general register slots.
497 */
498static int fpr_set_msa(struct task_struct *target,
499 unsigned int *pos, unsigned int *count,
500 const void **kbuf, const void __user **ubuf)
501{
502 unsigned int i;
503 u64 fpr_val;
504 int err;
467 505
468 BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); 506 BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
469 for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) { 507 for (i = 0; i < NUM_FPU_REGS && *count >= sizeof(elf_fpreg_t); i++) {
470 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 508 err = user_regset_copyin(pos, count, kbuf, ubuf,
471 &fpr_val, i * sizeof(elf_fpreg_t), 509 &fpr_val, i * sizeof(elf_fpreg_t),
472 (i + 1) * sizeof(elf_fpreg_t)); 510 (i + 1) * sizeof(elf_fpreg_t));
473 if (err) 511 if (err)
@@ -478,6 +516,26 @@ static int fpr_set(struct task_struct *target,
478 return 0; 516 return 0;
479} 517}
480 518
519/* Copy the supplied NT_PRFPREG buffer to the floating-point context. */
520static int fpr_set(struct task_struct *target,
521 const struct user_regset *regset,
522 unsigned int pos, unsigned int count,
523 const void *kbuf, const void __user *ubuf)
524{
525 int err;
526
527 /* XXX fcr31 */
528
529 init_fp_ctx(target);
530
531 if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
532 err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
533 else
534 err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf);
535
536 return err;
537}
538
481enum mips_regset { 539enum mips_regset {
482 REGSET_GPR, 540 REGSET_GPR,
483 REGSET_FPR, 541 REGSET_FPR,