#include <linux/kprobes.h>
#include <linux/preempt.h>
+#include <linux/uaccess.h>
#include <linux/kdebug.h>
#include <linux/slab.h>
union mips_instruction prev_insn;
int ret = 0;
- prev_insn = p->addr[-1];
insn = p->addr[0];
- if (insn_has_delayslot(insn) || insn_has_delayslot(prev_insn)) {
- pr_notice("Kprobes for branch and jump instructions are not supported\n");
+ if (insn_has_delayslot(insn)) {
+ pr_notice("Kprobes for branch and jump instructions are not"
+ "supported\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if ((probe_kernel_read(&prev_insn, p->addr - 1,
+ sizeof(mips_instruction)) == 0) &&
+ insn_has_delayslot(prev_insn)) {
+ pr_notice("Kprobes for branch delayslot are not supported\n");
ret = -EINVAL;
goto out;
}