hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/mips/kernel/ptrace.c
....@@ -39,7 +39,6 @@
3939 #include <asm/fpu.h>
4040 #include <asm/mipsregs.h>
4141 #include <asm/mipsmtregs.h>
42
-#include <asm/pgtable.h>
4342 #include <asm/page.h>
4443 #include <asm/processor.h>
4544 #include <asm/syscall.h>
....@@ -49,25 +48,6 @@
4948
5049 #define CREATE_TRACE_POINTS
5150 #include <trace/events/syscalls.h>
52
-
53
-static void init_fp_ctx(struct task_struct *target)
54
-{
55
- /* If FP has been used then the target already has context */
56
- if (tsk_used_math(target))
57
- return;
58
-
59
- /* Begin with data registers set to all 1s... */
60
- memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
61
-
62
- /* FCSR has been preset by `mips_set_personality_nan'. */
63
-
64
- /*
65
- * Record that the target has "used" math, such that the context
66
- * just initialised, and any modifications made by the caller,
67
- * aren't discarded.
68
- */
69
- set_stopped_child_used_math(target);
70
-}
7151
7252 /*
7353 * Called by kernel/ptrace.c when detaching..
....@@ -81,21 +61,6 @@
8161 }
8262
8363 /*
84
- * Poke at FCSR according to its mask. Set the Cause bits even
85
- * if a corresponding Enable bit is set. This will be noticed at
86
- * the time the thread is switched to and SIGFPE thrown accordingly.
87
- */
88
-static void ptrace_setfcr31(struct task_struct *child, u32 value)
89
-{
90
- u32 fcr31;
91
- u32 mask;
92
-
93
- fcr31 = child->thread.fpu.fcr31;
94
- mask = boot_cpu_data.fpu_msk31;
95
- child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
96
-}
97
-
98
-/*
9964 * Read a general register set. We always use the 64-bit format, even
10065 * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
10166 * Registers are sign extended to fill the available space.
....@@ -105,7 +70,7 @@
10570 struct pt_regs *regs;
10671 int i;
10772
108
- if (!access_ok(VERIFY_WRITE, data, 38 * 8))
73
+ if (!access_ok(data, 38 * 8))
10974 return -EIO;
11075
11176 regs = task_pt_regs(child);
....@@ -132,7 +97,7 @@
13297 struct pt_regs *regs;
13398 int i;
13499
135
- if (!access_ok(VERIFY_READ, data, 38 * 8))
100
+ if (!access_ok(data, 38 * 8))
136101 return -EIO;
137102
138103 regs = task_pt_regs(child);
....@@ -151,55 +116,6 @@
151116 return 0;
152117 }
153118
154
-int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
155
-{
156
- int i;
157
-
158
- if (!access_ok(VERIFY_WRITE, data, 33 * 8))
159
- return -EIO;
160
-
161
- if (tsk_used_math(child)) {
162
- union fpureg *fregs = get_fpu_regs(child);
163
- for (i = 0; i < 32; i++)
164
- __put_user(get_fpr64(&fregs[i], 0),
165
- i + (__u64 __user *)data);
166
- } else {
167
- for (i = 0; i < 32; i++)
168
- __put_user((__u64) -1, i + (__u64 __user *) data);
169
- }
170
-
171
- __put_user(child->thread.fpu.fcr31, data + 64);
172
- __put_user(boot_cpu_data.fpu_id, data + 65);
173
-
174
- return 0;
175
-}
176
-
177
-int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
178
-{
179
- union fpureg *fregs;
180
- u64 fpr_val;
181
- u32 value;
182
- int i;
183
-
184
- if (!access_ok(VERIFY_READ, data, 33 * 8))
185
- return -EIO;
186
-
187
- init_fp_ctx(child);
188
- fregs = get_fpu_regs(child);
189
-
190
- for (i = 0; i < 32; i++) {
191
- __get_user(fpr_val, i + (__u64 __user *)data);
192
- set_fpr64(&fregs[i], 0, fpr_val);
193
- }
194
-
195
- __get_user(value, data + 64);
196
- ptrace_setfcr31(child, value);
197
-
198
- /* FIR may not be written. */
199
-
200
- return 0;
201
-}
202
-
203119 int ptrace_get_watch_regs(struct task_struct *child,
204120 struct pt_watch_regs __user *addr)
205121 {
....@@ -208,7 +124,7 @@
208124
209125 if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
210126 return -EIO;
211
- if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs)))
127
+ if (!access_ok(addr, sizeof(struct pt_watch_regs)))
212128 return -EIO;
213129
214130 #ifdef CONFIG_32BIT
....@@ -250,7 +166,7 @@
250166
251167 if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
252168 return -EIO;
253
- if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs)))
169
+ if (!access_ok(addr, sizeof(struct pt_watch_regs)))
254170 return -EIO;
255171 /* Check the values. */
256172 for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
....@@ -294,15 +210,13 @@
294210
295211 static int gpr32_get(struct task_struct *target,
296212 const struct user_regset *regset,
297
- unsigned int pos, unsigned int count,
298
- void *kbuf, void __user *ubuf)
213
+ struct membuf to)
299214 {
300215 struct pt_regs *regs = task_pt_regs(target);
301216 u32 uregs[ELF_NGREG] = {};
302217
303218 mips_dump_regs32(uregs, regs);
304
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
305
- sizeof(uregs));
219
+ return membuf_write(&to, uregs, sizeof(uregs));
306220 }
307221
308222 static int gpr32_set(struct task_struct *target,
....@@ -361,15 +275,13 @@
361275
362276 static int gpr64_get(struct task_struct *target,
363277 const struct user_regset *regset,
364
- unsigned int pos, unsigned int count,
365
- void *kbuf, void __user *ubuf)
278
+ struct membuf to)
366279 {
367280 struct pt_regs *regs = task_pt_regs(target);
368281 u64 uregs[ELF_NGREG] = {};
369282
370283 mips_dump_regs64(uregs, regs);
371
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
372
- sizeof(uregs));
284
+ return membuf_write(&to, uregs, sizeof(uregs));
373285 }
374286
375287 static int gpr64_set(struct task_struct *target,
....@@ -420,18 +332,83 @@
420332
421333 #endif /* CONFIG_64BIT */
422334
335
+
336
+#ifdef CONFIG_MIPS_FP_SUPPORT
337
+
338
+/*
339
+ * Poke at FCSR according to its mask. Set the Cause bits even
340
+ * if a corresponding Enable bit is set. This will be noticed at
341
+ * the time the thread is switched to and SIGFPE thrown accordingly.
342
+ */
343
+static void ptrace_setfcr31(struct task_struct *child, u32 value)
344
+{
345
+ u32 fcr31;
346
+ u32 mask;
347
+
348
+ fcr31 = child->thread.fpu.fcr31;
349
+ mask = boot_cpu_data.fpu_msk31;
350
+ child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
351
+}
352
+
353
+int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
354
+{
355
+ int i;
356
+
357
+ if (!access_ok(data, 33 * 8))
358
+ return -EIO;
359
+
360
+ if (tsk_used_math(child)) {
361
+ union fpureg *fregs = get_fpu_regs(child);
362
+ for (i = 0; i < 32; i++)
363
+ __put_user(get_fpr64(&fregs[i], 0),
364
+ i + (__u64 __user *)data);
365
+ } else {
366
+ for (i = 0; i < 32; i++)
367
+ __put_user((__u64) -1, i + (__u64 __user *) data);
368
+ }
369
+
370
+ __put_user(child->thread.fpu.fcr31, data + 64);
371
+ __put_user(boot_cpu_data.fpu_id, data + 65);
372
+
373
+ return 0;
374
+}
375
+
376
+int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
377
+{
378
+ union fpureg *fregs;
379
+ u64 fpr_val;
380
+ u32 value;
381
+ int i;
382
+
383
+ if (!access_ok(data, 33 * 8))
384
+ return -EIO;
385
+
386
+ init_fp_ctx(child);
387
+ fregs = get_fpu_regs(child);
388
+
389
+ for (i = 0; i < 32; i++) {
390
+ __get_user(fpr_val, i + (__u64 __user *)data);
391
+ set_fpr64(&fregs[i], 0, fpr_val);
392
+ }
393
+
394
+ __get_user(value, data + 64);
395
+ ptrace_setfcr31(child, value);
396
+
397
+ /* FIR may not be written. */
398
+
399
+ return 0;
400
+}
401
+
423402 /*
424403 * Copy the floating-point context to the supplied NT_PRFPREG buffer,
425404 * !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
426405 * correspond 1:1 to buffer slots. Only general registers are copied.
427406 */
428
-static int fpr_get_fpa(struct task_struct *target,
429
- unsigned int *pos, unsigned int *count,
430
- void **kbuf, void __user **ubuf)
407
+static void fpr_get_fpa(struct task_struct *target,
408
+ struct membuf *to)
431409 {
432
- return user_regset_copyout(pos, count, kbuf, ubuf,
433
- &target->thread.fpu,
434
- 0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
410
+ membuf_write(to, &target->thread.fpu,
411
+ NUM_FPU_REGS * sizeof(elf_fpreg_t));
435412 }
436413
437414 /*
....@@ -440,25 +417,13 @@
440417 * general register slots are copied to buffer slots. Only general
441418 * registers are copied.
442419 */
443
-static int fpr_get_msa(struct task_struct *target,
444
- unsigned int *pos, unsigned int *count,
445
- void **kbuf, void __user **ubuf)
420
+static void fpr_get_msa(struct task_struct *target, struct membuf *to)
446421 {
447422 unsigned int i;
448
- u64 fpr_val;
449
- int err;
450423
451
- BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
452
- for (i = 0; i < NUM_FPU_REGS; i++) {
453
- fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
454
- err = user_regset_copyout(pos, count, kbuf, ubuf,
455
- &fpr_val, i * sizeof(elf_fpreg_t),
456
- (i + 1) * sizeof(elf_fpreg_t));
457
- if (err)
458
- return err;
459
- }
460
-
461
- return 0;
424
+ BUILD_BUG_ON(sizeof(u64) != sizeof(elf_fpreg_t));
425
+ for (i = 0; i < NUM_FPU_REGS; i++)
426
+ membuf_store(to, get_fpr64(&target->thread.fpu.fpr[i], 0));
462427 }
463428
464429 /*
....@@ -468,31 +433,16 @@
468433 */
469434 static int fpr_get(struct task_struct *target,
470435 const struct user_regset *regset,
471
- unsigned int pos, unsigned int count,
472
- void *kbuf, void __user *ubuf)
436
+ struct membuf to)
473437 {
474
- const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
475
- const int fir_pos = fcr31_pos + sizeof(u32);
476
- int err;
477
-
478438 if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
479
- err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
439
+ fpr_get_fpa(target, &to);
480440 else
481
- err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
482
- if (err)
483
- return err;
441
+ fpr_get_msa(target, &to);
484442
485
- err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
486
- &target->thread.fpu.fcr31,
487
- fcr31_pos, fcr31_pos + sizeof(u32));
488
- if (err)
489
- return err;
490
-
491
- err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
492
- &boot_cpu_data.fpu_id,
493
- fir_pos, fir_pos + sizeof(u32));
494
-
495
- return err;
443
+ membuf_write(&to, &target->thread.fpu.fcr31, sizeof(u32));
444
+ membuf_write(&to, &boot_cpu_data.fpu_id, sizeof(u32));
445
+ return 0;
496446 }
497447
498448 /*
....@@ -590,6 +540,151 @@
590540 return err;
591541 }
592542
543
+/* Copy the FP mode setting to the supplied NT_MIPS_FP_MODE buffer. */
544
+static int fp_mode_get(struct task_struct *target,
545
+ const struct user_regset *regset,
546
+ struct membuf to)
547
+{
548
+ return membuf_store(&to, (int)mips_get_process_fp_mode(target));
549
+}
550
+
551
+/*
552
+ * Copy the supplied NT_MIPS_FP_MODE buffer to the FP mode setting.
553
+ *
554
+ * We optimize for the case where `count % sizeof(int) == 0', which
555
+ * is supposed to have been guaranteed by the kernel before calling
556
+ * us, e.g. in `ptrace_regset'. We enforce that requirement, so
557
+ * that we can safely avoid preinitializing temporaries for partial
558
+ * mode writes.
559
+ */
560
+static int fp_mode_set(struct task_struct *target,
561
+ const struct user_regset *regset,
562
+ unsigned int pos, unsigned int count,
563
+ const void *kbuf, const void __user *ubuf)
564
+{
565
+ int fp_mode;
566
+ int err;
567
+
568
+ BUG_ON(count % sizeof(int));
569
+
570
+ if (pos + count > sizeof(fp_mode))
571
+ return -EIO;
572
+
573
+ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
574
+ sizeof(fp_mode));
575
+ if (err)
576
+ return err;
577
+
578
+ if (count > 0)
579
+ err = mips_set_process_fp_mode(target, fp_mode);
580
+
581
+ return err;
582
+}
583
+
584
+#endif /* CONFIG_MIPS_FP_SUPPORT */
585
+
586
+#ifdef CONFIG_CPU_HAS_MSA
587
+
588
+struct msa_control_regs {
589
+ unsigned int fir;
590
+ unsigned int fcsr;
591
+ unsigned int msair;
592
+ unsigned int msacsr;
593
+};
594
+
595
+static void copy_pad_fprs(struct task_struct *target,
596
+ const struct user_regset *regset,
597
+ struct membuf *to,
598
+ unsigned int live_sz)
599
+{
600
+ int i, j;
601
+ unsigned long long fill = ~0ull;
602
+ unsigned int cp_sz, pad_sz;
603
+
604
+ cp_sz = min(regset->size, live_sz);
605
+ pad_sz = regset->size - cp_sz;
606
+ WARN_ON(pad_sz % sizeof(fill));
607
+
608
+ for (i = 0; i < NUM_FPU_REGS; i++) {
609
+ membuf_write(to, &target->thread.fpu.fpr[i], cp_sz);
610
+ for (j = 0; j < (pad_sz / sizeof(fill)); j++)
611
+ membuf_store(to, fill);
612
+ }
613
+}
614
+
615
+static int msa_get(struct task_struct *target,
616
+ const struct user_regset *regset,
617
+ struct membuf to)
618
+{
619
+ const unsigned int wr_size = NUM_FPU_REGS * regset->size;
620
+ const struct msa_control_regs ctrl_regs = {
621
+ .fir = boot_cpu_data.fpu_id,
622
+ .fcsr = target->thread.fpu.fcr31,
623
+ .msair = boot_cpu_data.msa_id,
624
+ .msacsr = target->thread.fpu.msacsr,
625
+ };
626
+
627
+ if (!tsk_used_math(target)) {
628
+ /* The task hasn't used FP or MSA, fill with 0xff */
629
+ copy_pad_fprs(target, regset, &to, 0);
630
+ } else if (!test_tsk_thread_flag(target, TIF_MSA_CTX_LIVE)) {
631
+ /* Copy scalar FP context, fill the rest with 0xff */
632
+ copy_pad_fprs(target, regset, &to, 8);
633
+ } else if (sizeof(target->thread.fpu.fpr[0]) == regset->size) {
634
+ /* Trivially copy the vector registers */
635
+ membuf_write(&to, &target->thread.fpu.fpr, wr_size);
636
+ } else {
637
+ /* Copy as much context as possible, fill the rest with 0xff */
638
+ copy_pad_fprs(target, regset, &to,
639
+ sizeof(target->thread.fpu.fpr[0]));
640
+ }
641
+
642
+ return membuf_write(&to, &ctrl_regs, sizeof(ctrl_regs));
643
+}
644
+
645
+static int msa_set(struct task_struct *target,
646
+ const struct user_regset *regset,
647
+ unsigned int pos, unsigned int count,
648
+ const void *kbuf, const void __user *ubuf)
649
+{
650
+ const unsigned int wr_size = NUM_FPU_REGS * regset->size;
651
+ struct msa_control_regs ctrl_regs;
652
+ unsigned int cp_sz;
653
+ int i, err, start;
654
+
655
+ init_fp_ctx(target);
656
+
657
+ if (sizeof(target->thread.fpu.fpr[0]) == regset->size) {
658
+ /* Trivially copy the vector registers */
659
+ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
660
+ &target->thread.fpu.fpr,
661
+ 0, wr_size);
662
+ } else {
663
+ /* Copy as much context as possible */
664
+ cp_sz = min_t(unsigned int, regset->size,
665
+ sizeof(target->thread.fpu.fpr[0]));
666
+
667
+ i = start = err = 0;
668
+ for (; i < NUM_FPU_REGS; i++, start += regset->size) {
669
+ err |= user_regset_copyin(&pos, &count, &kbuf, &ubuf,
670
+ &target->thread.fpu.fpr[i],
671
+ start, start + cp_sz);
672
+ }
673
+ }
674
+
675
+ if (!err)
676
+ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl_regs,
677
+ wr_size, wr_size + sizeof(ctrl_regs));
678
+ if (!err) {
679
+ target->thread.fpu.fcr31 = ctrl_regs.fcsr & ~FPU_CSR_ALL_X;
680
+ target->thread.fpu.msacsr = ctrl_regs.msacsr & ~MSA_CSR_CAUSEF;
681
+ }
682
+
683
+ return err;
684
+}
685
+
686
+#endif /* CONFIG_CPU_HAS_MSA */
687
+
593688 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
594689
595690 /*
....@@ -597,34 +692,20 @@
597692 */
598693 static int dsp32_get(struct task_struct *target,
599694 const struct user_regset *regset,
600
- unsigned int pos, unsigned int count,
601
- void *kbuf, void __user *ubuf)
695
+ struct membuf to)
602696 {
603
- unsigned int start, num_regs, i;
604697 u32 dspregs[NUM_DSP_REGS + 1];
698
+ unsigned int i;
605699
606
- BUG_ON(count % sizeof(u32));
700
+ BUG_ON(to.left % sizeof(u32));
607701
608702 if (!cpu_has_dsp)
609703 return -EIO;
610704
611
- start = pos / sizeof(u32);
612
- num_regs = count / sizeof(u32);
613
-
614
- if (start + num_regs > NUM_DSP_REGS + 1)
615
- return -EIO;
616
-
617
- for (i = start; i < num_regs; i++)
618
- switch (i) {
619
- case 0 ... NUM_DSP_REGS - 1:
620
- dspregs[i] = target->thread.dsp.dspr[i];
621
- break;
622
- case NUM_DSP_REGS:
623
- dspregs[i] = target->thread.dsp.dspcontrol;
624
- break;
625
- }
626
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, dspregs, 0,
627
- sizeof(dspregs));
705
+ for (i = 0; i < NUM_DSP_REGS; i++)
706
+ dspregs[i] = target->thread.dsp.dspr[i];
707
+ dspregs[NUM_DSP_REGS] = target->thread.dsp.dspcontrol;
708
+ return membuf_write(&to, dspregs, sizeof(dspregs));
628709 }
629710
630711 /*
....@@ -677,34 +758,20 @@
677758 */
678759 static int dsp64_get(struct task_struct *target,
679760 const struct user_regset *regset,
680
- unsigned int pos, unsigned int count,
681
- void *kbuf, void __user *ubuf)
761
+ struct membuf to)
682762 {
683
- unsigned int start, num_regs, i;
684763 u64 dspregs[NUM_DSP_REGS + 1];
764
+ unsigned int i;
685765
686
- BUG_ON(count % sizeof(u64));
766
+ BUG_ON(to.left % sizeof(u64));
687767
688768 if (!cpu_has_dsp)
689769 return -EIO;
690770
691
- start = pos / sizeof(u64);
692
- num_regs = count / sizeof(u64);
693
-
694
- if (start + num_regs > NUM_DSP_REGS + 1)
695
- return -EIO;
696
-
697
- for (i = start; i < num_regs; i++)
698
- switch (i) {
699
- case 0 ... NUM_DSP_REGS - 1:
700
- dspregs[i] = target->thread.dsp.dspr[i];
701
- break;
702
- case NUM_DSP_REGS:
703
- dspregs[i] = target->thread.dsp.dspcontrol;
704
- break;
705
- }
706
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, dspregs, 0,
707
- sizeof(dspregs));
771
+ for (i = 0; i < NUM_DSP_REGS; i++)
772
+ dspregs[i] = target->thread.dsp.dspr[i];
773
+ dspregs[NUM_DSP_REGS] = target->thread.dsp.dspcontrol;
774
+ return membuf_write(&to, dspregs, sizeof(dspregs));
708775 }
709776
710777 /*
....@@ -759,57 +826,16 @@
759826 return cpu_has_dsp ? NUM_DSP_REGS + 1 : -ENODEV;
760827 }
761828
762
-/* Copy the FP mode setting to the supplied NT_MIPS_FP_MODE buffer. */
763
-static int fp_mode_get(struct task_struct *target,
764
- const struct user_regset *regset,
765
- unsigned int pos, unsigned int count,
766
- void *kbuf, void __user *ubuf)
767
-{
768
- int fp_mode;
769
-
770
- fp_mode = mips_get_process_fp_mode(target);
771
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
772
- sizeof(fp_mode));
773
-}
774
-
775
-/*
776
- * Copy the supplied NT_MIPS_FP_MODE buffer to the FP mode setting.
777
- *
778
- * We optimize for the case where `count % sizeof(int) == 0', which
779
- * is supposed to have been guaranteed by the kernel before calling
780
- * us, e.g. in `ptrace_regset'. We enforce that requirement, so
781
- * that we can safely avoid preinitializing temporaries for partial
782
- * mode writes.
783
- */
784
-static int fp_mode_set(struct task_struct *target,
785
- const struct user_regset *regset,
786
- unsigned int pos, unsigned int count,
787
- const void *kbuf, const void __user *ubuf)
788
-{
789
- int fp_mode;
790
- int err;
791
-
792
- BUG_ON(count % sizeof(int));
793
-
794
- if (pos + count > sizeof(fp_mode))
795
- return -EIO;
796
-
797
- err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
798
- sizeof(fp_mode));
799
- if (err)
800
- return err;
801
-
802
- if (count > 0)
803
- err = mips_set_process_fp_mode(target, fp_mode);
804
-
805
- return err;
806
-}
807
-
808829 enum mips_regset {
809830 REGSET_GPR,
810
- REGSET_FPR,
811831 REGSET_DSP,
832
+#ifdef CONFIG_MIPS_FP_SUPPORT
833
+ REGSET_FPR,
812834 REGSET_FP_MODE,
835
+#endif
836
+#ifdef CONFIG_CPU_HAS_MSA
837
+ REGSET_MSA,
838
+#endif
813839 };
814840
815841 struct pt_regs_offset {
....@@ -904,34 +930,46 @@
904930 .n = ELF_NGREG,
905931 .size = sizeof(unsigned int),
906932 .align = sizeof(unsigned int),
907
- .get = gpr32_get,
933
+ .regset_get = gpr32_get,
908934 .set = gpr32_set,
909
- },
910
- [REGSET_FPR] = {
911
- .core_note_type = NT_PRFPREG,
912
- .n = ELF_NFPREG,
913
- .size = sizeof(elf_fpreg_t),
914
- .align = sizeof(elf_fpreg_t),
915
- .get = fpr_get,
916
- .set = fpr_set,
917935 },
918936 [REGSET_DSP] = {
919937 .core_note_type = NT_MIPS_DSP,
920938 .n = NUM_DSP_REGS + 1,
921939 .size = sizeof(u32),
922940 .align = sizeof(u32),
923
- .get = dsp32_get,
941
+ .regset_get = dsp32_get,
924942 .set = dsp32_set,
925943 .active = dsp_active,
944
+ },
945
+#ifdef CONFIG_MIPS_FP_SUPPORT
946
+ [REGSET_FPR] = {
947
+ .core_note_type = NT_PRFPREG,
948
+ .n = ELF_NFPREG,
949
+ .size = sizeof(elf_fpreg_t),
950
+ .align = sizeof(elf_fpreg_t),
951
+ .regset_get = fpr_get,
952
+ .set = fpr_set,
926953 },
927954 [REGSET_FP_MODE] = {
928955 .core_note_type = NT_MIPS_FP_MODE,
929956 .n = 1,
930957 .size = sizeof(int),
931958 .align = sizeof(int),
932
- .get = fp_mode_get,
959
+ .regset_get = fp_mode_get,
933960 .set = fp_mode_set,
934961 },
962
+#endif
963
+#ifdef CONFIG_CPU_HAS_MSA
964
+ [REGSET_MSA] = {
965
+ .core_note_type = NT_MIPS_MSA,
966
+ .n = NUM_FPU_REGS + 1,
967
+ .size = 16,
968
+ .align = 16,
969
+ .regset_get = msa_get,
970
+ .set = msa_set,
971
+ },
972
+#endif
935973 };
936974
937975 static const struct user_regset_view user_mips_view = {
....@@ -952,34 +990,46 @@
952990 .n = ELF_NGREG,
953991 .size = sizeof(unsigned long),
954992 .align = sizeof(unsigned long),
955
- .get = gpr64_get,
993
+ .regset_get = gpr64_get,
956994 .set = gpr64_set,
957
- },
958
- [REGSET_FPR] = {
959
- .core_note_type = NT_PRFPREG,
960
- .n = ELF_NFPREG,
961
- .size = sizeof(elf_fpreg_t),
962
- .align = sizeof(elf_fpreg_t),
963
- .get = fpr_get,
964
- .set = fpr_set,
965995 },
966996 [REGSET_DSP] = {
967997 .core_note_type = NT_MIPS_DSP,
968998 .n = NUM_DSP_REGS + 1,
969999 .size = sizeof(u64),
9701000 .align = sizeof(u64),
971
- .get = dsp64_get,
1001
+ .regset_get = dsp64_get,
9721002 .set = dsp64_set,
9731003 .active = dsp_active,
9741004 },
1005
+#ifdef CONFIG_MIPS_FP_SUPPORT
9751006 [REGSET_FP_MODE] = {
9761007 .core_note_type = NT_MIPS_FP_MODE,
9771008 .n = 1,
9781009 .size = sizeof(int),
9791010 .align = sizeof(int),
980
- .get = fp_mode_get,
1011
+ .regset_get = fp_mode_get,
9811012 .set = fp_mode_set,
9821013 },
1014
+ [REGSET_FPR] = {
1015
+ .core_note_type = NT_PRFPREG,
1016
+ .n = ELF_NFPREG,
1017
+ .size = sizeof(elf_fpreg_t),
1018
+ .align = sizeof(elf_fpreg_t),
1019
+ .regset_get = fpr_get,
1020
+ .set = fpr_set,
1021
+ },
1022
+#endif
1023
+#ifdef CONFIG_CPU_HAS_MSA
1024
+ [REGSET_MSA] = {
1025
+ .core_note_type = NT_MIPS_MSA,
1026
+ .n = NUM_FPU_REGS + 1,
1027
+ .size = 16,
1028
+ .align = 16,
1029
+ .regset_get = msa_get,
1030
+ .set = msa_set,
1031
+ },
1032
+#endif
9831033 };
9841034
9851035 static const struct user_regset_view user_mips64_view = {
....@@ -1040,7 +1090,6 @@
10401090 /* Read the word at location addr in the USER area. */
10411091 case PTRACE_PEEKUSR: {
10421092 struct pt_regs *regs;
1043
- union fpureg *fregs;
10441093 unsigned long tmp = 0;
10451094
10461095 regs = task_pt_regs(child);
....@@ -1050,7 +1099,10 @@
10501099 case 0 ... 31:
10511100 tmp = regs->regs[addr];
10521101 break;
1053
- case FPR_BASE ... FPR_BASE + 31:
1102
+#ifdef CONFIG_MIPS_FP_SUPPORT
1103
+ case FPR_BASE ... FPR_BASE + 31: {
1104
+ union fpureg *fregs;
1105
+
10541106 if (!tsk_used_math(child)) {
10551107 /* FP not yet used */
10561108 tmp = -1;
....@@ -1072,6 +1124,15 @@
10721124 #endif
10731125 tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
10741126 break;
1127
+ }
1128
+ case FPC_CSR:
1129
+ tmp = child->thread.fpu.fcr31;
1130
+ break;
1131
+ case FPC_EIR:
1132
+ /* implementation / version register */
1133
+ tmp = boot_cpu_data.fpu_id;
1134
+ break;
1135
+#endif
10751136 case PC:
10761137 tmp = regs->cp0_epc;
10771138 break;
....@@ -1092,13 +1153,6 @@
10921153 tmp = regs->acx;
10931154 break;
10941155 #endif
1095
- case FPC_CSR:
1096
- tmp = child->thread.fpu.fcr31;
1097
- break;
1098
- case FPC_EIR:
1099
- /* implementation / version register */
1100
- tmp = boot_cpu_data.fpu_id;
1101
- break;
11021156 case DSP_BASE ... DSP_BASE + 5: {
11031157 dspreg_t *dregs;
11041158
....@@ -1149,6 +1203,7 @@
11491203 mips_syscall_is_indirect(child, regs))
11501204 mips_syscall_update_nr(child, regs);
11511205 break;
1206
+#ifdef CONFIG_MIPS_FP_SUPPORT
11521207 case FPR_BASE ... FPR_BASE + 31: {
11531208 union fpureg *fregs = get_fpu_regs(child);
11541209
....@@ -1168,6 +1223,11 @@
11681223 set_fpr64(&fregs[addr - FPR_BASE], 0, data);
11691224 break;
11701225 }
1226
+ case FPC_CSR:
1227
+ init_fp_ctx(child);
1228
+ ptrace_setfcr31(child, data);
1229
+ break;
1230
+#endif
11711231 case PC:
11721232 regs->cp0_epc = data;
11731233 break;
....@@ -1182,10 +1242,6 @@
11821242 regs->acx = data;
11831243 break;
11841244 #endif
1185
- case FPC_CSR:
1186
- init_fp_ctx(child);
1187
- ptrace_setfcr31(child, data);
1188
- break;
11891245 case DSP_BASE ... DSP_BASE + 5: {
11901246 dspreg_t *dregs;
11911247
....@@ -1221,6 +1277,7 @@
12211277 ret = ptrace_setregs(child, datavp);
12221278 break;
12231279
1280
+#ifdef CONFIG_MIPS_FP_SUPPORT
12241281 case PTRACE_GETFPREGS:
12251282 ret = ptrace_getfpregs(child, datavp);
12261283 break;
....@@ -1228,7 +1285,7 @@
12281285 case PTRACE_SETFPREGS:
12291286 ret = ptrace_setfpregs(child, datavp);
12301287 break;
1231
-
1288
+#endif
12321289 case PTRACE_GET_THREAD_AREA:
12331290 ret = put_user(task_thread_info(child)->tp_value, datalp);
12341291 break;
....@@ -1272,8 +1329,8 @@
12721329 unsigned long args[6];
12731330
12741331 sd.nr = syscall;
1275
- sd.arch = syscall_get_arch();
1276
- syscall_get_arguments(current, regs, 0, 6, args);
1332
+ sd.arch = syscall_get_arch(current);
1333
+ syscall_get_arguments(current, regs, args);
12771334 for (i = 0; i < 6; i++)
12781335 sd.args[i] = args[i];
12791336 sd.instruction_pointer = KSTK_EIP(current);