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