aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/kprobes-arm.c116
1 files changed, 50 insertions, 66 deletions
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index ef350a5cd9b0..f2eed03f5522 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1203,72 +1203,56 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1203 return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false); 1203 return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false);
1204} 1204}
1205 1205
1206static enum kprobe_insn __kprobes 1206static const union decode_item arm_cccc_001x_table[] = {
1207space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1207 /* Data-processing (immediate) */
1208{ 1208
1209 /* MOVW : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ 1209 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
1210 /* MOVT : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ 1210 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
1211 if ((insn & 0x0fb00000) == 0x03000000) 1211 DECODE_CUSTOM (0x0fb00000, 0x03000000, prep_emulate_rd12_modify),
1212 return prep_emulate_rd12_modify(insn, asi); 1212
1213 1213 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
1214 /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ 1214 DECODE_OR (0x0fff00ff, 0x03200001),
1215 if ((insn & 0x0fff0000) == 0x03200000) { 1215 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
1216 unsigned op2 = insn & 0x000000ff; 1216 DECODE_EMULATE (0x0fff00ff, 0x03200004, kprobe_emulate_none),
1217 if (op2 == 0x01 || op2 == 0x04) { 1217 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
1218 /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ 1218 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
1219 /* SEV : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ 1219 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
1220 asi->insn[0] = insn; 1220 DECODE_SIMULATE (0x0fff00fc, 0x03200000, kprobe_simulate_nop),
1221 asi->insn_handler = emulate_none; 1221 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
1222 return INSN_GOOD; 1222 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
1223 } else if (op2 <= 0x03) { 1223 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
1224 /* NOP : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ 1224 DECODE_REJECT (0x0fb00000, 0x03200000),
1225 /* WFE : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ 1225
1226 /* WFI : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ 1226 /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
1227 /* 1227 DECODE_REJECT (0x0e10f000, 0x0210f000),
1228 * We make WFE and WFI true NOPs to avoid stalls due 1228
1229 * to missing events whilst processing the probe. 1229 /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
1230 */ 1230 /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
1231 asi->insn_handler = emulate_nop; 1231 /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
1232 return INSN_GOOD_NO_SLOT; 1232 /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
1233 } 1233 DECODE_EMULATEX (0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags,
1234 /* For DBG and unallocated hints it's safest to reject them */ 1234 REGS(ANY, 0, 0, 0, 0)),
1235 return INSN_REJECTED; 1235
1236 } 1236 /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
1237 /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
1238 DECODE_EMULATEX (0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags,
1239 REGS(0, ANY, 0, 0, 0)),
1240
1241 /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
1242 /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
1243 /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
1244 /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
1245 /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
1246 /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
1247 /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
1248 /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
1249 /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
1250 /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
1251 DECODE_EMULATEX (0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags,
1252 REGS(ANY, ANY, 0, 0, 0)),
1237 1253
1238 /* 1254 DECODE_END
1239 * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx 1255};
1240 * ALU op with S bit and Rd == 15 :
1241 * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
1242 */
1243 if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */
1244 (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */
1245 return INSN_REJECTED;
1246
1247 /*
1248 * Data processing: 32-bit Immediate
1249 * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
1250 * MOV : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx
1251 * *S (bit 20) updates condition codes
1252 * ADC/SBC/RSC reads the C flag
1253 */
1254 insn &= 0xfff00fff; /* Rn = r0 and Rd = r0 */
1255 asi->insn[0] = insn;
1256
1257 if ((insn & 0x0f900000) == 0x03100000) {
1258 /*
1259 * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
1260 * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
1261 * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
1262 * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
1263 */
1264 asi->insn_handler = emulate_alu_tests_imm;
1265 } else {
1266 /* ALU ops which write to Rd */
1267 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
1268 emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
1269 }
1270 return INSN_GOOD;
1271}
1272 1256
1273static enum kprobe_insn __kprobes 1257static enum kprobe_insn __kprobes
1274space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1258space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
@@ -1548,7 +1532,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1548 1532
1549 else if ((insn & 0x0e000000) == 0x02000000) 1533 else if ((insn & 0x0e000000) == 0x02000000)
1550 1534
1551 return space_cccc_001x(insn, asi); 1535 return kprobe_decode_insn(insn, asi, arm_cccc_001x_table, false);
1552 1536
1553 else if ((insn & 0x0f000010) == 0x06000010) 1537 else if ((insn & 0x0f000010) == 0x06000010)
1554 1538