0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _ARM_KERNEL_PROBES_H
0012 #define _ARM_KERNEL_PROBES_H
0013
0014 #include <linux/types.h>
0015 #include <linux/stddef.h>
0016 #include <asm/probes.h>
0017 #include <asm/ptrace.h>
0018 #include <asm/kprobes.h>
0019
0020 void __init arm_probes_decode_init(void);
0021
0022 extern probes_check_cc * const probes_condition_checks[16];
0023
0024 #if __LINUX_ARM_ARCH__ >= 7
0025
0026
0027 #define str_pc_offset 8
0028 #define find_str_pc_offset()
0029
0030 #else
0031
0032
0033 extern int str_pc_offset;
0034 void __init find_str_pc_offset(void);
0035
0036 #endif
0037
0038
0039 static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
0040 {
0041 long cpsr = regs->ARM_cpsr;
0042 if (pcv & 0x1) {
0043 cpsr |= PSR_T_BIT;
0044 pcv &= ~0x1;
0045 } else {
0046 cpsr &= ~PSR_T_BIT;
0047 pcv &= ~0x2;
0048 }
0049 regs->ARM_cpsr = cpsr;
0050 regs->ARM_pc = pcv;
0051 }
0052
0053
0054 #if __LINUX_ARM_ARCH__ >= 6
0055
0056
0057 #define load_write_pc_interworks true
0058 #define test_load_write_pc_interworking()
0059
0060 #else
0061
0062
0063 extern bool load_write_pc_interworks;
0064 void __init test_load_write_pc_interworking(void);
0065
0066 #endif
0067
0068 static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
0069 {
0070 if (load_write_pc_interworks)
0071 bx_write_pc(pcv, regs);
0072 else
0073 regs->ARM_pc = pcv;
0074 }
0075
0076
0077 #if __LINUX_ARM_ARCH__ >= 7
0078
0079 #define alu_write_pc_interworks true
0080 #define test_alu_write_pc_interworking()
0081
0082 #elif __LINUX_ARM_ARCH__ <= 5
0083
0084
0085 #define alu_write_pc_interworks false
0086 #define test_alu_write_pc_interworking()
0087
0088 #else
0089
0090
0091 extern bool alu_write_pc_interworks;
0092 void __init test_alu_write_pc_interworking(void);
0093
0094 #endif
0095
0096 static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
0097 {
0098 if (alu_write_pc_interworks)
0099 bx_write_pc(pcv, regs);
0100 else
0101 regs->ARM_pc = pcv;
0102 }
0103
0104
0105
0106
0107
0108
0109 #define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 enum decode_type {
0228 DECODE_TYPE_END,
0229 DECODE_TYPE_TABLE,
0230 DECODE_TYPE_CUSTOM,
0231 DECODE_TYPE_SIMULATE,
0232 DECODE_TYPE_EMULATE,
0233 DECODE_TYPE_OR,
0234 DECODE_TYPE_REJECT,
0235 NUM_DECODE_TYPES
0236 };
0237
0238 #define DECODE_TYPE_BITS 4
0239 #define DECODE_TYPE_MASK ((1 << DECODE_TYPE_BITS) - 1)
0240
0241 enum decode_reg_type {
0242 REG_TYPE_NONE = 0,
0243 REG_TYPE_ANY,
0244 REG_TYPE_SAMEAS16,
0245 REG_TYPE_SP,
0246 REG_TYPE_PC,
0247 REG_TYPE_NOSP,
0248 REG_TYPE_NOSPPC,
0249 REG_TYPE_NOPC,
0250 REG_TYPE_NOPCWB,
0251
0252
0253
0254
0255
0256 REG_TYPE_NOPCX,
0257 REG_TYPE_NOSPPCX,
0258
0259
0260 REG_TYPE_0 = REG_TYPE_NONE
0261 };
0262
0263 #define REGS(r16, r12, r8, r4, r0) \
0264 (((REG_TYPE_##r16) << 16) + \
0265 ((REG_TYPE_##r12) << 12) + \
0266 ((REG_TYPE_##r8) << 8) + \
0267 ((REG_TYPE_##r4) << 4) + \
0268 (REG_TYPE_##r0))
0269
0270 union decode_item {
0271 u32 bits;
0272 const union decode_item *table;
0273 int action;
0274 };
0275
0276 struct decode_header;
0277 typedef enum probes_insn (probes_custom_decode_t)(probes_opcode_t,
0278 struct arch_probes_insn *,
0279 const struct decode_header *);
0280
0281 union decode_action {
0282 probes_insn_handler_t *handler;
0283 probes_custom_decode_t *decoder;
0284 };
0285
0286 typedef enum probes_insn (probes_check_t)(probes_opcode_t,
0287 struct arch_probes_insn *,
0288 const struct decode_header *);
0289
0290 struct decode_checker {
0291 probes_check_t *checker;
0292 };
0293
0294 #define DECODE_END \
0295 {.bits = DECODE_TYPE_END}
0296
0297
0298 struct decode_header {
0299 union decode_item type_regs;
0300 union decode_item mask;
0301 union decode_item value;
0302 };
0303
0304 #define DECODE_HEADER(_type, _mask, _value, _regs) \
0305 {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)}, \
0306 {.bits = (_mask)}, \
0307 {.bits = (_value)}
0308
0309
0310 struct decode_table {
0311 struct decode_header header;
0312 union decode_item table;
0313 };
0314
0315 #define DECODE_TABLE(_mask, _value, _table) \
0316 DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0), \
0317 {.table = (_table)}
0318
0319
0320 struct decode_custom {
0321 struct decode_header header;
0322 union decode_item decoder;
0323 };
0324
0325 #define DECODE_CUSTOM(_mask, _value, _decoder) \
0326 DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \
0327 {.action = (_decoder)}
0328
0329
0330 struct decode_simulate {
0331 struct decode_header header;
0332 union decode_item handler;
0333 };
0334
0335 #define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \
0336 DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \
0337 {.action = (_handler)}
0338
0339 #define DECODE_SIMULATE(_mask, _value, _handler) \
0340 DECODE_SIMULATEX(_mask, _value, _handler, 0)
0341
0342
0343 struct decode_emulate {
0344 struct decode_header header;
0345 union decode_item handler;
0346 };
0347
0348 #define DECODE_EMULATEX(_mask, _value, _handler, _regs) \
0349 DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \
0350 {.action = (_handler)}
0351
0352 #define DECODE_EMULATE(_mask, _value, _handler) \
0353 DECODE_EMULATEX(_mask, _value, _handler, 0)
0354
0355
0356 struct decode_or {
0357 struct decode_header header;
0358 };
0359
0360 #define DECODE_OR(_mask, _value) \
0361 DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0)
0362
0363 enum probes_insn {
0364 INSN_REJECTED,
0365 INSN_GOOD,
0366 INSN_GOOD_NO_SLOT
0367 };
0368
0369 struct decode_reject {
0370 struct decode_header header;
0371 };
0372
0373 #define DECODE_REJECT(_mask, _value) \
0374 DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0)
0375
0376 probes_insn_handler_t probes_simulate_nop;
0377 probes_insn_handler_t probes_emulate_none;
0378
0379 int __kprobes
0380 probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
0381 const union decode_item *table, bool thumb, bool emulate,
0382 const union decode_action *actions,
0383 const struct decode_checker **checkers);
0384
0385 #endif