diff options
author | Maneesh Soni <manesoni@cisco.com> | 2011-11-08 06:35:35 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-12-07 17:04:03 -0500 |
commit | 9233c1ee71bdd3c8a918c8e17026cf3f7d99c90b (patch) | |
tree | 9c653068e63cda169569796ce721af418670db5d /arch/mips/kernel/kprobes.c | |
parent | 41dde781f50c39cddc8032fc04d6a7d538237737 (diff) |
MIPS Kprobes: Deny probes on ll/sc instructions
As ll/sc instruction are for atomic read-modify-write operations, allowing
probes on top of these insturctions is a bad idea.
Signed-off-by: Victor Kamensky <kamensky@cisco.com>
Signed-off-by: Maneesh Soni <manesoni@cisco.com>
Cc: David Daney <david.daney@cavium.com>
Cc: ananth@in.ibm.com
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/2912/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/kprobes.c')
-rw-r--r-- | arch/mips/kernel/kprobes.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index 9fb1876cb0bd..0ab1a5ff1049 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c | |||
@@ -113,6 +113,30 @@ insn_ok: | |||
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | 115 | ||
116 | /* | ||
117 | * insn_has_ll_or_sc function checks whether instruction is ll or sc | ||
118 | * one; putting breakpoint on top of atomic ll/sc pair is bad idea; | ||
119 | * so we need to prevent it and refuse kprobes insertion for such | ||
120 | * instructions; cannot do much about breakpoint in the middle of | ||
121 | * ll/sc pair; it is upto user to avoid those places | ||
122 | */ | ||
123 | static int __kprobes insn_has_ll_or_sc(union mips_instruction insn) | ||
124 | { | ||
125 | int ret = 0; | ||
126 | |||
127 | switch (insn.i_format.opcode) { | ||
128 | case ll_op: | ||
129 | case lld_op: | ||
130 | case sc_op: | ||
131 | case scd_op: | ||
132 | ret = 1; | ||
133 | break; | ||
134 | default: | ||
135 | break; | ||
136 | } | ||
137 | return ret; | ||
138 | } | ||
139 | |||
116 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | 140 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
117 | { | 141 | { |
118 | union mips_instruction insn; | 142 | union mips_instruction insn; |
@@ -121,6 +145,13 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
121 | 145 | ||
122 | insn = p->addr[0]; | 146 | insn = p->addr[0]; |
123 | 147 | ||
148 | if (insn_has_ll_or_sc(insn)) { | ||
149 | pr_notice("Kprobes for ll and sc instructions are not" | ||
150 | "supported\n"); | ||
151 | ret = -EINVAL; | ||
152 | goto out; | ||
153 | } | ||
154 | |||
124 | if (insn_has_delayslot(insn)) { | 155 | if (insn_has_delayslot(insn)) { |
125 | pr_notice("Kprobes for branch and jump instructions are not" | 156 | pr_notice("Kprobes for branch and jump instructions are not" |
126 | "supported\n"); | 157 | "supported\n"); |