Commit 5328f742 authored by Paul Burton's avatar Paul Burton

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: default avatarPaul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/21007/
Cc: linux-mips@linux-mips.org
parent b2e628a8
...@@ -553,7 +553,9 @@ NESTED(nmi_handler, PT_SIZE, sp) ...@@ -553,7 +553,9 @@ NESTED(nmi_handler, PT_SIZE, sp)
BUILD_HANDLER ov ov sti silent /* #12 */ BUILD_HANDLER ov ov sti silent /* #12 */
BUILD_HANDLER tr tr sti silent /* #13 */ BUILD_HANDLER tr tr sti silent /* #13 */
BUILD_HANDLER msa_fpe msa_fpe msa_fpe silent /* #14 */ BUILD_HANDLER msa_fpe msa_fpe msa_fpe silent /* #14 */
#ifdef CONFIG_MIPS_FP_SUPPORT
BUILD_HANDLER fpe fpe fpe silent /* #15 */ BUILD_HANDLER fpe fpe fpe silent /* #15 */
#endif
BUILD_HANDLER ftlb ftlb none silent /* #16 */ BUILD_HANDLER ftlb ftlb none silent /* #16 */
BUILD_HANDLER msa msa sti silent /* #21 */ BUILD_HANDLER msa msa sti silent /* #21 */
BUILD_HANDLER mdmx mdmx sti silent /* #22 */ BUILD_HANDLER mdmx mdmx sti silent /* #22 */
......
...@@ -706,6 +706,8 @@ asmlinkage void do_ov(struct pt_regs *regs) ...@@ -706,6 +706,8 @@ asmlinkage void do_ov(struct pt_regs *regs)
exception_exit(prev_state); exception_exit(prev_state);
} }
#ifdef CONFIG_MIPS_FP_SUPPORT
/* /*
* Send SIGFPE according to FCSR Cause bits, which must have already * Send SIGFPE according to FCSR Cause bits, which must have already
* been masked against Enable bits. This is impotant as Inexact can * been masked against Enable bits. This is impotant as Inexact can
...@@ -871,6 +873,45 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) ...@@ -871,6 +873,45 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
exception_exit(prev_state); 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, void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
const char *str) const char *str)
{ {
...@@ -1154,35 +1195,6 @@ asmlinkage void do_ri(struct pt_regs *regs) ...@@ -1154,35 +1195,6 @@ asmlinkage void do_ri(struct pt_regs *regs)
exception_exit(prev_state); 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. * 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, ...@@ -1210,6 +1222,8 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
return NOTIFY_OK; return NOTIFY_OK;
} }
#ifdef CONFIG_MIPS_FP_SUPPORT
static int enable_restore_fp_context(int msa) static int enable_restore_fp_context(int msa)
{ {
int err, was_fpu_owner, prior_msa; int err, was_fpu_owner, prior_msa;
...@@ -1317,17 +1331,23 @@ static int enable_restore_fp_context(int msa) ...@@ -1317,17 +1331,23 @@ static int enable_restore_fp_context(int msa)
return 0; 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) asmlinkage void do_cpu(struct pt_regs *regs)
{ {
enum ctx_state prev_state; enum ctx_state prev_state;
unsigned int __user *epc; unsigned int __user *epc;
unsigned long old_epc, old31; unsigned long old_epc, old31;
void __user *fault_addr;
unsigned int opcode; unsigned int opcode;
unsigned long fcr31;
unsigned int cpid; unsigned int cpid;
int status, err; int status;
int sig;
prev_state = exception_enter(); prev_state = exception_enter();
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
...@@ -1365,6 +1385,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1365,6 +1385,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
break; break;
#ifdef CONFIG_MIPS_FP_SUPPORT
case 3: case 3:
/* /*
* The COP3 opcode space and consequently the CP0.Status.CU3 * The COP3 opcode space and consequently the CP0.Status.CU3
...@@ -1384,7 +1405,11 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1384,7 +1405,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
} }
/* Fall through. */ /* Fall through. */
case 1: case 1: {
void __user *fault_addr;
unsigned long fcr31;
int err, sig;
err = enable_restore_fp_context(0); err = enable_restore_fp_context(0);
if (raw_cpu_has_fpu && !err) if (raw_cpu_has_fpu && !err)
...@@ -1405,6 +1430,13 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1405,6 +1430,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
mt_ase_fp_affinity(); mt_ase_fp_affinity();
break; break;
}
#else /* CONFIG_MIPS_FP_SUPPORT */
case 1:
case 3:
force_sig(SIGILL, current);
break;
#endif /* CONFIG_MIPS_FP_SUPPORT */
case 2: case 2:
raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment