1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <asm/system_info.h>
17#include <asm/ptrace.h>
18#include <linux/bug.h>
19
20#include "decode.h"
21
22
23#ifndef find_str_pc_offset
24
25
26
27
28
29
30
31
32int str_pc_offset;
33
34void __init find_str_pc_offset(void)
35{
36 int addr, scratch, ret;
37
38 __asm__ (
39 "sub %[ret], pc, #4 \n\t"
40 "str pc, %[addr] \n\t"
41 "ldr %[scr], %[addr] \n\t"
42 "sub %[ret], %[scr], %[ret] \n\t"
43 : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
44
45 str_pc_offset = ret;
46}
47
48#endif
49
50
51#ifndef test_load_write_pc_interworking
52
53bool load_write_pc_interworks;
54
55void __init test_load_write_pc_interworking(void)
56{
57 int arch = cpu_architecture();
58 BUG_ON(arch == CPU_ARCH_UNKNOWN);
59 load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
60}
61
62#endif
63
64
65#ifndef test_alu_write_pc_interworking
66
67bool alu_write_pc_interworks;
68
69void __init test_alu_write_pc_interworking(void)
70{
71 int arch = cpu_architecture();
72 BUG_ON(arch == CPU_ARCH_UNKNOWN);
73 alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
74}
75
76#endif
77
78
79void __init arm_probes_decode_init(void)
80{
81 find_str_pc_offset();
82 test_load_write_pc_interworking();
83 test_alu_write_pc_interworking();
84}
85
86
87static unsigned long __kprobes __check_eq(unsigned long cpsr)
88{
89 return cpsr & PSR_Z_BIT;
90}
91
92static unsigned long __kprobes __check_ne(unsigned long cpsr)
93{
94 return (~cpsr) & PSR_Z_BIT;
95}
96
97static unsigned long __kprobes __check_cs(unsigned long cpsr)
98{
99 return cpsr & PSR_C_BIT;
100}
101
102static unsigned long __kprobes __check_cc(unsigned long cpsr)
103{
104 return (~cpsr) & PSR_C_BIT;
105}
106
107static unsigned long __kprobes __check_mi(unsigned long cpsr)
108{
109 return cpsr & PSR_N_BIT;
110}
111
112static unsigned long __kprobes __check_pl(unsigned long cpsr)
113{
114 return (~cpsr) & PSR_N_BIT;
115}
116
117static unsigned long __kprobes __check_vs(unsigned long cpsr)
118{
119 return cpsr & PSR_V_BIT;
120}
121
122static unsigned long __kprobes __check_vc(unsigned long cpsr)
123{
124 return (~cpsr) & PSR_V_BIT;
125}
126
127static unsigned long __kprobes __check_hi(unsigned long cpsr)
128{
129 cpsr &= ~(cpsr >> 1);
130 return cpsr & PSR_C_BIT;
131}
132
133static unsigned long __kprobes __check_ls(unsigned long cpsr)
134{
135 cpsr &= ~(cpsr >> 1);
136 return (~cpsr) & PSR_C_BIT;
137}
138
139static unsigned long __kprobes __check_ge(unsigned long cpsr)
140{
141 cpsr ^= (cpsr << 3);
142 return (~cpsr) & PSR_N_BIT;
143}
144
145static unsigned long __kprobes __check_lt(unsigned long cpsr)
146{
147 cpsr ^= (cpsr << 3);
148 return cpsr & PSR_N_BIT;
149}
150
151static unsigned long __kprobes __check_gt(unsigned long cpsr)
152{
153 unsigned long temp = cpsr ^ (cpsr << 3);
154 temp |= (cpsr << 1);
155 return (~temp) & PSR_N_BIT;
156}
157
158static unsigned long __kprobes __check_le(unsigned long cpsr)
159{
160 unsigned long temp = cpsr ^ (cpsr << 3);
161 temp |= (cpsr << 1);
162 return temp & PSR_N_BIT;
163}
164
165static unsigned long __kprobes __check_al(unsigned long cpsr)
166{
167 return true;
168}
169
170probes_check_cc * const probes_condition_checks[16] = {
171 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
172 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
173 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
174 &__check_gt, &__check_le, &__check_al, &__check_al
175};
176
177
178void __kprobes probes_simulate_nop(probes_opcode_t opcode,
179 struct arch_probes_insn *asi,
180 struct pt_regs *regs)
181{
182}
183
184void __kprobes probes_emulate_none(probes_opcode_t opcode,
185 struct arch_probes_insn *asi,
186 struct pt_regs *regs)
187{
188 asi->insn_fn();
189}
190
191
192
193
194
195
196
197
198static probes_opcode_t __kprobes
199prepare_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
200 bool thumb)
201{
202#ifdef CONFIG_THUMB2_KERNEL
203 if (thumb) {
204 u16 *thumb_insn = (u16 *)asi->insn;
205
206 thumb_insn[1] = __opcode_to_mem_thumb16(0x4770);
207 thumb_insn[2] = __opcode_to_mem_thumb16(0x4770);
208 return insn;
209 }
210 asi->insn[1] = __opcode_to_mem_arm(0xe12fff1e);
211#else
212 asi->insn[1] = __opcode_to_mem_arm(0xe1a0f00e);
213#endif
214
215 if (insn < 0xe0000000)
216 insn = (insn | 0xe0000000) & ~0x10000000;
217 return insn;
218}
219
220
221
222
223
224static void __kprobes
225set_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
226 bool thumb)
227{
228#ifdef CONFIG_THUMB2_KERNEL
229 if (thumb) {
230 u16 *ip = (u16 *)asi->insn;
231 if (is_wide_instruction(insn))
232 *ip++ = __opcode_to_mem_thumb16(insn >> 16);
233 *ip++ = __opcode_to_mem_thumb16(insn);
234 return;
235 }
236#endif
237 asi->insn[0] = __opcode_to_mem_arm(insn);
238}
239
240
241
242
243
244
245
246
247
248
249#define INSN_NEW_BITS 0x00020103
250
251
252#define INSN_SAMEAS16_BITS 0x22222222
253
254
255
256
257
258
259
260
261static bool __kprobes decode_regs(probes_opcode_t *pinsn, u32 regs, bool modify)
262{
263 probes_opcode_t insn = *pinsn;
264 probes_opcode_t mask = 0xf;
265
266 for (; regs != 0; regs >>= 4, mask <<= 4) {
267
268 probes_opcode_t new_bits = INSN_NEW_BITS;
269
270 switch (regs & 0xf) {
271
272 case REG_TYPE_NONE:
273
274 continue;
275
276 case REG_TYPE_ANY:
277
278 break;
279
280 case REG_TYPE_SAMEAS16:
281
282 new_bits = INSN_SAMEAS16_BITS;
283 break;
284
285 case REG_TYPE_SP:
286
287 if ((insn ^ 0xdddddddd) & mask)
288 goto reject;
289 break;
290
291 case REG_TYPE_PC:
292
293 if ((insn ^ 0xffffffff) & mask)
294 goto reject;
295 break;
296
297 case REG_TYPE_NOSP:
298
299 if (((insn ^ 0xdddddddd) & mask) == 0)
300 goto reject;
301 break;
302
303 case REG_TYPE_NOSPPC:
304 case REG_TYPE_NOSPPCX:
305
306 if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
307 goto reject;
308 break;
309
310 case REG_TYPE_NOPCWB:
311 if (!is_writeback(insn))
312 break;
313
314 case REG_TYPE_NOPC:
315 case REG_TYPE_NOPCX:
316
317 if (((insn ^ 0xffffffff) & mask) == 0)
318 goto reject;
319 break;
320 }
321
322
323 insn &= ~mask;
324 insn |= new_bits & mask;
325 }
326
327 if (modify)
328 *pinsn = insn;
329
330 return true;
331
332reject:
333 return false;
334}
335
336static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
337 [DECODE_TYPE_TABLE] = sizeof(struct decode_table),
338 [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom),
339 [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate),
340 [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate),
341 [DECODE_TYPE_OR] = sizeof(struct decode_or),
342 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
343};
344
345static int run_checkers(const struct decode_checker *checkers[],
346 int action, probes_opcode_t insn,
347 struct arch_probes_insn *asi,
348 const struct decode_header *h)
349{
350 const struct decode_checker **p;
351
352 if (!checkers)
353 return INSN_GOOD;
354
355 p = checkers;
356 while (*p != NULL) {
357 int retval;
358 probes_check_t *checker_func = (*p)[action].checker;
359
360 retval = INSN_GOOD;
361 if (checker_func)
362 retval = checker_func(insn, asi, h);
363 if (retval == INSN_REJECTED)
364 return retval;
365 p++;
366 }
367 return INSN_GOOD;
368}
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413int __kprobes
414probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
415 const union decode_item *table, bool thumb,
416 bool emulate, const union decode_action *actions,
417 const struct decode_checker *checkers[])
418{
419 const struct decode_header *h = (struct decode_header *)table;
420 const struct decode_header *next;
421 bool matched = false;
422
423
424
425
426 probes_opcode_t origin_insn = insn;
427
428
429
430
431
432
433
434
435
436 asi->stack_space = 0;
437
438
439
440
441
442
443 asi->register_usage_flags = ~0UL;
444
445 if (emulate)
446 insn = prepare_emulated_insn(insn, asi, thumb);
447
448 for (;; h = next) {
449 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
450 u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
451
452 if (type == DECODE_TYPE_END)
453 return INSN_REJECTED;
454
455 next = (struct decode_header *)
456 ((uintptr_t)h + decode_struct_sizes[type]);
457
458 if (!matched && (insn & h->mask.bits) != h->value.bits)
459 continue;
460
461 if (!decode_regs(&insn, regs, emulate))
462 return INSN_REJECTED;
463
464 switch (type) {
465
466 case DECODE_TYPE_TABLE: {
467 struct decode_table *d = (struct decode_table *)h;
468 next = (struct decode_header *)d->table.table;
469 break;
470 }
471
472 case DECODE_TYPE_CUSTOM: {
473 int err;
474 struct decode_custom *d = (struct decode_custom *)h;
475 int action = d->decoder.action;
476
477 err = run_checkers(checkers, action, origin_insn, asi, h);
478 if (err == INSN_REJECTED)
479 return INSN_REJECTED;
480 return actions[action].decoder(insn, asi, h);
481 }
482
483 case DECODE_TYPE_SIMULATE: {
484 int err;
485 struct decode_simulate *d = (struct decode_simulate *)h;
486 int action = d->handler.action;
487
488 err = run_checkers(checkers, action, origin_insn, asi, h);
489 if (err == INSN_REJECTED)
490 return INSN_REJECTED;
491 asi->insn_handler = actions[action].handler;
492 return INSN_GOOD_NO_SLOT;
493 }
494
495 case DECODE_TYPE_EMULATE: {
496 int err;
497 struct decode_emulate *d = (struct decode_emulate *)h;
498 int action = d->handler.action;
499
500 err = run_checkers(checkers, action, origin_insn, asi, h);
501 if (err == INSN_REJECTED)
502 return INSN_REJECTED;
503
504 if (!emulate)
505 return actions[action].decoder(insn, asi, h);
506
507 asi->insn_handler = actions[action].handler;
508 set_emulated_insn(insn, asi, thumb);
509 return INSN_GOOD;
510 }
511
512 case DECODE_TYPE_OR:
513 matched = true;
514 break;
515
516 case DECODE_TYPE_REJECT:
517 default:
518 return INSN_REJECTED;
519 }
520 }
521}
522