diff options
author | Paul Burton <paul.burton@imgtec.com> | 2014-07-11 11:44:35 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-08-01 18:06:44 -0400 |
commit | 762a1f4388a22690cd4f848ba858e5f02d4bfc22 (patch) | |
tree | 899750a406e47a67945d1525be4bd2e7a6f6a5aa /arch/mips/kernel | |
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/kernel')
-rw-r--r-- | arch/mips/kernel/traps.c | 14 |
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 | |||
1190 | out: | ||
1191 | preempt_enable(); | ||
1192 | |||
1185 | return 0; | 1193 | return 0; |
1186 | } | 1194 | } |
1187 | 1195 | ||