From 5328f7422e4b195a36b0ed021ce8cc95bd8e0e59 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 7 Nov 2018 23:14:05 +0000 Subject: [PATCH] MIPS: traps: Never enable FPU when CONFIG_MIPS_FP_SUPPORT=n 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 Patchwork: https://patchwork.linux-mips.org/patch/21007/ Cc: linux-mips@linux-mips.org --- arch/mips/kernel/genex.S | 2 + arch/mips/kernel/traps.c | 100 ++++++++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 6c257b52f57f..6c0c0d0c30bd 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -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 */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index db52d30eacec..6eb89fd95533 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -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(¤t->cpus_allowed, &mt_fpu_cpumask)) { + cpumask_t tmask; + + current->thread.user_cpus_allowed + = current->cpus_allowed; + cpumask_and(&tmask, ¤t->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(¤t->cpus_allowed, &mt_fpu_cpumask)) { - cpumask_t tmask; - - current->thread.user_cpus_allowed - = current->cpus_allowed; - cpumask_and(&tmask, ¤t->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); -- 2.30.2