diff options
author | Paul Burton <paul.burton@imgtec.com> | 2014-07-11 16:44:35 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-08-02 00:06:44 +0200 |
commit | 762a1f4388a22690cd4f848ba858e5f02d4bfc22 (patch) | |
tree | 899750a406e47a67945d1525be4bd2e7a6f6a5aa /arch/mips | |
parent | 3587ea888b8ed0a3d7e792738b4db687d9e7f73b (diff) |
MIPS: disable preemption whilst initialising MSA
Preemption must be disabled throughout the process of enabling the FPU,
enabling MSA & initialising the vector registers. Without doing so it
is possible to lose the FPU or MSA whilst initialising them causing
that initialisation to fail.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7307/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/fpu.h | 4 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 14 |
2 files changed, 11 insertions, 7 deletions
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index 71d97ebd9090..4d0aeda68397 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -164,8 +164,6 @@ static inline int init_fpu(void) { int ret = 0; - preempt_disable(); - if (cpu_has_fpu) { ret = __own_fpu(); if (!ret) @@ -173,8 +171,6 @@ static inline int init_fpu(void) } else fpu_emulator_init_fpu(); - preempt_enable(); - return ret; } diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 4716b89543a9..22b19c275044 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1093,6 +1093,7 @@ static int enable_restore_fp_context(int msa) if (!used_math()) { /* First time FP context user. */ + preempt_disable(); err = init_fpu(); if (msa && !err) { enable_msa(); @@ -1100,6 +1101,7 @@ static int enable_restore_fp_context(int msa) set_thread_flag(TIF_USEDMSA); set_thread_flag(TIF_MSA_CTX_LIVE); } + preempt_enable(); if (!err) set_used_math(); return err; @@ -1139,10 +1141,11 @@ static int enable_restore_fp_context(int msa) * This task is using or has previously used MSA. Thus we require * that Status.FR == 1. */ + preempt_disable(); was_fpu_owner = is_fpu_owner(); - err = own_fpu(0); + err = own_fpu_inatomic(0); if (err) - return err; + goto out; enable_msa(); write_msa_csr(current->thread.fpu.msacsr); @@ -1158,7 +1161,8 @@ static int enable_restore_fp_context(int msa) prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE); if (!prior_msa && was_fpu_owner) { _init_msa_upper(); - return 0; + + goto out; } if (!prior_msa) { @@ -1182,6 +1186,10 @@ static int enable_restore_fp_context(int msa) if (!was_fpu_owner) asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31)); } + +out: + preempt_enable(); + return 0; } |