MIPS: traps: Never enable FPU when CONFIG_MIPS_FP_SUPPORT=n
authorPaul Burton <paul.burton@mips.com>
Wed, 7 Nov 2018 23:14:05 +0000 (23:14 +0000)
committerPaul Burton <paul.burton@mips.com>
Fri, 9 Nov 2018 18:23:16 +0000 (10:23 -0800)
When CONFIG_MIPS_FP_SUPPORT=n we don't support floating point, so we'll
never need to enable the FPU. Avoid doing so on a Co-Processor Unusable
exception (do_cpu), and remove the Floating Point Exception handler
(do_fpe) which should never be executed when the FPU is disabled.

Signed-off-by: Paul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/21007/
Cc: linux-mips@linux-mips.org
arch/mips/kernel/genex.S
arch/mips/kernel/traps.c

index 6c257b52f57fb00ae9174da336c276d9ba9471f8..6c0c0d0c30bd2f9268361cf7ccbdf98bd4e9585a 100644 (file)
@@ -553,7 +553,9 @@ NESTED(nmi_handler, PT_SIZE, sp)
        BUILD_HANDLER ov ov sti silent                  /* #12 */
        BUILD_HANDLER tr tr sti silent                  /* #13 */
        BUILD_HANDLER msa_fpe msa_fpe msa_fpe silent    /* #14 */
+#ifdef CONFIG_MIPS_FP_SUPPORT
        BUILD_HANDLER fpe fpe fpe silent                /* #15 */
+#endif
        BUILD_HANDLER ftlb ftlb none silent             /* #16 */
        BUILD_HANDLER msa msa sti silent                /* #21 */
        BUILD_HANDLER mdmx mdmx sti silent              /* #22 */
index db52d30eacec51e9ebde7c3ba95569c3bedc3321..6eb89fd95533f2314f215cca41c59db32009ab1d 100644 (file)
@@ -706,6 +706,8 @@ asmlinkage void do_ov(struct pt_regs *regs)
        exception_exit(prev_state);
 }
 
+#ifdef CONFIG_MIPS_FP_SUPPORT
+
 /*
  * Send SIGFPE according to FCSR Cause bits, which must have already
  * been masked against Enable bits.  This is impotant as Inexact can
@@ -871,6 +873,45 @@ out:
        exception_exit(prev_state);
 }
 
+/*
+ * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've
+ * emulated more than some threshold number of instructions, force migration to
+ * a "CPU" that has FP support.
+ */
+static void mt_ase_fp_affinity(void)
+{
+#ifdef CONFIG_MIPS_MT_FPAFF
+       if (mt_fpemul_threshold > 0 &&
+            ((current->thread.emulated_fp++ > mt_fpemul_threshold))) {
+               /*
+                * If there's no FPU present, or if the application has already
+                * restricted the allowed set to exclude any CPUs with FPUs,
+                * we'll skip the procedure.
+                */
+               if (cpumask_intersects(&current->cpus_allowed, &mt_fpu_cpumask)) {
+                       cpumask_t tmask;
+
+                       current->thread.user_cpus_allowed
+                               = current->cpus_allowed;
+                       cpumask_and(&tmask, &current->cpus_allowed,
+                                   &mt_fpu_cpumask);
+                       set_cpus_allowed_ptr(current, &tmask);
+                       set_thread_flag(TIF_FPUBOUND);
+               }
+       }
+#endif /* CONFIG_MIPS_MT_FPAFF */
+}
+
+#else /* !CONFIG_MIPS_FP_SUPPORT */
+
+static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
+                      unsigned long old_epc, unsigned long old_ra)
+{
+       return -1;
+}
+
+#endif /* !CONFIG_MIPS_FP_SUPPORT */
+
 void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
        const char *str)
 {
@@ -1154,35 +1195,6 @@ out:
        exception_exit(prev_state);
 }
 
-/*
- * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've
- * emulated more than some threshold number of instructions, force migration to
- * a "CPU" that has FP support.
- */
-static void mt_ase_fp_affinity(void)
-{
-#ifdef CONFIG_MIPS_MT_FPAFF
-       if (mt_fpemul_threshold > 0 &&
-            ((current->thread.emulated_fp++ > mt_fpemul_threshold))) {
-               /*
-                * If there's no FPU present, or if the application has already
-                * restricted the allowed set to exclude any CPUs with FPUs,
-                * we'll skip the procedure.
-                */
-               if (cpumask_intersects(&current->cpus_allowed, &mt_fpu_cpumask)) {
-                       cpumask_t tmask;
-
-                       current->thread.user_cpus_allowed
-                               = current->cpus_allowed;
-                       cpumask_and(&tmask, &current->cpus_allowed,
-                                   &mt_fpu_cpumask);
-                       set_cpus_allowed_ptr(current, &tmask);
-                       set_thread_flag(TIF_FPUBOUND);
-               }
-       }
-#endif /* CONFIG_MIPS_MT_FPAFF */
-}
-
 /*
  * No lock; only written during early bootup by CPU 0.
  */
@@ -1210,6 +1222,8 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
        return NOTIFY_OK;
 }
 
+#ifdef CONFIG_MIPS_FP_SUPPORT
+
 static int enable_restore_fp_context(int msa)
 {
        int err, was_fpu_owner, prior_msa;
@@ -1317,17 +1331,23 @@ out:
        return 0;
 }
 
+#else /* !CONFIG_MIPS_FP_SUPPORT */
+
+static int enable_restore_fp_context(int msa)
+{
+       return SIGILL;
+}
+
+#endif /* CONFIG_MIPS_FP_SUPPORT */
+
 asmlinkage void do_cpu(struct pt_regs *regs)
 {
        enum ctx_state prev_state;
        unsigned int __user *epc;
        unsigned long old_epc, old31;
-       void __user *fault_addr;
        unsigned int opcode;
-       unsigned long fcr31;
        unsigned int cpid;
-       int status, err;
-       int sig;
+       int status;
 
        prev_state = exception_enter();
        cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
@@ -1365,6 +1385,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
 
                break;
 
+#ifdef CONFIG_MIPS_FP_SUPPORT
        case 3:
                /*
                 * The COP3 opcode space and consequently the CP0.Status.CU3
@@ -1384,7 +1405,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
                }
                /* Fall through.  */
 
-       case 1:
+       case 1: {
+               void __user *fault_addr;
+               unsigned long fcr31;
+               int err, sig;
+
                err = enable_restore_fp_context(0);
 
                if (raw_cpu_has_fpu && !err)
@@ -1405,6 +1430,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
                        mt_ase_fp_affinity();
 
                break;
+       }
+#else /* CONFIG_MIPS_FP_SUPPORT */
+       case 1:
+       case 3:
+               force_sig(SIGILL, current);
+               break;
+#endif /* CONFIG_MIPS_FP_SUPPORT */
 
        case 2:
                raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);