sparc: switch to ->regset_get()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 22 Feb 2020 05:19:46 +0000 (00:19 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 27 Jul 2020 18:31:08 +0000 (14:31 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/sparc/kernel/ptrace_32.c
arch/sparc/kernel/ptrace_64.c

index 144e5a6..5318174 100644 (file)
@@ -83,39 +83,25 @@ static int regwindow32_set(struct task_struct *target,
 
 static int genregs32_get(struct task_struct *target,
                         const struct user_regset *regset,
-                        unsigned int pos, unsigned int count,
-                        void *kbuf, void __user *ubuf)
+                        struct membuf to)
 {
        const struct pt_regs *regs = target->thread.kregs;
        u32 uregs[16];
-       int ret;
 
        if (target == current)
                flush_user_windows();
 
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 regs->u_regs,
-                                 0, 16 * sizeof(u32));
-       if (ret || !count)
-               return ret;
-
+       membuf_write(&to, regs->u_regs, 16 * sizeof(u32));
+       if (!to.left)
+               return 0;
        if (regwindow32_get(target, regs, uregs))
                return -EFAULT;
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 uregs,
-                                 16 * sizeof(u32), 32 * sizeof(u32));
-       if (ret)
-               return ret;
-
-       uregs[0] = regs->psr;
-       uregs[1] = regs->pc;
-       uregs[2] = regs->npc;
-       uregs[3] = regs->y;
-       uregs[4] = 0;   /* WIM */
-       uregs[5] = 0;   /* TBR */
-       return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 uregs,
-                                 32 * sizeof(u32), 38 * sizeof(u32));
+       membuf_write(&to, uregs, 16 * sizeof(u32));
+       membuf_store(&to, regs->psr);
+       membuf_store(&to, regs->pc);
+       membuf_store(&to, regs->npc);
+       membuf_store(&to, regs->y);
+       return membuf_zero(&to, 2 * sizeof(u32));
 }
 
 static int genregs32_set(struct task_struct *target,
@@ -179,46 +165,18 @@ static int genregs32_set(struct task_struct *target,
 
 static int fpregs32_get(struct task_struct *target,
                        const struct user_regset *regset,
-                       unsigned int pos, unsigned int count,
-                       void *kbuf, void __user *ubuf)
+                       struct membuf to)
 {
-       const unsigned long *fpregs = target->thread.float_regs;
-       int ret = 0;
-
 #if 0
        if (target == current)
                save_and_clear_fpu();
 #endif
 
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 fpregs,
-                                 0, 32 * sizeof(u32));
-
-       if (!ret)
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                              32 * sizeof(u32),
-                                              33 * sizeof(u32));
-       if (!ret)
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &target->thread.fsr,
-                                         33 * sizeof(u32),
-                                         34 * sizeof(u32));
-
-       if (!ret) {
-               unsigned long val;
-
-               val = (1 << 8) | (8 << 16);
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &val,
-                                         34 * sizeof(u32),
-                                         35 * sizeof(u32));
-       }
-
-       if (!ret)
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                              35 * sizeof(u32), -1);
-
-       return ret;
+       membuf_write(&to, target->thread.float_regs, 32 * sizeof(u32));
+       membuf_zero(&to, sizeof(u32));
+       membuf_write(&to, &target->thread.fsr, sizeof(u32));
+       membuf_store(&to, (u32)((1 << 8) | (8 << 16)));
+       return membuf_zero(&to, 64 * sizeof(u32));
 }
 
 static int fpregs32_set(struct task_struct *target,
@@ -263,7 +221,7 @@ static const struct user_regset sparc32_regsets[] = {
                .core_note_type = NT_PRSTATUS,
                .n = 38,
                .size = sizeof(u32), .align = sizeof(u32),
-               .get = genregs32_get, .set = genregs32_set
+               .regset_get = genregs32_get, .set = genregs32_set
        },
        /* Format is:
         *      F0 --> F31
@@ -279,35 +237,24 @@ static const struct user_regset sparc32_regsets[] = {
                .core_note_type = NT_PRFPREG,
                .n = 99,
                .size = sizeof(u32), .align = sizeof(u32),
-               .get = fpregs32_get, .set = fpregs32_set
+               .regset_get = fpregs32_get, .set = fpregs32_set
        },
 };
 
 static int getregs_get(struct task_struct *target,
                         const struct user_regset *regset,
-                        unsigned int pos, unsigned int count,
-                        void *kbuf, void __user *ubuf)
+                        struct membuf to)
 {
        const struct pt_regs *regs = target->thread.kregs;
-       u32 v[4];
-       int ret;
 
        if (target == current)
                flush_user_windows();
 
-       v[0] = regs->psr;
-       v[1] = regs->pc;
-       v[2] = regs->npc;
-       v[3] = regs->y;
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 v,
-                                 0 * sizeof(u32), 4 * sizeof(u32));
-       if (ret)
-               return ret;
-
-       return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 regs->u_regs + 1,
-                                 4 * sizeof(u32), 19 * sizeof(u32));
+       membuf_store(&to, regs->psr);
+       membuf_store(&to, regs->pc);
+       membuf_store(&to, regs->npc);
+       membuf_store(&to, regs->y);
+       return membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u32));
 }
 
 static int setregs_set(struct task_struct *target,
@@ -339,29 +286,15 @@ static int setregs_set(struct task_struct *target,
 
 static int getfpregs_get(struct task_struct *target,
                        const struct user_regset *regset,
-                       unsigned int pos, unsigned int count,
-                       void *kbuf, void __user *ubuf)
+                       struct membuf to)
 {
-       const unsigned long *fpregs = target->thread.float_regs;
-       int ret = 0;
-
 #if 0
        if (target == current)
                save_and_clear_fpu();
 #endif
-
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 fpregs,
-                                 0, 32 * sizeof(u32));
-       if (ret)
-               return ret;
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 &target->thread.fsr,
-                                 32 * sizeof(u32), 33 * sizeof(u32));
-       if (ret)
-               return ret;
-       return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                 33 * sizeof(u32), 68 * sizeof(u32));
+       membuf_write(&to, &target->thread.float_regs, 32 * sizeof(u32));
+       membuf_write(&to, &target->thread.fsr, sizeof(u32));
+       return membuf_zero(&to, 35 * sizeof(u32));
 }
 
 static int setfpregs_set(struct task_struct *target,
@@ -390,11 +323,11 @@ static int setfpregs_set(struct task_struct *target,
 static const struct user_regset ptrace32_regsets[] = {
        [REGSET_GENERAL] = {
                .n = 19, .size = sizeof(u32),
-               .get = getregs_get, .set = setregs_set,
+               .regset_get = getregs_get, .set = setregs_set,
        },
        [REGSET_FP] = {
                .n = 68, .size = sizeof(u32),
-               .get = getfpregs_get, .set = setfpregs_set,
+               .regset_get = getfpregs_get, .set = setfpregs_set,
        },
 };
 
index 3c9eee1..2b92155 100644 (file)
@@ -246,52 +246,23 @@ enum sparc_regset {
 
 static int genregs64_get(struct task_struct *target,
                         const struct user_regset *regset,
-                        unsigned int pos, unsigned int count,
-                        void *kbuf, void __user *ubuf)
+                        struct membuf to)
 {
        const struct pt_regs *regs = task_pt_regs(target);
-       int ret;
+       struct reg_window window;
 
        if (target == current)
                flushw_user();
 
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 regs->u_regs,
-                                 0, 16 * sizeof(u64));
-       if (!ret && count) {
-               struct reg_window window;
-
-               if (regwindow64_get(target, regs, &window))
-                       return -EFAULT;
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &window,
-                                         16 * sizeof(u64),
-                                         32 * sizeof(u64));
-       }
-
-       if (!ret) {
-               /* TSTATE, TPC, TNPC */
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &regs->tstate,
-                                         32 * sizeof(u64),
-                                         35 * sizeof(u64));
-       }
-
-       if (!ret) {
-               unsigned long y = regs->y;
-
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &y,
-                                         35 * sizeof(u64),
-                                         36 * sizeof(u64));
-       }
-
-       if (!ret) {
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                              36 * sizeof(u64), -1);
-
-       }
-       return ret;
+       membuf_write(&to, regs->u_regs, 16 * sizeof(u64));
+       if (!to.left)
+               return 0;
+       if (regwindow64_get(target, regs, &window))
+               return -EFAULT;
+       membuf_write(&to, &window, 16 * sizeof(u64));
+       /* TSTATE, TPC, TNPC */
+       membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
+       return membuf_store(&to, (u64)regs->y);
 }
 
 static int genregs64_set(struct task_struct *target,
@@ -370,69 +341,32 @@ static int genregs64_set(struct task_struct *target,
 
 static int fpregs64_get(struct task_struct *target,
                        const struct user_regset *regset,
-                       unsigned int pos, unsigned int count,
-                       void *kbuf, void __user *ubuf)
+                       struct membuf to)
 {
-       const unsigned long *fpregs = task_thread_info(target)->fpregs;
-       unsigned long fprs, fsr, gsr;
-       int ret;
+       struct thread_info *t = task_thread_info(target);
+       unsigned long fprs;
 
        if (target == current)
                save_and_clear_fpu();
 
-       fprs = task_thread_info(target)->fpsaved[0];
+       fprs = t->fpsaved[0];
 
        if (fprs & FPRS_DL)
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         fpregs,
-                                         0, 16 * sizeof(u64));
+               membuf_write(&to, t->fpregs, 16 * sizeof(u64));
        else
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                              0,
-                                              16 * sizeof(u64));
-
-       if (!ret) {
-               if (fprs & FPRS_DU)
-                       ret = user_regset_copyout(&pos, &count,
-                                                 &kbuf, &ubuf,
-                                                 fpregs + 16,
-                                                 16 * sizeof(u64),
-                                                 32 * sizeof(u64));
-               else
-                       ret = user_regset_copyout_zero(&pos, &count,
-                                                      &kbuf, &ubuf,
-                                                      16 * sizeof(u64),
-                                                      32 * sizeof(u64));
-       }
+               membuf_zero(&to, 16 * sizeof(u64));
 
+       if (fprs & FPRS_DU)
+               membuf_write(&to, t->fpregs + 16, 16 * sizeof(u64));
+       else
+               membuf_zero(&to, 16 * sizeof(u64));
        if (fprs & FPRS_FEF) {
-               fsr = task_thread_info(target)->xfsr[0];
-               gsr = task_thread_info(target)->gsr[0];
+               membuf_store(&to, t->xfsr[0]);
+               membuf_store(&to, t->gsr[0]);
        } else {
-               fsr = gsr = 0;
+               membuf_zero(&to, 2 * sizeof(u64));
        }
-
-       if (!ret)
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &fsr,
-                                         32 * sizeof(u64),
-                                         33 * sizeof(u64));
-       if (!ret)
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &gsr,
-                                         33 * sizeof(u64),
-                                         34 * sizeof(u64));
-       if (!ret)
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &fprs,
-                                         34 * sizeof(u64),
-                                         35 * sizeof(u64));
-
-       if (!ret)
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                              35 * sizeof(u64), -1);
-
-       return ret;
+       return membuf_store(&to, fprs);
 }
 
 static int fpregs64_set(struct task_struct *target,
@@ -490,7 +424,7 @@ static const struct user_regset sparc64_regsets[] = {
                .core_note_type = NT_PRSTATUS,
                .n = 36,
                .size = sizeof(u64), .align = sizeof(u64),
-               .get = genregs64_get, .set = genregs64_set
+               .regset_get = genregs64_get, .set = genregs64_set
        },
        /* Format is:
         *      F0 --> F63
@@ -502,43 +436,23 @@ static const struct user_regset sparc64_regsets[] = {
                .core_note_type = NT_PRFPREG,
                .n = 35,
                .size = sizeof(u64), .align = sizeof(u64),
-               .get = fpregs64_get, .set = fpregs64_set
+               .regset_get = fpregs64_get, .set = fpregs64_set
        },
 };
 
 static int getregs64_get(struct task_struct *target,
                         const struct user_regset *regset,
-                        unsigned int pos, unsigned int count,
-                        void *kbuf, void __user *ubuf)
+                        struct membuf to)
 {
        const struct pt_regs *regs = task_pt_regs(target);
-       int ret;
 
        if (target == current)
                flushw_user();
 
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 regs->u_regs + 1,
-                                 0, 15 * sizeof(u64));
-       if (!ret)
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                 15 * sizeof(u64), 16 * sizeof(u64));
-       if (!ret) {
-               /* TSTATE, TPC, TNPC */
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &regs->tstate,
-                                         16 * sizeof(u64),
-                                         19 * sizeof(u64));
-       }
-       if (!ret) {
-               unsigned long y = regs->y;
-
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &y,
-                                         19 * sizeof(u64),
-                                         20 * sizeof(u64));
-       }
-       return ret;
+       membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u64));
+       membuf_store(&to, (u64)0);
+       membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
+       return membuf_store(&to, (u64)regs->y);
 }
 
 static int setregs64_set(struct task_struct *target,
@@ -604,7 +518,7 @@ static const struct user_regset ptrace64_regsets[] = {
         */
        [REGSET_GENERAL] = {
                .n = 20, .size = sizeof(u64),
-               .get = getregs64_get, .set = setregs64_set,
+               .regset_get = getregs64_get, .set = setregs64_set,
        },
 };
 
@@ -620,81 +534,28 @@ static const struct user_regset_view user_sparc64_view = {
 #ifdef CONFIG_COMPAT
 static int genregs32_get(struct task_struct *target,
                         const struct user_regset *regset,
-                        unsigned int pos, unsigned int count,
-                        void *kbuf, void __user *ubuf)
+                        struct membuf to)
 {
        const struct pt_regs *regs = task_pt_regs(target);
-       compat_ulong_t *k = kbuf;
-       compat_ulong_t __user *u = ubuf;
        u32 uregs[16];
-       u32 reg;
+       int i;
 
        if (target == current)
                flushw_user();
 
-       pos /= sizeof(reg);
-       count /= sizeof(reg);
-
-       if (kbuf) {
-               for (; count > 0 && pos < 16; count--)
-                       *k++ = regs->u_regs[pos++];
-
-               if (count) {
-                       if (get_from_target(target, regs->u_regs[UREG_I6],
-                                       uregs, sizeof(uregs)))
-                               return -EFAULT;
-                       for (; count > 0 && pos < 32; count--)
-                               *k++ = uregs[pos++ - 16];
-
-               }
-       } else {
-               for (; count > 0 && pos < 16; count--)
-                       if (put_user((compat_ulong_t) regs->u_regs[pos++], u++))
-                               return -EFAULT;
-               if (count) {
-                       if (get_from_target(target, regs->u_regs[UREG_I6],
-                                       uregs, sizeof(uregs)))
-                               return -EFAULT;
-                       for (; count > 0 && pos < 32; count--)
-                               if (put_user(uregs[pos++ - 16], u++))
-                                       return -EFAULT;
-               }
-       }
-       while (count > 0) {
-               switch (pos) {
-               case 32: /* PSR */
-                       reg = tstate_to_psr(regs->tstate);
-                       break;
-               case 33: /* PC */
-                       reg = regs->tpc;
-                       break;
-               case 34: /* NPC */
-                       reg = regs->tnpc;
-                       break;
-               case 35: /* Y */
-                       reg = regs->y;
-                       break;
-               case 36: /* WIM */
-               case 37: /* TBR */
-                       reg = 0;
-                       break;
-               default:
-                       goto finish;
-               }
-
-               if (kbuf)
-                       *k++ = reg;
-               else if (put_user(reg, u++))
-                       return -EFAULT;
-               pos++;
-               count--;
-       }
-finish:
-       pos *= sizeof(reg);
-       count *= sizeof(reg);
-
-       return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                       38 * sizeof(reg), -1);
+       for (i = 0; i < 16; i++)
+               membuf_store(&to, (u32)regs->u_regs[i]);
+       if (!to.left)
+               return 0;
+       if (get_from_target(target, regs->u_regs[UREG_I6],
+                           uregs, sizeof(uregs)))
+               return -EFAULT;
+       membuf_write(&to, uregs, 16 * sizeof(u32));
+       membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
+       membuf_store(&to, (u32)(regs->tpc));
+       membuf_store(&to, (u32)(regs->tnpc));
+       membuf_store(&to, (u32)(regs->y));
+       return membuf_zero(&to, 2 * sizeof(u32));
 }
 
 static int genregs32_set(struct task_struct *target,
@@ -816,56 +677,24 @@ finish:
 
 static int fpregs32_get(struct task_struct *target,
                        const struct user_regset *regset,
-                       unsigned int pos, unsigned int count,
-                       void *kbuf, void __user *ubuf)
+                       struct membuf to)
 {
-       const unsigned long *fpregs = task_thread_info(target)->fpregs;
-       compat_ulong_t enabled;
-       unsigned long fprs;
-       compat_ulong_t fsr;
-       int ret = 0;
+       struct thread_info *t = task_thread_info(target);
+       bool enabled;
 
        if (target == current)
                save_and_clear_fpu();
 
-       fprs = task_thread_info(target)->fpsaved[0];
-       if (fprs & FPRS_FEF) {
-               fsr = task_thread_info(target)->xfsr[0];
-               enabled = 1;
-       } else {
-               fsr = 0;
-               enabled = 0;
-       }
-
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 fpregs,
-                                 0, 32 * sizeof(u32));
-
-       if (!ret)
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                              32 * sizeof(u32),
-                                              33 * sizeof(u32));
-       if (!ret)
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &fsr,
-                                         33 * sizeof(u32),
-                                         34 * sizeof(u32));
+       enabled = t->fpsaved[0] & FPRS_FEF;
 
-       if (!ret) {
-               compat_ulong_t val;
-
-               val = (enabled << 8) | (8 << 16);
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &val,
-                                         34 * sizeof(u32),
-                                         35 * sizeof(u32));
-       }
-
-       if (!ret)
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                              35 * sizeof(u32), -1);
-
-       return ret;
+       membuf_write(&to, t->fpregs, 32 * sizeof(u32));
+       membuf_zero(&to, sizeof(u32));
+       if (enabled)
+               membuf_store(&to, (u32)t->xfsr[0]);
+       else
+               membuf_zero(&to, sizeof(u32));
+       membuf_store(&to, (u32)((enabled << 8) | (8 << 16)));
+       return membuf_zero(&to, 64 * sizeof(u32));
 }
 
 static int fpregs32_set(struct task_struct *target,
@@ -926,7 +755,7 @@ static const struct user_regset sparc32_regsets[] = {
                .core_note_type = NT_PRSTATUS,
                .n = 38,
                .size = sizeof(u32), .align = sizeof(u32),
-               .get = genregs32_get, .set = genregs32_set
+               .regset_get = genregs32_get, .set = genregs32_set
        },
        /* Format is:
         *      F0 --> F31
@@ -942,31 +771,27 @@ static const struct user_regset sparc32_regsets[] = {
                .core_note_type = NT_PRFPREG,
                .n = 99,
                .size = sizeof(u32), .align = sizeof(u32),
-               .get = fpregs32_get, .set = fpregs32_set
+               .regset_get = fpregs32_get, .set = fpregs32_set
        },
 };
 
 static int getregs_get(struct task_struct *target,
-                      const struct user_regset *regset,
-                      unsigned int pos, unsigned int count,
-                      void *kbuf, void __user *ubuf)
+                        const struct user_regset *regset,
+                        struct membuf to)
 {
        const struct pt_regs *regs = task_pt_regs(target);
-       u32 uregs[19];
        int i;
 
        if (target == current)
                flushw_user();
 
-       uregs[0] = tstate_to_psr(regs->tstate);
-       uregs[1] = regs->tpc;
-       uregs[2] = regs->tnpc;
-       uregs[3] = regs->y;
+       membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
+       membuf_store(&to, (u32)(regs->tpc));
+       membuf_store(&to, (u32)(regs->tnpc));
+       membuf_store(&to, (u32)(regs->y));
        for (i = 1; i < 16; i++)
-               uregs[3 + i] = regs->u_regs[i];
-       return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                  uregs,
-                                  0, 19 * sizeof(u32));
+               membuf_store(&to, (u32)regs->u_regs[i]);
+       return to.left;
 }
 
 static int setregs_set(struct task_struct *target,
@@ -1005,36 +830,19 @@ static int setregs_set(struct task_struct *target,
 
 static int getfpregs_get(struct task_struct *target,
                        const struct user_regset *regset,
-                       unsigned int pos, unsigned int count,
-                       void *kbuf, void __user *ubuf)
+                       struct membuf to)
 {
-       const unsigned long *fpregs = task_thread_info(target)->fpregs;
-       unsigned long fprs;
-       compat_ulong_t fsr;
-       int ret = 0;
+       struct thread_info *t = task_thread_info(target);
 
        if (target == current)
                save_and_clear_fpu();
 
-       fprs = task_thread_info(target)->fpsaved[0];
-       if (fprs & FPRS_FEF) {
-               fsr = task_thread_info(target)->xfsr[0];
-       } else {
-               fsr = 0;
-       }
-
-       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 fpregs,
-                                 0, 32 * sizeof(u32));
-       if (!ret)
-               ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         &fsr,
-                                         32 * sizeof(u32),
-                                         33 * sizeof(u32));
-       if (!ret)
-               ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
-                                         33 * sizeof(u32), 68 * sizeof(u32));
-       return ret;
+       membuf_write(&to, t->fpregs, 32 * sizeof(u32));
+       if (t->fpsaved[0] & FPRS_FEF)
+               membuf_store(&to, (u32)t->xfsr[0]);
+       else
+               membuf_zero(&to, sizeof(u32));
+       return membuf_zero(&to, 35 * sizeof(u32));
 }
 
 static int setfpregs_set(struct task_struct *target,
@@ -1078,11 +886,11 @@ static int setfpregs_set(struct task_struct *target,
 static const struct user_regset ptrace32_regsets[] = {
        [REGSET_GENERAL] = {
                .n = 19, .size = sizeof(u32),
-               .get = getregs_get, .set = setregs_set,
+               .regset_get = getregs_get, .set = setregs_set,
        },
        [REGSET_FP] = {
                .n = 68, .size = sizeof(u32),
-               .get = getfpregs_get, .set = setfpregs_set,
+               .regset_get = getfpregs_get, .set = setfpregs_set,
        },
 };