aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorManeesh Soni <manesoni@cisco.com>2011-11-08 06:35:35 -0500
committerRalf Baechle <ralf@linux-mips.org>2011-12-07 17:04:03 -0500
commit9233c1ee71bdd3c8a918c8e17026cf3f7d99c90b (patch)
tree9c653068e63cda169569796ce721af418670db5d /arch/mips/kernel
parent41dde781f50c39cddc8032fc04d6a7d538237737 (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')
-rw-r--r--arch/mips/kernel/kprobes.c31
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 */
123static 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
116int __kprobes arch_prepare_kprobe(struct kprobe *p) 140int __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");