MIPS: microMIPS: Floating point support.
[deliverable/linux.git] / arch / mips / kernel / unaligned.c
index 6087a54c86a0dbc5e6e9a167659df9408a1dc3e1..f4c94ff3e3d3c484d121f70c8b2efbd52b020c81 100644 (file)
@@ -83,6 +83,8 @@
 #include <asm/branch.h>
 #include <asm/byteorder.h>
 #include <asm/cop2.h>
+#include <asm/fpu.h>
+#include <asm/fpu_emulator.h>
 #include <asm/inst.h>
 #include <asm/uaccess.h>
 
@@ -108,6 +110,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
        union mips_instruction insn;
        unsigned long value;
        unsigned int res;
+       void __user *fault_addr = NULL;
 
        perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
 
@@ -447,10 +450,21 @@ static void emulate_load_store_insn(struct pt_regs *regs,
        case ldc1_op:
        case swc1_op:
        case sdc1_op:
-               /*
-                * I herewith declare: this does not happen.  So send SIGBUS.
-                */
-               goto sigbus;
+               die_if_kernel("Unaligned FP access in kernel code", regs);
+               BUG_ON(!used_math());
+               BUG_ON(!is_fpu_owner());
+
+               lose_fpu(1);    /* Save FPU state for the emulator. */
+               res = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
+                                              &fault_addr);
+               own_fpu(1);     /* Restore FPU state. */
+
+               /* Signal if something went wrong. */
+               process_fpemu_return(res, fault_addr);
+
+               if (res == 0)
+                       break;
+               return;
 
        /*
         * COP2 is available to implementor for application specific use.
This page took 0.039192 seconds and 5 git commands to generate.