aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2014-07-11 11:44:35 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-08-01 18:06:44 -0400
commit762a1f4388a22690cd4f848ba858e5f02d4bfc22 (patch)
tree899750a406e47a67945d1525be4bd2e7a6f6a5aa /arch/mips/kernel
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/kernel')
-rw-r--r--arch/mips/kernel/traps.c14
1 files changed, 11 insertions, 3 deletions
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)
1093 1093
1094 if (!used_math()) { 1094 if (!used_math()) {
1095 /* First time FP context user. */ 1095 /* First time FP context user. */
1096 preempt_disable();
1096 err = init_fpu(); 1097 err = init_fpu();
1097 if (msa && !err) { 1098 if (msa && !err) {
1098 enable_msa(); 1099 enable_msa();
@@ -1100,6 +1101,7 @@ static int enable_restore_fp_context(int msa)
1100 set_thread_flag(TIF_USEDMSA); 1101 set_thread_flag(TIF_USEDMSA);
1101 set_thread_flag(TIF_MSA_CTX_LIVE); 1102 set_thread_flag(TIF_MSA_CTX_LIVE);
1102 } 1103 }
1104 preempt_enable();
1103 if (!err) 1105 if (!err)
1104 set_used_math(); 1106 set_used_math();
1105 return err; 1107 return err;
@@ -1139,10 +1141,11 @@ static int enable_restore_fp_context(int msa)
1139 * This task is using or has previously used MSA. Thus we require 1141 * This task is using or has previously used MSA. Thus we require
1140 * that Status.FR == 1. 1142 * that Status.FR == 1.
1141 */ 1143 */
1144 preempt_disable();
1142 was_fpu_owner = is_fpu_owner(); 1145 was_fpu_owner = is_fpu_owner();
1143 err = own_fpu(0); 1146 err = own_fpu_inatomic(0);
1144 if (err) 1147 if (err)
1145 return err; 1148 goto out;
1146 1149
1147 enable_msa(); 1150 enable_msa();
1148 write_msa_csr(current->thread.fpu.msacsr); 1151 write_msa_csr(current->thread.fpu.msacsr);
@@ -1158,7 +1161,8 @@ static int enable_restore_fp_context(int msa)
1158 prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE); 1161 prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE);
1159 if (!prior_msa && was_fpu_owner) { 1162 if (!prior_msa && was_fpu_owner) {
1160 _init_msa_upper(); 1163 _init_msa_upper();
1161 return 0; 1164
1165 goto out;
1162 } 1166 }
1163 1167
1164 if (!prior_msa) { 1168 if (!prior_msa) {
@@ -1182,6 +1186,10 @@ static int enable_restore_fp_context(int msa)
1182 if (!was_fpu_owner) 1186 if (!was_fpu_owner)
1183 asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31)); 1187 asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31));
1184 } 1188 }
1189
1190out:
1191 preempt_enable();
1192
1185 return 0; 1193 return 0;
1186} 1194}
1187 1195