Merge tag 'gcc-plugins-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / arch / mips / kernel / kprobes.c
index 212f46f..f5c8bce 100644 (file)
@@ -32,7 +32,8 @@
 #include <asm/ptrace.h>
 #include <asm/branch.h>
 #include <asm/break.h>
-#include <asm/inst.h>
+
+#include "probes-common.h"
 
 static const union mips_instruction breakpoint_insn = {
        .b_format = {
@@ -55,63 +56,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 static int __kprobes insn_has_delayslot(union mips_instruction insn)
 {
-       switch (insn.i_format.opcode) {
-
-               /*
-                * This group contains:
-                * jr and jalr are in r_format format.
-                */
-       case spec_op:
-               switch (insn.r_format.func) {
-               case jr_op:
-               case jalr_op:
-                       break;
-               default:
-                       goto insn_ok;
-               }
-
-               /*
-                * This group contains:
-                * bltz_op, bgez_op, bltzl_op, bgezl_op,
-                * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
-                */
-       case bcond_op:
-
-               /*
-                * These are unconditional and in j_format.
-                */
-       case jal_op:
-       case j_op:
-
-               /*
-                * These are conditional and in i_format.
-                */
-       case beq_op:
-       case beql_op:
-       case bne_op:
-       case bnel_op:
-       case blez_op:
-       case blezl_op:
-       case bgtz_op:
-       case bgtzl_op:
-
-               /*
-                * These are the FPA/cp1 branch instructions.
-                */
-       case cop1_op:
-
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-       case lwc2_op: /* This is bbit0 on Octeon */
-       case ldc2_op: /* This is bbit032 on Octeon */
-       case swc2_op: /* This is bbit1 on Octeon */
-       case sdc2_op: /* This is bbit132 on Octeon */
-#endif
-               return 1;
-       default:
-               break;
-       }
-insn_ok:
-       return 0;
+       return __insn_has_delay_slot(insn);
 }
 
 /*
@@ -161,6 +106,12 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
                goto out;
        }
 
+       if (__insn_is_compact_branch(insn)) {
+               pr_notice("Kprobes for compact branches are not supported\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
        /* insn: must be on special executable page on mips. */
        p->ainsn.insn = get_insn_slot();
        if (!p->ainsn.insn) {