aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-04-08 10:32:53 -0400
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-04-28 23:40:56 -0400
commitec58d7f2373cec47f30b773d40a89f18bf6fc489 (patch)
tree3c196788348435ea7ac6c1dfda58d9789d5c6e83 /arch
parentba48d40713ae5afe758dd5525a0f8740cce71d22 (diff)
ARM: kprobes: Reject probing of STREX and LDREX instructions
The emulation code for STREX and LDREX instructions is faulty, however, rather than attempting to fix this we reject probes of these instructions. We do this because they can never succeed in gaining exclusive access as the exception framework clears the exclusivity monitor when a probes breakpoint is hit. (This is a general problem when probing all instructions executing between a LDREX and its corresponding STREX and can lead to infinite retry loops.) Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/kprobes-decode.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 8f3f03e46ace..c24e21ec427f 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -1136,17 +1136,34 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1136 1136
1137 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */ 1137 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
1138 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */ 1138 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
1139 /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ 1139 /* ??? : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */
1140 /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ 1140 /* ??? : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */
1141 /* ??? : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */
1141 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ 1142 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
1142 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ 1143 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
1144 /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */
1145 /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */
1146 /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */
1147 /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */
1148 /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */
1149 /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */
1150
1151 /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
1152 /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
1143 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */ 1153 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
1144 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */ 1154 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
1145 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */ 1155 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
1146 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */ 1156 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
1147 if ((insn & 0x0fb000f0) == 0x01000090) { 1157 if ((insn & 0x0f0000f0) == 0x01000090) {
1148 /* SWP/SWPB */ 1158 if ((insn & 0x0fb000f0) == 0x01000090) {
1149 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1159 /* SWP/SWPB */
1160 return prep_emulate_rd12rn16rm0_wflags(insn,
1161 asi);
1162 } else {
1163 /* STREX/LDREX variants and unallocaed space */
1164 return INSN_REJECTED;
1165 }
1166
1150 } else if ((insn & 0x0e1000d0) == 0x00000d0) { 1167 } else if ((insn & 0x0e1000d0) == 0x00000d0) {
1151 /* STRD/LDRD */ 1168 /* STRD/LDRD */
1152 insn &= 0xfff00fff; 1169 insn &= 0xfff00fff;