>>>>> On Wed, 27 Apr 2005 14:36:22 +0900 (JST), Atsushi Nemoto <anemo@xxxxxxxxxxxxx> said: anemo> With this patch, whole fpu-emulator can be run without anemo> disabling preempt. I will post a patch to fix preemption issue anemo> soon. Here it is. It also fixes these issues: * The process might lose fpu BEFORE calling preempt_disable() in do_fpe(). * The saved fp context might be overwritten if another process took fpu. --- linux-mips/arch/mips/kernel/traps.c 2005-04-18 11:42:47.000000000 +0900 +++ linux/arch/mips/kernel/traps.c 2005-04-27 14:04:53.407006244 +0900 @@ -551,6 +551,14 @@ preempt_disable(); +#ifdef CONFIG_PREEMPT + if (!is_fpu_owner()) { + /* We might lose fpu before disabling preempt... */ + own_fpu(); + BUG_ON(!used_math()); + restore_fp(current); + } +#endif /* * Unimplemented operation exception. If we've got the full * software emulator on-board, let's use it... @@ -562,11 +570,18 @@ * a bit extreme for what should be an infrequent event. */ save_fp(current); + /* Ensure 'resume' not overwrite saved fp context again. */ + lose_fpu(); + + preempt_enable(); /* Run the emulator */ sig = fpu_emulator_cop1Handler (0, regs, ¤t->thread.fpu.soft); + preempt_disable(); + + own_fpu(); /* Using the FPU again. */ /* * We can't allow the emulated instruction to leave any of * the cause bit set in $fcr31. @@ -712,6 +727,8 @@ set_used_math(); } + preempt_enable(); + if (!cpu_has_fpu) { int sig = fpu_emulator_cop1Handler(0, regs, ¤t->thread.fpu.soft); @@ -719,8 +736,6 @@ force_sig(sig, current); } - preempt_enable(); - return; case 2: