linux-mips
[Top] [All Lists]

CFC1 instruction in compute_return_epc

To: linux-mips@linux-mips.org
Subject: CFC1 instruction in compute_return_epc
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Wed, 20 Apr 2005 16:53:20 +0900 (JST)
Cc: ralf@linux-mips.org
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
The __compute_return_epc() uses CFC1 instruction but it might cause a
coprocessor unusable exception since the process can lose its fpu
context by preemption.  The coprocessor unusable exception is not
allowed in kernel context.

Here is a patch.  Please review.  Thank you.

--- linux-mips/arch/mips/kernel/branch.c        2004-08-14 19:55:32.000000000 
+0900
+++ linux/arch/mips/kernel/branch.c     2005-04-20 16:33:24.662914765 +0900
@@ -12,6 +12,7 @@
 #include <asm/branch.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
+#include <asm/fpu.h>
 #include <asm/inst.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
@@ -163,8 +164,14 @@
        case cop1_op:
                if (!cpu_has_fpu)
                        fcr31 = current->thread.fpu.soft.fcr31;
-               else
-                       asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+               else {
+                       preempt_disable();
+                       if (is_fpu_owner())
+                               asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+                       else
+                               fcr31 = current->thread.fpu.hard.fcr31;
+                       preempt_enable();
+               }
                bit = (insn.i_format.rt >> 2);
                bit += (bit != 0);
                bit += 23;

---
Atsushi Nemoto

<Prev in Thread] Current Thread [Next in Thread>
  • CFC1 instruction in compute_return_epc, Atsushi Nemoto <=