summaryrefslogtreecommitdiff
path: root/arch/mips/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/kprobes.c')
-rw-r--r--arch/mips/kernel/kprobes.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c
index ee28683..9fb1876 100644
--- a/arch/mips/kernel/kprobes.c
+++ b/arch/mips/kernel/kprobes.c
@@ -25,6 +25,7 @@
#include <linux/kprobes.h>
#include <linux/preempt.h>
+#include <linux/uaccess.h>
#include <linux/kdebug.h>
#include <linux/slab.h>
@@ -118,11 +119,19 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
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;
}