hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/arch/sparc/kernel/ptrace_64.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* ptrace.c: Sparc process tracing support.
23 *
34 * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
....@@ -31,7 +32,6 @@
3132 #include <linux/context_tracking.h>
3233
3334 #include <asm/asi.h>
34
-#include <asm/pgtable.h>
3535 #include <linux/uaccess.h>
3636 #include <asm/psrcompat.h>
3737 #include <asm/visasm.h>
....@@ -246,52 +246,23 @@
246246
247247 static int genregs64_get(struct task_struct *target,
248248 const struct user_regset *regset,
249
- unsigned int pos, unsigned int count,
250
- void *kbuf, void __user *ubuf)
249
+ struct membuf to)
251250 {
252251 const struct pt_regs *regs = task_pt_regs(target);
253
- int ret;
252
+ struct reg_window window;
254253
255254 if (target == current)
256255 flushw_user();
257256
258
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
259
- regs->u_regs,
260
- 0, 16 * sizeof(u64));
261
- if (!ret && count && pos < (32 * sizeof(u64))) {
262
- struct reg_window window;
263
-
264
- if (regwindow64_get(target, regs, &window))
265
- return -EFAULT;
266
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
267
- &window,
268
- 16 * sizeof(u64),
269
- 32 * sizeof(u64));
270
- }
271
-
272
- if (!ret) {
273
- /* TSTATE, TPC, TNPC */
274
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
275
- &regs->tstate,
276
- 32 * sizeof(u64),
277
- 35 * sizeof(u64));
278
- }
279
-
280
- if (!ret) {
281
- unsigned long y = regs->y;
282
-
283
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
284
- &y,
285
- 35 * sizeof(u64),
286
- 36 * sizeof(u64));
287
- }
288
-
289
- if (!ret) {
290
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
291
- 36 * sizeof(u64), -1);
292
-
293
- }
294
- return ret;
257
+ membuf_write(&to, regs->u_regs, 16 * sizeof(u64));
258
+ if (!to.left)
259
+ return 0;
260
+ if (regwindow64_get(target, regs, &window))
261
+ return -EFAULT;
262
+ membuf_write(&to, &window, 16 * sizeof(u64));
263
+ /* TSTATE, TPC, TNPC */
264
+ membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
265
+ return membuf_store(&to, (u64)regs->y);
295266 }
296267
297268 static int genregs64_set(struct task_struct *target,
....@@ -370,69 +341,32 @@
370341
371342 static int fpregs64_get(struct task_struct *target,
372343 const struct user_regset *regset,
373
- unsigned int pos, unsigned int count,
374
- void *kbuf, void __user *ubuf)
344
+ struct membuf to)
375345 {
376
- const unsigned long *fpregs = task_thread_info(target)->fpregs;
377
- unsigned long fprs, fsr, gsr;
378
- int ret;
346
+ struct thread_info *t = task_thread_info(target);
347
+ unsigned long fprs;
379348
380349 if (target == current)
381350 save_and_clear_fpu();
382351
383
- fprs = task_thread_info(target)->fpsaved[0];
352
+ fprs = t->fpsaved[0];
384353
385354 if (fprs & FPRS_DL)
386
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
387
- fpregs,
388
- 0, 16 * sizeof(u64));
355
+ membuf_write(&to, t->fpregs, 16 * sizeof(u64));
389356 else
390
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
391
- 0,
392
- 16 * sizeof(u64));
357
+ membuf_zero(&to, 16 * sizeof(u64));
393358
394
- if (!ret) {
395
- if (fprs & FPRS_DU)
396
- ret = user_regset_copyout(&pos, &count,
397
- &kbuf, &ubuf,
398
- fpregs + 16,
399
- 16 * sizeof(u64),
400
- 32 * sizeof(u64));
401
- else
402
- ret = user_regset_copyout_zero(&pos, &count,
403
- &kbuf, &ubuf,
404
- 16 * sizeof(u64),
405
- 32 * sizeof(u64));
406
- }
407
-
359
+ if (fprs & FPRS_DU)
360
+ membuf_write(&to, t->fpregs + 16, 16 * sizeof(u64));
361
+ else
362
+ membuf_zero(&to, 16 * sizeof(u64));
408363 if (fprs & FPRS_FEF) {
409
- fsr = task_thread_info(target)->xfsr[0];
410
- gsr = task_thread_info(target)->gsr[0];
364
+ membuf_store(&to, t->xfsr[0]);
365
+ membuf_store(&to, t->gsr[0]);
411366 } else {
412
- fsr = gsr = 0;
367
+ membuf_zero(&to, 2 * sizeof(u64));
413368 }
414
-
415
- if (!ret)
416
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
417
- &fsr,
418
- 32 * sizeof(u64),
419
- 33 * sizeof(u64));
420
- if (!ret)
421
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
422
- &gsr,
423
- 33 * sizeof(u64),
424
- 34 * sizeof(u64));
425
- if (!ret)
426
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
427
- &fprs,
428
- 34 * sizeof(u64),
429
- 35 * sizeof(u64));
430
-
431
- if (!ret)
432
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
433
- 35 * sizeof(u64), -1);
434
-
435
- return ret;
369
+ return membuf_store(&to, fprs);
436370 }
437371
438372 static int fpregs64_set(struct task_struct *target,
....@@ -490,7 +424,7 @@
490424 .core_note_type = NT_PRSTATUS,
491425 .n = 36,
492426 .size = sizeof(u64), .align = sizeof(u64),
493
- .get = genregs64_get, .set = genregs64_set
427
+ .regset_get = genregs64_get, .set = genregs64_set
494428 },
495429 /* Format is:
496430 * F0 --> F63
....@@ -502,8 +436,94 @@
502436 .core_note_type = NT_PRFPREG,
503437 .n = 35,
504438 .size = sizeof(u64), .align = sizeof(u64),
505
- .get = fpregs64_get, .set = fpregs64_set
439
+ .regset_get = fpregs64_get, .set = fpregs64_set
506440 },
441
+};
442
+
443
+static int getregs64_get(struct task_struct *target,
444
+ const struct user_regset *regset,
445
+ struct membuf to)
446
+{
447
+ const struct pt_regs *regs = task_pt_regs(target);
448
+
449
+ if (target == current)
450
+ flushw_user();
451
+
452
+ membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u64));
453
+ membuf_store(&to, (u64)0);
454
+ membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
455
+ return membuf_store(&to, (u64)regs->y);
456
+}
457
+
458
+static int setregs64_set(struct task_struct *target,
459
+ const struct user_regset *regset,
460
+ unsigned int pos, unsigned int count,
461
+ const void *kbuf, const void __user *ubuf)
462
+{
463
+ struct pt_regs *regs = task_pt_regs(target);
464
+ unsigned long y = regs->y;
465
+ unsigned long tstate;
466
+ int ret;
467
+
468
+ if (target == current)
469
+ flushw_user();
470
+
471
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
472
+ regs->u_regs + 1,
473
+ 0 * sizeof(u64),
474
+ 15 * sizeof(u64));
475
+ if (ret)
476
+ return ret;
477
+ ret =user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
478
+ 15 * sizeof(u64), 16 * sizeof(u64));
479
+ if (ret)
480
+ return ret;
481
+ /* TSTATE */
482
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
483
+ &tstate,
484
+ 16 * sizeof(u64),
485
+ 17 * sizeof(u64));
486
+ if (ret)
487
+ return ret;
488
+ /* Only the condition codes and the "in syscall"
489
+ * state can be modified in the %tstate register.
490
+ */
491
+ tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
492
+ regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
493
+ regs->tstate |= tstate;
494
+
495
+ /* TPC, TNPC */
496
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
497
+ &regs->tpc,
498
+ 17 * sizeof(u64),
499
+ 19 * sizeof(u64));
500
+ if (ret)
501
+ return ret;
502
+ /* Y */
503
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
504
+ &y,
505
+ 19 * sizeof(u64),
506
+ 20 * sizeof(u64));
507
+ if (!ret)
508
+ regs->y = y;
509
+ return ret;
510
+}
511
+
512
+static const struct user_regset ptrace64_regsets[] = {
513
+ /* Format is:
514
+ * G1 --> G7
515
+ * O0 --> O7
516
+ * 0
517
+ * TSTATE, TPC, TNPC, Y
518
+ */
519
+ [REGSET_GENERAL] = {
520
+ .n = 20, .size = sizeof(u64),
521
+ .regset_get = getregs64_get, .set = setregs64_set,
522
+ },
523
+};
524
+
525
+static const struct user_regset_view ptrace64_view = {
526
+ .regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets)
507527 };
508528
509529 static const struct user_regset_view user_sparc64_view = {
....@@ -514,108 +534,28 @@
514534 #ifdef CONFIG_COMPAT
515535 static int genregs32_get(struct task_struct *target,
516536 const struct user_regset *regset,
517
- unsigned int pos, unsigned int count,
518
- void *kbuf, void __user *ubuf)
537
+ struct membuf to)
519538 {
520539 const struct pt_regs *regs = task_pt_regs(target);
521
- compat_ulong_t __user *reg_window;
522
- compat_ulong_t *k = kbuf;
523
- compat_ulong_t __user *u = ubuf;
524
- compat_ulong_t reg;
540
+ u32 uregs[16];
541
+ int i;
525542
526543 if (target == current)
527544 flushw_user();
528545
529
- pos /= sizeof(reg);
530
- count /= sizeof(reg);
531
-
532
- if (kbuf) {
533
- for (; count > 0 && pos < 16; count--)
534
- *k++ = regs->u_regs[pos++];
535
-
536
- reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
537
- reg_window -= 16;
538
- if (target == current) {
539
- for (; count > 0 && pos < 32; count--) {
540
- if (get_user(*k++, &reg_window[pos++]))
541
- return -EFAULT;
542
- }
543
- } else {
544
- for (; count > 0 && pos < 32; count--) {
545
- if (access_process_vm(target,
546
- (unsigned long)
547
- &reg_window[pos],
548
- k, sizeof(*k),
549
- FOLL_FORCE)
550
- != sizeof(*k))
551
- return -EFAULT;
552
- k++;
553
- pos++;
554
- }
555
- }
556
- } else {
557
- for (; count > 0 && pos < 16; count--) {
558
- if (put_user((compat_ulong_t) regs->u_regs[pos++], u++))
559
- return -EFAULT;
560
- }
561
-
562
- reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
563
- reg_window -= 16;
564
- if (target == current) {
565
- for (; count > 0 && pos < 32; count--) {
566
- if (get_user(reg, &reg_window[pos++]) ||
567
- put_user(reg, u++))
568
- return -EFAULT;
569
- }
570
- } else {
571
- for (; count > 0 && pos < 32; count--) {
572
- if (access_process_vm(target,
573
- (unsigned long)
574
- &reg_window[pos++],
575
- &reg, sizeof(reg),
576
- FOLL_FORCE)
577
- != sizeof(reg))
578
- return -EFAULT;
579
- if (put_user(reg, u++))
580
- return -EFAULT;
581
- }
582
- }
583
- }
584
- while (count > 0) {
585
- switch (pos) {
586
- case 32: /* PSR */
587
- reg = tstate_to_psr(regs->tstate);
588
- break;
589
- case 33: /* PC */
590
- reg = regs->tpc;
591
- break;
592
- case 34: /* NPC */
593
- reg = regs->tnpc;
594
- break;
595
- case 35: /* Y */
596
- reg = regs->y;
597
- break;
598
- case 36: /* WIM */
599
- case 37: /* TBR */
600
- reg = 0;
601
- break;
602
- default:
603
- goto finish;
604
- }
605
-
606
- if (kbuf)
607
- *k++ = reg;
608
- else if (put_user(reg, u++))
609
- return -EFAULT;
610
- pos++;
611
- count--;
612
- }
613
-finish:
614
- pos *= sizeof(reg);
615
- count *= sizeof(reg);
616
-
617
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
618
- 38 * sizeof(reg), -1);
546
+ for (i = 0; i < 16; i++)
547
+ membuf_store(&to, (u32)regs->u_regs[i]);
548
+ if (!to.left)
549
+ return 0;
550
+ if (get_from_target(target, regs->u_regs[UREG_I6],
551
+ uregs, sizeof(uregs)))
552
+ return -EFAULT;
553
+ membuf_write(&to, uregs, 16 * sizeof(u32));
554
+ membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
555
+ membuf_store(&to, (u32)(regs->tpc));
556
+ membuf_store(&to, (u32)(regs->tnpc));
557
+ membuf_store(&to, (u32)(regs->y));
558
+ return membuf_zero(&to, 2 * sizeof(u32));
619559 }
620560
621561 static int genregs32_set(struct task_struct *target,
....@@ -737,56 +677,24 @@
737677
738678 static int fpregs32_get(struct task_struct *target,
739679 const struct user_regset *regset,
740
- unsigned int pos, unsigned int count,
741
- void *kbuf, void __user *ubuf)
680
+ struct membuf to)
742681 {
743
- const unsigned long *fpregs = task_thread_info(target)->fpregs;
744
- compat_ulong_t enabled;
745
- unsigned long fprs;
746
- compat_ulong_t fsr;
747
- int ret = 0;
682
+ struct thread_info *t = task_thread_info(target);
683
+ bool enabled;
748684
749685 if (target == current)
750686 save_and_clear_fpu();
751687
752
- fprs = task_thread_info(target)->fpsaved[0];
753
- if (fprs & FPRS_FEF) {
754
- fsr = task_thread_info(target)->xfsr[0];
755
- enabled = 1;
756
- } else {
757
- fsr = 0;
758
- enabled = 0;
759
- }
688
+ enabled = t->fpsaved[0] & FPRS_FEF;
760689
761
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
762
- fpregs,
763
- 0, 32 * sizeof(u32));
764
-
765
- if (!ret)
766
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
767
- 32 * sizeof(u32),
768
- 33 * sizeof(u32));
769
- if (!ret)
770
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
771
- &fsr,
772
- 33 * sizeof(u32),
773
- 34 * sizeof(u32));
774
-
775
- if (!ret) {
776
- compat_ulong_t val;
777
-
778
- val = (enabled << 8) | (8 << 16);
779
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
780
- &val,
781
- 34 * sizeof(u32),
782
- 35 * sizeof(u32));
783
- }
784
-
785
- if (!ret)
786
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
787
- 35 * sizeof(u32), -1);
788
-
789
- return ret;
690
+ membuf_write(&to, t->fpregs, 32 * sizeof(u32));
691
+ membuf_zero(&to, sizeof(u32));
692
+ if (enabled)
693
+ membuf_store(&to, (u32)t->xfsr[0]);
694
+ else
695
+ membuf_zero(&to, sizeof(u32));
696
+ membuf_store(&to, (u32)((enabled << 8) | (8 << 16)));
697
+ return membuf_zero(&to, 64 * sizeof(u32));
790698 }
791699
792700 static int fpregs32_set(struct task_struct *target,
....@@ -847,7 +755,7 @@
847755 .core_note_type = NT_PRSTATUS,
848756 .n = 38,
849757 .size = sizeof(u32), .align = sizeof(u32),
850
- .get = genregs32_get, .set = genregs32_set
758
+ .regset_get = genregs32_get, .set = genregs32_set
851759 },
852760 /* Format is:
853761 * F0 --> F31
....@@ -863,8 +771,131 @@
863771 .core_note_type = NT_PRFPREG,
864772 .n = 99,
865773 .size = sizeof(u32), .align = sizeof(u32),
866
- .get = fpregs32_get, .set = fpregs32_set
774
+ .regset_get = fpregs32_get, .set = fpregs32_set
867775 },
776
+};
777
+
778
+static int getregs_get(struct task_struct *target,
779
+ const struct user_regset *regset,
780
+ struct membuf to)
781
+{
782
+ const struct pt_regs *regs = task_pt_regs(target);
783
+ int i;
784
+
785
+ if (target == current)
786
+ flushw_user();
787
+
788
+ membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
789
+ membuf_store(&to, (u32)(regs->tpc));
790
+ membuf_store(&to, (u32)(regs->tnpc));
791
+ membuf_store(&to, (u32)(regs->y));
792
+ for (i = 1; i < 16; i++)
793
+ membuf_store(&to, (u32)regs->u_regs[i]);
794
+ return to.left;
795
+}
796
+
797
+static int setregs_set(struct task_struct *target,
798
+ const struct user_regset *regset,
799
+ unsigned int pos, unsigned int count,
800
+ const void *kbuf, const void __user *ubuf)
801
+{
802
+ struct pt_regs *regs = task_pt_regs(target);
803
+ unsigned long tstate;
804
+ u32 uregs[19];
805
+ int i, ret;
806
+
807
+ if (target == current)
808
+ flushw_user();
809
+
810
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
811
+ uregs,
812
+ 0, 19 * sizeof(u32));
813
+ if (ret)
814
+ return ret;
815
+
816
+ tstate = regs->tstate;
817
+ tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
818
+ tstate |= psr_to_tstate_icc(uregs[0]);
819
+ if (uregs[0] & PSR_SYSCALL)
820
+ tstate |= TSTATE_SYSCALL;
821
+ regs->tstate = tstate;
822
+ regs->tpc = uregs[1];
823
+ regs->tnpc = uregs[2];
824
+ regs->y = uregs[3];
825
+
826
+ for (i = 1; i < 15; i++)
827
+ regs->u_regs[i] = uregs[3 + i];
828
+ return 0;
829
+}
830
+
831
+static int getfpregs_get(struct task_struct *target,
832
+ const struct user_regset *regset,
833
+ struct membuf to)
834
+{
835
+ struct thread_info *t = task_thread_info(target);
836
+
837
+ if (target == current)
838
+ save_and_clear_fpu();
839
+
840
+ membuf_write(&to, t->fpregs, 32 * sizeof(u32));
841
+ if (t->fpsaved[0] & FPRS_FEF)
842
+ membuf_store(&to, (u32)t->xfsr[0]);
843
+ else
844
+ membuf_zero(&to, sizeof(u32));
845
+ return membuf_zero(&to, 35 * sizeof(u32));
846
+}
847
+
848
+static int setfpregs_set(struct task_struct *target,
849
+ const struct user_regset *regset,
850
+ unsigned int pos, unsigned int count,
851
+ const void *kbuf, const void __user *ubuf)
852
+{
853
+ unsigned long *fpregs = task_thread_info(target)->fpregs;
854
+ unsigned long fprs;
855
+ int ret;
856
+
857
+ if (target == current)
858
+ save_and_clear_fpu();
859
+
860
+ fprs = task_thread_info(target)->fpsaved[0];
861
+
862
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
863
+ fpregs,
864
+ 0, 32 * sizeof(u32));
865
+ if (!ret) {
866
+ compat_ulong_t fsr;
867
+ unsigned long val;
868
+
869
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
870
+ &fsr,
871
+ 32 * sizeof(u32),
872
+ 33 * sizeof(u32));
873
+ if (!ret) {
874
+ val = task_thread_info(target)->xfsr[0];
875
+ val &= 0xffffffff00000000UL;
876
+ val |= fsr;
877
+ task_thread_info(target)->xfsr[0] = val;
878
+ }
879
+ }
880
+
881
+ fprs |= (FPRS_FEF | FPRS_DL);
882
+ task_thread_info(target)->fpsaved[0] = fprs;
883
+ return ret;
884
+}
885
+
886
+static const struct user_regset ptrace32_regsets[] = {
887
+ [REGSET_GENERAL] = {
888
+ .n = 19, .size = sizeof(u32),
889
+ .regset_get = getregs_get, .set = setregs_set,
890
+ },
891
+ [REGSET_FP] = {
892
+ .n = 68, .size = sizeof(u32),
893
+ .regset_get = getfpregs_get, .set = setfpregs_set,
894
+ },
895
+};
896
+
897
+static const struct user_regset_view ptrace32_view = {
898
+ .regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets)
868899 };
869900
870901 static const struct user_regset_view user_sparc32_view = {
....@@ -898,7 +929,6 @@
898929 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
899930 compat_ulong_t caddr, compat_ulong_t cdata)
900931 {
901
- const struct user_regset_view *view = task_user_regset_view(current);
902932 compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
903933 struct pt_regs32 __user *pregs;
904934 struct compat_fps __user *fps;
....@@ -916,58 +946,31 @@
916946 break;
917947
918948 case PTRACE_GETREGS:
919
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
920
- 32 * sizeof(u32),
921
- 4 * sizeof(u32),
922
- &pregs->psr);
923
- if (!ret)
924
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
925
- 1 * sizeof(u32),
926
- 15 * sizeof(u32),
927
- &pregs->u_regs[0]);
949
+ ret = copy_regset_to_user(child, &ptrace32_view,
950
+ REGSET_GENERAL, 0,
951
+ 19 * sizeof(u32),
952
+ pregs);
928953 break;
929954
930955 case PTRACE_SETREGS:
931
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
932
- 32 * sizeof(u32),
933
- 4 * sizeof(u32),
934
- &pregs->psr);
935
- if (!ret)
936
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
937
- 1 * sizeof(u32),
938
- 15 * sizeof(u32),
939
- &pregs->u_regs[0]);
956
+ ret = copy_regset_from_user(child, &ptrace32_view,
957
+ REGSET_GENERAL, 0,
958
+ 19 * sizeof(u32),
959
+ pregs);
940960 break;
941961
942962 case PTRACE_GETFPREGS:
943
- ret = copy_regset_to_user(child, view, REGSET_FP,
944
- 0 * sizeof(u32),
945
- 32 * sizeof(u32),
946
- &fps->regs[0]);
947
- if (!ret)
948
- ret = copy_regset_to_user(child, view, REGSET_FP,
949
- 33 * sizeof(u32),
950
- 1 * sizeof(u32),
951
- &fps->fsr);
952
- if (!ret) {
953
- if (__put_user(0, &fps->flags) ||
954
- __put_user(0, &fps->extra) ||
955
- __put_user(0, &fps->fpqd) ||
956
- clear_user(&fps->fpq[0], 32 * sizeof(unsigned int)))
957
- ret = -EFAULT;
958
- }
963
+ ret = copy_regset_to_user(child, &ptrace32_view,
964
+ REGSET_FP, 0,
965
+ 68 * sizeof(u32),
966
+ fps);
959967 break;
960968
961969 case PTRACE_SETFPREGS:
962
- ret = copy_regset_from_user(child, view, REGSET_FP,
963
- 0 * sizeof(u32),
964
- 32 * sizeof(u32),
965
- &fps->regs[0]);
966
- if (!ret)
967
- ret = copy_regset_from_user(child, view, REGSET_FP,
968
- 33 * sizeof(u32),
969
- 1 * sizeof(u32),
970
- &fps->fsr);
970
+ ret = copy_regset_from_user(child, &ptrace32_view,
971
+ REGSET_FP, 0,
972
+ 33 * sizeof(u32),
973
+ fps);
971974 break;
972975
973976 case PTRACE_READTEXT:
....@@ -1026,31 +1029,17 @@
10261029 break;
10271030
10281031 case PTRACE_GETREGS64:
1029
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
1030
- 1 * sizeof(u64),
1031
- 15 * sizeof(u64),
1032
- &pregs->u_regs[0]);
1033
- if (!ret) {
1034
- /* XXX doesn't handle 'y' register correctly XXX */
1035
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
1036
- 32 * sizeof(u64),
1037
- 4 * sizeof(u64),
1038
- &pregs->tstate);
1039
- }
1032
+ ret = copy_regset_to_user(child, &ptrace64_view,
1033
+ REGSET_GENERAL, 0,
1034
+ 19 * sizeof(u64),
1035
+ pregs);
10401036 break;
10411037
10421038 case PTRACE_SETREGS64:
1043
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
1044
- 1 * sizeof(u64),
1045
- 15 * sizeof(u64),
1046
- &pregs->u_regs[0]);
1047
- if (!ret) {
1048
- /* XXX doesn't handle 'y' register correctly XXX */
1049
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
1050
- 32 * sizeof(u64),
1051
- 4 * sizeof(u64),
1052
- &pregs->tstate);
1053
- }
1039
+ ret = copy_regset_from_user(child, &ptrace64_view,
1040
+ REGSET_GENERAL, 0,
1041
+ 19 * sizeof(u64),
1042
+ pregs);
10541043 break;
10551044
10561045 case PTRACE_GETFPREGS64: