Re: preempt safe fpu-emulator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>>>> 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,
 			&current->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,
 						&current->thread.fpu.soft);
@@ -719,8 +736,6 @@
 				force_sig(sig, current);
 		}
 
-		preempt_enable();
-
 		return;
 
 	case 2:


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux