MIPS: ptrace: Remove FP support when CONFIG_MIPS_FP_SUPPORT=n
authorPaul Burton <paul.burton@mips.com>
Wed, 7 Nov 2018 23:14:07 +0000 (23:14 +0000)
committerPaul Burton <paul.burton@mips.com>
Fri, 9 Nov 2018 18:23:17 +0000 (10:23 -0800)
When CONFIG_MIPS_FP_SUPPORT=n we don't support floating point, so remove
the related ptrace support. Besides removing code which should not be
needed, this prepares us for the removal of FPU state in struct
task_struct which this code requires.

Signed-off-by: Paul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/21008/
Cc: linux-mips@linux-mips.org
arch/mips/kernel/ptrace.c
arch/mips/kernel/ptrace32.c

index 04db951b0f8c9676bc5be04cc6c30775dc6c5a6b..d7d032f2b6569192c372608b900d67835c98ef93 100644 (file)
@@ -61,21 +61,6 @@ void ptrace_disable(struct task_struct *child)
        clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
 }
 
-/*
- * Poke at FCSR according to its mask.  Set the Cause bits even
- * if a corresponding Enable bit is set.  This will be noticed at
- * the time the thread is switched to and SIGFPE thrown accordingly.
- */
-static void ptrace_setfcr31(struct task_struct *child, u32 value)
-{
-       u32 fcr31;
-       u32 mask;
-
-       fcr31 = child->thread.fpu.fcr31;
-       mask = boot_cpu_data.fpu_msk31;
-       child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
-}
-
 /*
  * Read a general register set.         We always use the 64-bit format, even
  * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
@@ -132,55 +117,6 @@ int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data)
        return 0;
 }
 
-int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
-{
-       int i;
-
-       if (!access_ok(VERIFY_WRITE, data, 33 * 8))
-               return -EIO;
-
-       if (tsk_used_math(child)) {
-               union fpureg *fregs = get_fpu_regs(child);
-               for (i = 0; i < 32; i++)
-                       __put_user(get_fpr64(&fregs[i], 0),
-                                  i + (__u64 __user *)data);
-       } else {
-               for (i = 0; i < 32; i++)
-                       __put_user((__u64) -1, i + (__u64 __user *) data);
-       }
-
-       __put_user(child->thread.fpu.fcr31, data + 64);
-       __put_user(boot_cpu_data.fpu_id, data + 65);
-
-       return 0;
-}
-
-int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
-{
-       union fpureg *fregs;
-       u64 fpr_val;
-       u32 value;
-       int i;
-
-       if (!access_ok(VERIFY_READ, data, 33 * 8))
-               return -EIO;
-
-       init_fp_ctx(child);
-       fregs = get_fpu_regs(child);
-
-       for (i = 0; i < 32; i++) {
-               __get_user(fpr_val, i + (__u64 __user *)data);
-               set_fpr64(&fregs[i], 0, fpr_val);
-       }
-
-       __get_user(value, data + 64);
-       ptrace_setfcr31(child, value);
-
-       /* FIR may not be written.  */
-
-       return 0;
-}
-
 int ptrace_get_watch_regs(struct task_struct *child,
                          struct pt_watch_regs __user *addr)
 {
@@ -401,6 +337,73 @@ static int gpr64_set(struct task_struct *target,
 
 #endif /* CONFIG_64BIT */
 
+
+#ifdef CONFIG_MIPS_FP_SUPPORT
+
+/*
+ * Poke at FCSR according to its mask.  Set the Cause bits even
+ * if a corresponding Enable bit is set.  This will be noticed at
+ * the time the thread is switched to and SIGFPE thrown accordingly.
+ */
+static void ptrace_setfcr31(struct task_struct *child, u32 value)
+{
+       u32 fcr31;
+       u32 mask;
+
+       fcr31 = child->thread.fpu.fcr31;
+       mask = boot_cpu_data.fpu_msk31;
+       child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
+}
+
+int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
+{
+       int i;
+
+       if (!access_ok(VERIFY_WRITE, data, 33 * 8))
+               return -EIO;
+
+       if (tsk_used_math(child)) {
+               union fpureg *fregs = get_fpu_regs(child);
+               for (i = 0; i < 32; i++)
+                       __put_user(get_fpr64(&fregs[i], 0),
+                                  i + (__u64 __user *)data);
+       } else {
+               for (i = 0; i < 32; i++)
+                       __put_user((__u64) -1, i + (__u64 __user *) data);
+       }
+
+       __put_user(child->thread.fpu.fcr31, data + 64);
+       __put_user(boot_cpu_data.fpu_id, data + 65);
+
+       return 0;
+}
+
+int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
+{
+       union fpureg *fregs;
+       u64 fpr_val;
+       u32 value;
+       int i;
+
+       if (!access_ok(VERIFY_READ, data, 33 * 8))
+               return -EIO;
+
+       init_fp_ctx(child);
+       fregs = get_fpu_regs(child);
+
+       for (i = 0; i < 32; i++) {
+               __get_user(fpr_val, i + (__u64 __user *)data);
+               set_fpr64(&fregs[i], 0, fpr_val);
+       }
+
+       __get_user(value, data + 64);
+       ptrace_setfcr31(child, value);
+
+       /* FIR may not be written.  */
+
+       return 0;
+}
+
 /*
  * Copy the floating-point context to the supplied NT_PRFPREG buffer,
  * !CONFIG_CPU_HAS_MSA variant.  FP context's general register slots
@@ -571,6 +574,54 @@ static int fpr_set(struct task_struct *target,
        return err;
 }
 
+/* Copy the FP mode setting to the supplied NT_MIPS_FP_MODE buffer.  */
+static int fp_mode_get(struct task_struct *target,
+                      const struct user_regset *regset,
+                      unsigned int pos, unsigned int count,
+                      void *kbuf, void __user *ubuf)
+{
+       int fp_mode;
+
+       fp_mode = mips_get_process_fp_mode(target);
+       return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
+                                  sizeof(fp_mode));
+}
+
+/*
+ * Copy the supplied NT_MIPS_FP_MODE buffer to the FP mode setting.
+ *
+ * We optimize for the case where `count % sizeof(int) == 0', which
+ * is supposed to have been guaranteed by the kernel before calling
+ * us, e.g. in `ptrace_regset'.  We enforce that requirement, so
+ * that we can safely avoid preinitializing temporaries for partial
+ * mode writes.
+ */
+static int fp_mode_set(struct task_struct *target,
+                      const struct user_regset *regset,
+                      unsigned int pos, unsigned int count,
+                      const void *kbuf, const void __user *ubuf)
+{
+       int fp_mode;
+       int err;
+
+       BUG_ON(count % sizeof(int));
+
+       if (pos + count > sizeof(fp_mode))
+               return -EIO;
+
+       err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
+                                sizeof(fp_mode));
+       if (err)
+               return err;
+
+       if (count > 0)
+               err = mips_set_process_fp_mode(target, fp_mode);
+
+       return err;
+}
+
+#endif /* CONFIG_MIPS_FP_SUPPORT */
+
 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
 
 /*
@@ -740,57 +791,13 @@ static int dsp_active(struct task_struct *target,
        return cpu_has_dsp ? NUM_DSP_REGS + 1 : -ENODEV;
 }
 
-/* Copy the FP mode setting to the supplied NT_MIPS_FP_MODE buffer.  */
-static int fp_mode_get(struct task_struct *target,
-                      const struct user_regset *regset,
-                      unsigned int pos, unsigned int count,
-                      void *kbuf, void __user *ubuf)
-{
-       int fp_mode;
-
-       fp_mode = mips_get_process_fp_mode(target);
-       return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
-                                  sizeof(fp_mode));
-}
-
-/*
- * Copy the supplied NT_MIPS_FP_MODE buffer to the FP mode setting.
- *
- * We optimize for the case where `count % sizeof(int) == 0', which
- * is supposed to have been guaranteed by the kernel before calling
- * us, e.g. in `ptrace_regset'.  We enforce that requirement, so
- * that we can safely avoid preinitializing temporaries for partial
- * mode writes.
- */
-static int fp_mode_set(struct task_struct *target,
-                      const struct user_regset *regset,
-                      unsigned int pos, unsigned int count,
-                      const void *kbuf, const void __user *ubuf)
-{
-       int fp_mode;
-       int err;
-
-       BUG_ON(count % sizeof(int));
-
-       if (pos + count > sizeof(fp_mode))
-               return -EIO;
-
-       err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fp_mode, 0,
-                                sizeof(fp_mode));
-       if (err)
-               return err;
-
-       if (count > 0)
-               err = mips_set_process_fp_mode(target, fp_mode);
-
-       return err;
-}
-
 enum mips_regset {
        REGSET_GPR,
-       REGSET_FPR,
        REGSET_DSP,
+#ifdef CONFIG_MIPS_FP_SUPPORT
+       REGSET_FPR,
        REGSET_FP_MODE,
+#endif
 };
 
 struct pt_regs_offset {
@@ -888,14 +895,6 @@ static const struct user_regset mips_regsets[] = {
                .get            = gpr32_get,
                .set            = gpr32_set,
        },
-       [REGSET_FPR] = {
-               .core_note_type = NT_PRFPREG,
-               .n              = ELF_NFPREG,
-               .size           = sizeof(elf_fpreg_t),
-               .align          = sizeof(elf_fpreg_t),
-               .get            = fpr_get,
-               .set            = fpr_set,
-       },
        [REGSET_DSP] = {
                .core_note_type = NT_MIPS_DSP,
                .n              = NUM_DSP_REGS + 1,
@@ -905,6 +904,15 @@ static const struct user_regset mips_regsets[] = {
                .set            = dsp32_set,
                .active         = dsp_active,
        },
+#ifdef CONFIG_MIPS_FP_SUPPORT
+       [REGSET_FPR] = {
+               .core_note_type = NT_PRFPREG,
+               .n              = ELF_NFPREG,
+               .size           = sizeof(elf_fpreg_t),
+               .align          = sizeof(elf_fpreg_t),
+               .get            = fpr_get,
+               .set            = fpr_set,
+       },
        [REGSET_FP_MODE] = {
                .core_note_type = NT_MIPS_FP_MODE,
                .n              = 1,
@@ -913,6 +921,7 @@ static const struct user_regset mips_regsets[] = {
                .get            = fp_mode_get,
                .set            = fp_mode_set,
        },
+#endif
 };
 
 static const struct user_regset_view user_mips_view = {
@@ -936,14 +945,6 @@ static const struct user_regset mips64_regsets[] = {
                .get            = gpr64_get,
                .set            = gpr64_set,
        },
-       [REGSET_FPR] = {
-               .core_note_type = NT_PRFPREG,
-               .n              = ELF_NFPREG,
-               .size           = sizeof(elf_fpreg_t),
-               .align          = sizeof(elf_fpreg_t),
-               .get            = fpr_get,
-               .set            = fpr_set,
-       },
        [REGSET_DSP] = {
                .core_note_type = NT_MIPS_DSP,
                .n              = NUM_DSP_REGS + 1,
@@ -953,6 +954,7 @@ static const struct user_regset mips64_regsets[] = {
                .set            = dsp64_set,
                .active         = dsp_active,
        },
+#ifdef CONFIG_MIPS_FP_SUPPORT
        [REGSET_FP_MODE] = {
                .core_note_type = NT_MIPS_FP_MODE,
                .n              = 1,
@@ -961,6 +963,15 @@ static const struct user_regset mips64_regsets[] = {
                .get            = fp_mode_get,
                .set            = fp_mode_set,
        },
+       [REGSET_FPR] = {
+               .core_note_type = NT_PRFPREG,
+               .n              = ELF_NFPREG,
+               .size           = sizeof(elf_fpreg_t),
+               .align          = sizeof(elf_fpreg_t),
+               .get            = fpr_get,
+               .set            = fpr_set,
+       },
+#endif
 };
 
 static const struct user_regset_view user_mips64_view = {
@@ -1021,7 +1032,6 @@ long arch_ptrace(struct task_struct *child, long request,
        /* Read the word at location addr in the USER area. */
        case PTRACE_PEEKUSR: {
                struct pt_regs *regs;
-               union fpureg *fregs;
                unsigned long tmp = 0;
 
                regs = task_pt_regs(child);
@@ -1031,7 +1041,10 @@ long arch_ptrace(struct task_struct *child, long request,
                case 0 ... 31:
                        tmp = regs->regs[addr];
                        break;
-               case FPR_BASE ... FPR_BASE + 31:
+#ifdef CONFIG_MIPS_FP_SUPPORT
+               case FPR_BASE ... FPR_BASE + 31: {
+                       union fpureg *fregs;
+
                        if (!tsk_used_math(child)) {
                                /* FP not yet used */
                                tmp = -1;
@@ -1053,6 +1066,15 @@ long arch_ptrace(struct task_struct *child, long request,
 #endif
                        tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
                        break;
+               }
+               case FPC_CSR:
+                       tmp = child->thread.fpu.fcr31;
+                       break;
+               case FPC_EIR:
+                       /* implementation / version register */
+                       tmp = boot_cpu_data.fpu_id;
+                       break;
+#endif
                case PC:
                        tmp = regs->cp0_epc;
                        break;
@@ -1073,13 +1095,6 @@ long arch_ptrace(struct task_struct *child, long request,
                        tmp = regs->acx;
                        break;
 #endif
-               case FPC_CSR:
-                       tmp = child->thread.fpu.fcr31;
-                       break;
-               case FPC_EIR:
-                       /* implementation / version register */
-                       tmp = boot_cpu_data.fpu_id;
-                       break;
                case DSP_BASE ... DSP_BASE + 5: {
                        dspreg_t *dregs;
 
@@ -1130,6 +1145,7 @@ long arch_ptrace(struct task_struct *child, long request,
                                 mips_syscall_is_indirect(child, regs))
                                mips_syscall_update_nr(child, regs);
                        break;
+#ifdef CONFIG_MIPS_FP_SUPPORT
                case FPR_BASE ... FPR_BASE + 31: {
                        union fpureg *fregs = get_fpu_regs(child);
 
@@ -1149,6 +1165,11 @@ long arch_ptrace(struct task_struct *child, long request,
                        set_fpr64(&fregs[addr - FPR_BASE], 0, data);
                        break;
                }
+               case FPC_CSR:
+                       init_fp_ctx(child);
+                       ptrace_setfcr31(child, data);
+                       break;
+#endif
                case PC:
                        regs->cp0_epc = data;
                        break;
@@ -1163,10 +1184,6 @@ long arch_ptrace(struct task_struct *child, long request,
                        regs->acx = data;
                        break;
 #endif
-               case FPC_CSR:
-                       init_fp_ctx(child);
-                       ptrace_setfcr31(child, data);
-                       break;
                case DSP_BASE ... DSP_BASE + 5: {
                        dspreg_t *dregs;
 
@@ -1202,6 +1219,7 @@ long arch_ptrace(struct task_struct *child, long request,
                ret = ptrace_setregs(child, datavp);
                break;
 
+#ifdef CONFIG_MIPS_FP_SUPPORT
        case PTRACE_GETFPREGS:
                ret = ptrace_getfpregs(child, datavp);
                break;
@@ -1209,7 +1227,7 @@ long arch_ptrace(struct task_struct *child, long request,
        case PTRACE_SETFPREGS:
                ret = ptrace_setfpregs(child, datavp);
                break;
-
+#endif
        case PTRACE_GET_THREAD_AREA:
                ret = put_user(task_thread_info(child)->tp_value, datalp);
                break;
index bc348d44d151705770c9e4c1275fe0ed750a7050..2525eca9c9629dc6089e449f32f7805b0078cb38 100644 (file)
@@ -82,7 +82,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
        /* Read the word at location addr in the USER area. */
        case PTRACE_PEEKUSR: {
                struct pt_regs *regs;
-               union fpureg *fregs;
                unsigned int tmp;
 
                regs = task_pt_regs(child);
@@ -92,7 +91,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                case 0 ... 31:
                        tmp = regs->regs[addr];
                        break;
-               case FPR_BASE ... FPR_BASE + 31:
+#ifdef CONFIG_MIPS_FP_SUPPORT
+               case FPR_BASE ... FPR_BASE + 31: {
+                       union fpureg *fregs;
+
                        if (!tsk_used_math(child)) {
                                /* FP not yet used */
                                tmp = -1;
@@ -111,6 +113,15 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        }
                        tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
                        break;
+               }
+               case FPC_CSR:
+                       tmp = child->thread.fpu.fcr31;
+                       break;
+               case FPC_EIR:
+                       /* implementation / version register */
+                       tmp = boot_cpu_data.fpu_id;
+                       break;
+#endif /* CONFIG_MIPS_FP_SUPPORT */
                case PC:
                        tmp = regs->cp0_epc;
                        break;
@@ -126,13 +137,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                case MMLO:
                        tmp = regs->lo;
                        break;
-               case FPC_CSR:
-                       tmp = child->thread.fpu.fcr31;
-                       break;
-               case FPC_EIR:
-                       /* implementation / version register */
-                       tmp = boot_cpu_data.fpu_id;
-                       break;
                case DSP_BASE ... DSP_BASE + 5: {
                        dspreg_t *dregs;
 
@@ -203,6 +207,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                                 mips_syscall_is_indirect(child, regs))
                                mips_syscall_update_nr(child, regs);
                        break;
+#ifdef CONFIG_MIPS_FP_SUPPORT
                case FPR_BASE ... FPR_BASE + 31: {
                        union fpureg *fregs = get_fpu_regs(child);
 
@@ -225,6 +230,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        set_fpr64(&fregs[addr - FPR_BASE], 0, data);
                        break;
                }
+               case FPC_CSR:
+                       child->thread.fpu.fcr31 = data;
+                       break;
+#endif /* CONFIG_MIPS_FP_SUPPORT */
                case PC:
                        regs->cp0_epc = data;
                        break;
@@ -234,9 +243,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                case MMLO:
                        regs->lo = data;
                        break;
-               case FPC_CSR:
-                       child->thread.fpu.fcr31 = data;
-                       break;
                case DSP_BASE ... DSP_BASE + 5: {
                        dspreg_t *dregs;
 
@@ -274,6 +280,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                                (struct user_pt_regs __user *) (__u64) data);
                break;
 
+#ifdef CONFIG_MIPS_FP_SUPPORT
        case PTRACE_GETFPREGS:
                ret = ptrace_getfpregs(child, (__u32 __user *) (__u64) data);
                break;
@@ -281,7 +288,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
        case PTRACE_SETFPREGS:
                ret = ptrace_setfpregs(child, (__u32 __user *) (__u64) data);
                break;
-
+#endif
        case PTRACE_GET_THREAD_AREA:
                ret = put_user(task_thread_info(child)->tp_value,
                                (unsigned int __user *) (unsigned long) data);