Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / arch / mips / kernel / branch.c
index 76fd3f22c76624363d94b7e4b870d0e798ff282d..0176ed015c895644bc72fc30bc661c2ad555b515 100644 (file)
@@ -22,7 +22,8 @@
  */
 int __compute_return_epc(struct pt_regs *regs)
 {
-       unsigned int *addr, bit, fcr31, dspcontrol;
+       unsigned int __user *addr;
+       unsigned int bit, fcr31, dspcontrol;
        long epc;
        union mips_instruction insn;
 
@@ -33,7 +34,7 @@ int __compute_return_epc(struct pt_regs *regs)
        /*
         * Read the instruction
         */
-       addr = (unsigned int *) epc;
+       addr = (unsigned int __user *) epc;
        if (__get_user(insn.word, addr)) {
                force_sig(SIGSEGV, current);
                return -EFAULT;
@@ -204,6 +205,39 @@ int __compute_return_epc(struct pt_regs *regs)
                        break;
                }
                break;
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+       case lwc2_op: /* This is bbit0 on Octeon */
+               if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
+                    == 0)
+                       epc = epc + 4 + (insn.i_format.simmediate << 2);
+               else
+                       epc += 8;
+               regs->cp0_epc = epc;
+               break;
+       case ldc2_op: /* This is bbit032 on Octeon */
+               if ((regs->regs[insn.i_format.rs] &
+                   (1ull<<(insn.i_format.rt+32))) == 0)
+                       epc = epc + 4 + (insn.i_format.simmediate << 2);
+               else
+                       epc += 8;
+               regs->cp0_epc = epc;
+               break;
+       case swc2_op: /* This is bbit1 on Octeon */
+               if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
+                       epc = epc + 4 + (insn.i_format.simmediate << 2);
+               else
+                       epc += 8;
+               regs->cp0_epc = epc;
+               break;
+       case sdc2_op: /* This is bbit132 on Octeon */
+               if (regs->regs[insn.i_format.rs] &
+                   (1ull<<(insn.i_format.rt+32)))
+                       epc = epc + 4 + (insn.i_format.simmediate << 2);
+               else
+                       epc += 8;
+               regs->cp0_epc = epc;
+               break;
+#endif
        }
 
        return 0;