summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2014-07-11 16:44:35 +0100
committerRalf Baechle <ralf@linux-mips.org>2014-08-02 00:06:44 +0200
commit762a1f4388a22690cd4f848ba858e5f02d4bfc22 (patch)
tree899750a406e47a67945d1525be4bd2e7a6f6a5aa /arch/mips
parent3587ea888b8ed0a3d7e792738b4db687d9e7f73b (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.h4
-rw-r--r--arch/mips/kernel/traps.c14
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;
}