aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal32.c
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2007-03-09 11:07:45 -0500
committerRalf Baechle <ralf@linux-mips.org>2007-03-16 21:03:26 -0400
commit53dc80287da43b75df2fe2658651d3c5160dad8e (patch)
tree3c4c97534c379709cd2a1dae5b90df626349f21d /arch/mips/kernel/signal32.c
parentc6a2f4679331206ef5d353fc9a6cda2fa4aef8c6 (diff)
[MIPS] FPU ownership management & preemption fixes
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/signal32.c')
-rw-r--r--arch/mips/kernel/signal32.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 20013b6fe725..151fd2f0893a 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -181,6 +181,7 @@ static int setup_sigcontext32(struct pt_regs *regs,
181{ 181{
182 int err = 0; 182 int err = 0;
183 int i; 183 int i;
184 u32 used_math;
184 185
185 err |= __put_user(regs->cp0_epc, &sc->sc_pc); 186 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
186 187
@@ -200,22 +201,18 @@ static int setup_sigcontext32(struct pt_regs *regs,
200 err |= __put_user(mflo3(), &sc->sc_lo3); 201 err |= __put_user(mflo3(), &sc->sc_lo3);
201 } 202 }
202 203
203 err |= __put_user(!!used_math(), &sc->sc_used_math); 204 used_math = !!used_math();
205 err |= __put_user(used_math, &sc->sc_used_math);
204 206
205 if (used_math()) { 207 if (used_math) {
206 /* 208 /*
207 * Save FPU state to signal context. Signal handler 209 * Save FPU state to signal context. Signal handler
208 * will "inherit" current FPU state. 210 * will "inherit" current FPU state.
209 */ 211 */
210 preempt_disable(); 212 own_fpu(1);
211 213 enable_fp_in_kernel();
212 if (!is_fpu_owner()) {
213 own_fpu();
214 restore_fp(current);
215 }
216 err |= save_fp_context32(sc); 214 err |= save_fp_context32(sc);
217 215 disable_fp_in_kernel();
218 preempt_enable();
219 } 216 }
220 return err; 217 return err;
221} 218}
@@ -262,20 +259,18 @@ static int restore_sigcontext32(struct pt_regs *regs,
262 err |= __get_user(used_math, &sc->sc_used_math); 259 err |= __get_user(used_math, &sc->sc_used_math);
263 conditional_used_math(used_math); 260 conditional_used_math(used_math);
264 261
265 preempt_disable(); 262 if (used_math) {
266
267 if (used_math()) {
268 /* restore fpu context if we have used it before */ 263 /* restore fpu context if we have used it before */
269 own_fpu(); 264 own_fpu(0);
265 enable_fp_in_kernel();
270 if (!err) 266 if (!err)
271 err = check_and_restore_fp_context32(sc); 267 err = check_and_restore_fp_context32(sc);
268 disable_fp_in_kernel();
272 } else { 269 } else {
273 /* signal handler may have used FPU. Give it up. */ 270 /* signal handler may have used FPU. Give it up. */
274 lose_fpu(); 271 lose_fpu(0);
275 } 272 }
276 273
277 preempt_enable();
278
279 return err; 274 return err;
280} 275}
281 276