mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 22:02:28 +00:00
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 <paul.burton@mips.com> Patchwork: https://patchwork.linux-mips.org/patch/21007/ Cc: linux-mips@linux-mips.org
This commit is contained in:
parent
b2e628a8f9
commit
5328f7422e
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user