blob: 86fdc4c4c2ceeb7ea49f686b83bc7b4bb8f63b12 [file] [log] [blame]
Jon Medhurst0ab4c022011-07-06 11:25:18 +01001/*
2 * arch/arm/kernel/kprobes-common.c
3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 *
Jon Medhurst6c8df332011-07-07 10:21:40 +01006 * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is
7 * Copyright (C) 2006, 2007 Motorola Inc.
8 *
Jon Medhurst0ab4c022011-07-06 11:25:18 +01009 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/kprobes.h>
16
17#include "kprobes.h"
18
19
Jon Medhurstaea49022011-07-07 19:58:29 +010020#ifndef find_str_pc_offset
21
Jon Medhurst6c8df332011-07-07 10:21:40 +010022/*
23 * For STR and STM instructions, an ARM core may choose to use either
24 * a +8 or a +12 displacement from the current instruction's address.
25 * Whichever value is chosen for a given core, it must be the same for
26 * both instructions and may not change. This function measures it.
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
Jon Medhurstaea49022011-07-07 19:58:29 +010045#endif /* !find_str_pc_offset */
46
Jon Medhurst6c8df332011-07-07 10:21:40 +010047
Jon Medhurst263e3682011-06-10 20:29:04 +010048#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 /* !test_load_write_pc_interworking */
60
61
Jon Medhurst6c8df332011-07-07 10:21:40 +010062void __init arm_kprobe_decode_init(void)
63{
64 find_str_pc_offset();
Jon Medhurst263e3682011-06-10 20:29:04 +010065 test_load_write_pc_interworking();
Jon Medhurst6c8df332011-07-07 10:21:40 +010066}
67
68
Jon Medhurst0ab4c022011-07-06 11:25:18 +010069static unsigned long __kprobes __check_eq(unsigned long cpsr)
70{
71 return cpsr & PSR_Z_BIT;
72}
73
74static unsigned long __kprobes __check_ne(unsigned long cpsr)
75{
76 return (~cpsr) & PSR_Z_BIT;
77}
78
79static unsigned long __kprobes __check_cs(unsigned long cpsr)
80{
81 return cpsr & PSR_C_BIT;
82}
83
84static unsigned long __kprobes __check_cc(unsigned long cpsr)
85{
86 return (~cpsr) & PSR_C_BIT;
87}
88
89static unsigned long __kprobes __check_mi(unsigned long cpsr)
90{
91 return cpsr & PSR_N_BIT;
92}
93
94static unsigned long __kprobes __check_pl(unsigned long cpsr)
95{
96 return (~cpsr) & PSR_N_BIT;
97}
98
99static unsigned long __kprobes __check_vs(unsigned long cpsr)
100{
101 return cpsr & PSR_V_BIT;
102}
103
104static unsigned long __kprobes __check_vc(unsigned long cpsr)
105{
106 return (~cpsr) & PSR_V_BIT;
107}
108
109static unsigned long __kprobes __check_hi(unsigned long cpsr)
110{
111 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
112 return cpsr & PSR_C_BIT;
113}
114
115static unsigned long __kprobes __check_ls(unsigned long cpsr)
116{
117 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
118 return (~cpsr) & PSR_C_BIT;
119}
120
121static unsigned long __kprobes __check_ge(unsigned long cpsr)
122{
123 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
124 return (~cpsr) & PSR_N_BIT;
125}
126
127static unsigned long __kprobes __check_lt(unsigned long cpsr)
128{
129 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
130 return cpsr & PSR_N_BIT;
131}
132
133static unsigned long __kprobes __check_gt(unsigned long cpsr)
134{
135 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
136 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
137 return (~temp) & PSR_N_BIT;
138}
139
140static unsigned long __kprobes __check_le(unsigned long cpsr)
141{
142 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
143 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
144 return temp & PSR_N_BIT;
145}
146
147static unsigned long __kprobes __check_al(unsigned long cpsr)
148{
149 return true;
150}
151
152kprobe_check_cc * const kprobe_condition_checks[16] = {
153 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
154 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
155 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
156 &__check_gt, &__check_le, &__check_al, &__check_al
157};
Jon Medhurst0d1a0952011-04-26 15:15:56 +0100158
159
Jon Medhurst3f92dfe2011-07-02 15:36:32 +0100160void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs)
161{
162}
163
164void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs)
165{
166 p->ainsn.insn_fn();
167}
168
Jon Medhurst0d1a0952011-04-26 15:15:56 +0100169/*
170 * Prepare an instruction slot to receive an instruction for emulating.
171 * This is done by placing a subroutine return after the location where the
172 * instruction will be placed. We also modify ARM instructions to be
173 * unconditional as the condition code will already be checked before any
174 * emulation handler is called.
175 */
176static kprobe_opcode_t __kprobes
177prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
178 bool thumb)
179{
180#ifdef CONFIG_THUMB2_KERNEL
181 if (thumb) {
182 u16 *thumb_insn = (u16 *)asi->insn;
183 thumb_insn[1] = 0x4770; /* Thumb bx lr */
184 thumb_insn[2] = 0x4770; /* Thumb bx lr */
185 return insn;
186 }
187 asi->insn[1] = 0xe12fff1e; /* ARM bx lr */
188#else
189 asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */
190#endif
191 /* Make an ARM instruction unconditional */
192 if (insn < 0xe0000000)
193 insn = (insn | 0xe0000000) & ~0x10000000;
194 return insn;
195}
196
197/*
198 * Write a (probably modified) instruction into the slot previously prepared by
199 * prepare_emulated_insn
200 */
201static void __kprobes
202set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
203 bool thumb)
204{
205#ifdef CONFIG_THUMB2_KERNEL
206 if (thumb) {
207 u16 *ip = (u16 *)asi->insn;
208 if (is_wide_instruction(insn))
209 *ip++ = insn >> 16;
210 *ip++ = insn;
211 return;
212 }
213#endif
214 asi->insn[0] = insn;
215}
216
217/*
218 * When we modify the register numbers encoded in an instruction to be emulated,
219 * the new values come from this define. For ARM and 32-bit Thumb instructions
220 * this gives...
221 *
222 * bit position 16 12 8 4 0
223 * ---------------+---+---+---+---+---+
224 * register r2 r0 r1 -- r3
225 */
226#define INSN_NEW_BITS 0x00020103
227
228/* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
229#define INSN_SAMEAS16_BITS 0x22222222
230
231/*
232 * Validate and modify each of the registers encoded in an instruction.
233 *
234 * Each nibble in regs contains a value from enum decode_reg_type. For each
235 * non-zero value, the corresponding nibble in pinsn is validated and modified
236 * according to the type.
237 */
238static bool __kprobes decode_regs(kprobe_opcode_t* pinsn, u32 regs)
239{
240 kprobe_opcode_t insn = *pinsn;
241 kprobe_opcode_t mask = 0xf; /* Start at least significant nibble */
242
243 for (; regs != 0; regs >>= 4, mask <<= 4) {
244
245 kprobe_opcode_t new_bits = INSN_NEW_BITS;
246
247 switch (regs & 0xf) {
248
249 case REG_TYPE_NONE:
250 /* Nibble not a register, skip to next */
251 continue;
252
253 case REG_TYPE_ANY:
254 /* Any register is allowed */
255 break;
256
257 case REG_TYPE_SAMEAS16:
258 /* Replace register with same as at bit position 16 */
259 new_bits = INSN_SAMEAS16_BITS;
260 break;
261
262 case REG_TYPE_SP:
263 /* Only allow SP (R13) */
264 if ((insn ^ 0xdddddddd) & mask)
265 goto reject;
266 break;
267
268 case REG_TYPE_PC:
269 /* Only allow PC (R15) */
270 if ((insn ^ 0xffffffff) & mask)
271 goto reject;
272 break;
273
274 case REG_TYPE_NOSP:
275 /* Reject SP (R13) */
276 if (((insn ^ 0xdddddddd) & mask) == 0)
277 goto reject;
278 break;
279
280 case REG_TYPE_NOSPPC:
281 case REG_TYPE_NOSPPCX:
282 /* Reject SP and PC (R13 and R15) */
283 if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
284 goto reject;
285 break;
286
287 case REG_TYPE_NOPCWB:
288 if (!is_writeback(insn))
289 break; /* No writeback, so any register is OK */
290 /* fall through... */
291 case REG_TYPE_NOPC:
292 case REG_TYPE_NOPCX:
293 /* Reject PC (R15) */
294 if (((insn ^ 0xffffffff) & mask) == 0)
295 goto reject;
296 break;
297 }
298
299 /* Replace value of nibble with new register number... */
300 insn &= ~mask;
301 insn |= new_bits & mask;
302 }
303
304 *pinsn = insn;
305 return true;
306
307reject:
308 return false;
309}
310
311static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
312 [DECODE_TYPE_TABLE] = sizeof(struct decode_table),
313 [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom),
314 [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate),
315 [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate),
316 [DECODE_TYPE_OR] = sizeof(struct decode_or),
317 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
318};
319
320/*
321 * kprobe_decode_insn operates on data tables in order to decode an ARM
322 * architecture instruction onto which a kprobe has been placed.
323 *
324 * These instruction decoding tables are a concatenation of entries each
325 * of which consist of one of the following structs:
326 *
327 * decode_table
328 * decode_custom
329 * decode_simulate
330 * decode_emulate
331 * decode_or
332 * decode_reject
333 *
334 * Each of these starts with a struct decode_header which has the following
335 * fields:
336 *
337 * type_regs
338 * mask
339 * value
340 *
341 * The least significant DECODE_TYPE_BITS of type_regs contains a value
342 * from enum decode_type, this indicates which of the decode_* structs
343 * the entry contains. The value DECODE_TYPE_END indicates the end of the
344 * table.
345 *
346 * When the table is parsed, each entry is checked in turn to see if it
347 * matches the instruction to be decoded using the test:
348 *
349 * (insn & mask) == value
350 *
351 * If no match is found before the end of the table is reached then decoding
352 * fails with INSN_REJECTED.
353 *
354 * When a match is found, decode_regs() is called to validate and modify each
355 * of the registers encoded in the instruction; the data it uses to do this
356 * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
357 * to fail with INSN_REJECTED.
358 *
359 * Once the instruction has passed the above tests, further processing
360 * depends on the type of the table entry's decode struct.
361 *
362 */
363int __kprobes
364kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
365 const union decode_item *table, bool thumb)
366{
367 const struct decode_header *h = (struct decode_header *)table;
368 const struct decode_header *next;
369 bool matched = false;
370
371 insn = prepare_emulated_insn(insn, asi, thumb);
372
373 for (;; h = next) {
374 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
375 u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
376
377 if (type == DECODE_TYPE_END)
378 return INSN_REJECTED;
379
380 next = (struct decode_header *)
381 ((uintptr_t)h + decode_struct_sizes[type]);
382
383 if (!matched && (insn & h->mask.bits) != h->value.bits)
384 continue;
385
386 if (!decode_regs(&insn, regs))
387 return INSN_REJECTED;
388
389 switch (type) {
390
391 case DECODE_TYPE_TABLE: {
392 struct decode_table *d = (struct decode_table *)h;
393 next = (struct decode_header *)d->table.table;
394 break;
395 }
396
397 case DECODE_TYPE_CUSTOM: {
398 struct decode_custom *d = (struct decode_custom *)h;
399 return (*d->decoder.decoder)(insn, asi);
400 }
401
402 case DECODE_TYPE_SIMULATE: {
403 struct decode_simulate *d = (struct decode_simulate *)h;
404 asi->insn_handler = d->handler.handler;
405 return INSN_GOOD_NO_SLOT;
406 }
407
408 case DECODE_TYPE_EMULATE: {
409 struct decode_emulate *d = (struct decode_emulate *)h;
410 asi->insn_handler = d->handler.handler;
411 set_emulated_insn(insn, asi, thumb);
412 return INSN_GOOD;
413 }
414
415 case DECODE_TYPE_OR:
416 matched = true;
417 break;
418
419 case DECODE_TYPE_REJECT:
420 default:
421 return INSN_REJECTED;
422 }
423 }
424 }