On the same model as ptrace_get_reg() and ptrace_put_reg(),
create ptrace_get_fpr() and ptrace_put_fpr() to get/set
the floating points registers.

We move the boundary checkings in them.

Signed-off-by: Christophe Leroy <christophe.le...@csgroup.eu>
---
 arch/powerpc/kernel/ptrace/Makefile      |  1 +
 arch/powerpc/kernel/ptrace/ptrace-decl.h |  4 +++
 arch/powerpc/kernel/ptrace/ptrace-fpu.c  | 40 ++++++++++++++++++++++++
 arch/powerpc/kernel/ptrace/ptrace.c      | 40 +++++++-----------------
 4 files changed, 56 insertions(+), 29 deletions(-)
 create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c

diff --git a/arch/powerpc/kernel/ptrace/Makefile 
b/arch/powerpc/kernel/ptrace/Makefile
index c2f2402ebc8c..77abd1a5a508 100644
--- a/arch/powerpc/kernel/ptrace/Makefile
+++ b/arch/powerpc/kernel/ptrace/Makefile
@@ -6,6 +6,7 @@
 CFLAGS_ptrace-view.o           += -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
 obj-y                          += ptrace.o ptrace-view.o
+obj-y                          += ptrace-fpu.o
 obj-$(CONFIG_COMPAT)           += ptrace32.o
 obj-$(CONFIG_VSX)              += ptrace-vsx.o
 ifneq ($(CONFIG_VSX),y)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h 
b/arch/powerpc/kernel/ptrace/ptrace-decl.h
index 2ddc68412fa8..eafe5f0f6289 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
+++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
@@ -164,6 +164,10 @@ int ptrace_put_reg(struct task_struct *task, int regno, 
unsigned long data);
 
 extern const struct user_regset_view user_ppc_native_view;
 
+/* ptrace-fpu */
+int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
+int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
+
 /* ptrace-(no)adv */
 void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
 int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c 
b/arch/powerpc/kernel/ptrace/ptrace-fpu.c
new file mode 100644
index 000000000000..8301cb52dd99
--- /dev/null
+++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/regset.h>
+
+#include <asm/switch_to.h>
+
+#include "ptrace-decl.h"
+
+int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
+{
+       unsigned int fpidx = index - PT_FPR0;
+
+       if (index > PT_FPSCR)
+               return -EIO;
+
+       flush_fp_to_thread(child);
+       if (fpidx < (PT_FPSCR - PT_FPR0))
+               memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
+       else
+               *data = child->thread.fp_state.fpscr;
+
+       return 0;
+}
+
+int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
+{
+       unsigned int fpidx = index - PT_FPR0;
+
+       if (index > PT_FPSCR)
+               return -EIO;
+
+       flush_fp_to_thread(child);
+       if (fpidx < (PT_FPSCR - PT_FPR0))
+               memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
+       else
+               child->thread.fp_state.fpscr = data;
+
+       return 0;
+}
+
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c 
b/arch/powerpc/kernel/ptrace/ptrace.c
index 51557a9c0765..3d44b73adb83 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -56,25 +56,17 @@ long arch_ptrace(struct task_struct *child, long request,
                ret = -EIO;
                /* convert to index and check */
                index = addr / sizeof(long);
-               if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR)
-                   || (child->thread.regs == NULL))
+               if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
                        break;
 
                CHECK_FULL_REGS(child->thread.regs);
-               if (index < PT_FPR0) {
+               if (index < PT_FPR0)
                        ret = ptrace_get_reg(child, (int) index, &tmp);
-                       if (ret)
-                               break;
-               } else {
-                       unsigned int fpidx = index - PT_FPR0;
-
-                       flush_fp_to_thread(child);
-                       if (fpidx < (PT_FPSCR - PT_FPR0))
-                               memcpy(&tmp, &child->thread.TS_FPR(fpidx),
-                                      sizeof(long));
-                       else
-                               tmp = child->thread.fp_state.fpscr;
-               }
+               else
+                       ret = ptrace_get_fpr(child, index, &tmp);
+
+               if (ret)
+                       break;
                ret = put_user(tmp, datalp);
                break;
        }
@@ -86,24 +78,14 @@ long arch_ptrace(struct task_struct *child, long request,
                ret = -EIO;
                /* convert to index and check */
                index = addr / sizeof(long);
-               if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR)
-                   || (child->thread.regs == NULL))
+               if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
                        break;
 
                CHECK_FULL_REGS(child->thread.regs);
-               if (index < PT_FPR0) {
+               if (index < PT_FPR0)
                        ret = ptrace_put_reg(child, index, data);
-               } else {
-                       unsigned int fpidx = index - PT_FPR0;
-
-                       flush_fp_to_thread(child);
-                       if (fpidx < (PT_FPSCR - PT_FPR0))
-                               memcpy(&child->thread.TS_FPR(fpidx), &data,
-                                      sizeof(long));
-                       else
-                               child->thread.fp_state.fpscr = data;
-                       ret = 0;
-               }
+               else
+                       ret = ptrace_put_fpr(child, index, data);
                break;
        }
 
-- 
2.25.0

Reply via email to