linux-mips
[Top] [All Lists]

[PATCH] do_fpe() cleanup

To: linux-mips@linux-mips.org
Subject: [PATCH] do_fpe() cleanup
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Sat, 10 Mar 2007 01:07:45 +0900 (JST)
Cc: ralf@linux-mips.org
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
If we had already lost FPU before disabling preempt, we do not have to
own it at all.  And we do not prevent preemption when managing saved
FCR31 if we did not have FPU ownership.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
---
This is an update of:
http://www.linux-mips.org/archives/linux-mips/2007-02/msg00086.html

 arch/mips/kernel/traps.c |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index d5833a4..2aaf76b 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -610,16 +610,6 @@ asmlinkage void do_fpe(struct pt_regs *r
        if (fcr31 & FPU_CSR_UNI_X) {
                int sig;
 
-               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...
@@ -630,7 +620,11 @@ asmlinkage void do_fpe(struct pt_regs *r
                 * register operands before invoking the emulator, which seems
                 * a bit extreme for what should be an infrequent event.
                 */
-               save_fp(current);
+               preempt_disable();
+
+               /* We might have lost fpu before disabling preempt... */
+               if (is_fpu_owner())
+                       save_fp(current);
                /* Ensure 'resume' not overwrite saved fp context again. */
                lose_fpu();
 
@@ -639,15 +633,15 @@ asmlinkage void do_fpe(struct pt_regs *r
                /* Run the emulator */
                sig = fpu_emulator_cop1Handler (regs, &current->thread.fpu, 1);
 
-               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.
                 */
                current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
 
+               preempt_disable();
+
+               own_fpu();      /* Using the FPU again.  */
                /* Restore the hardware register state */
                restore_fp(current);
 

<Prev in Thread] Current Thread [Next in Thread>