[REFACTOR] Buffer: move getting next queue element into separate function
[kernel/swap-modules.git] / kprobe / arch / asm-arm / dbi_kprobes.c
1 /*
2  *  Dynamic Binary Instrumentation Module based on KProbes
3  *  modules/kprobe/arch/asm-arm/dbi_kprobes.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2006-2010
20  *
21  * 2006-2007    Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
22  * 2008-2009    Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
23  *              Probes initial implementation; Support x86.
24  * 2010         Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
25  * 2010-2011    Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
26  * 2012         Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
27  * 2012         Stanislav Andreev <s.andreev@samsung.com>: redesign of kprobe functionality -
28  *              kprobe_handler() now called via undefined instruction hooks
29  * 2012         Stanislav Andreev <s.andreev@samsung.com>: hash tables search implemented for uprobes
30  */
31
32 #include <linux/module.h>
33 #include <linux/mm.h>
34
35 #include "dbi_kprobes.h"
36 #include "trampoline_arm.h"
37 #include <kprobe/dbi_kprobes.h>
38
39 #include <kprobe/dbi_kdebug.h>
40 #include <kprobe/dbi_insn_slots.h>
41 #include <kprobe/dbi_kprobes_deps.h>
42 #include <ksyms/ksyms.h>
43
44 #include <asm/cacheflush.h>
45 #include <asm/traps.h>
46 #include <asm/ptrace.h>
47 #include <linux/list.h>
48 #include <linux/hash.h>
49
50 #define SUPRESS_BUG_MESSAGES
51
52 extern struct kprobe * per_cpu__current_kprobe;
53 extern struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
54
55 static void (*__swap_register_undef_hook)(struct undef_hook *hook);
56 static void (*__swap_unregister_undef_hook)(struct undef_hook *hook);
57
58 int prep_pc_dep_insn_execbuf(kprobe_opcode_t *insns, kprobe_opcode_t insn, int uregs)
59 {
60         int i;
61
62         if (uregs & 0x10) {
63                 int reg_mask = 0x1;
64                 //search in reg list
65                 for (i = 0; i < 13; i++, reg_mask <<= 1) {
66                         if (!(insn & reg_mask))
67                                 break;
68                 }
69         } else {
70                 for (i = 0; i < 13; i++) {
71                         if ((uregs & 0x1) && (ARM_INSN_REG_RN(insn) == i))
72                                 continue;
73                         if ((uregs & 0x2) && (ARM_INSN_REG_RD(insn) == i))
74                                 continue;
75                         if ((uregs & 0x4) && (ARM_INSN_REG_RS(insn) == i))
76                                 continue;
77                         if ((uregs & 0x8) && (ARM_INSN_REG_RM(insn) == i))
78                                 continue;
79                         break;
80                 }
81         }
82
83         if (i == 13) {
84                 DBPRINTF ("there are no free register %x in insn %lx!", uregs, insn);
85                 return -EINVAL;
86         }
87         DBPRINTF ("prep_pc_dep_insn_execbuf: using R%d, changing regs %x", i, uregs);
88
89         // set register to save
90         ARM_INSN_REG_SET_RD(insns[0], i);
91         // set register to load address to
92         ARM_INSN_REG_SET_RD(insns[1], i);
93         // set instruction to execute and patch it
94         if (uregs & 0x10) {
95                 ARM_INSN_REG_CLEAR_MR(insn, 15);
96                 ARM_INSN_REG_SET_MR(insn, i);
97         } else {
98                 if ((uregs & 0x1) && (ARM_INSN_REG_RN(insn) == 15))
99                         ARM_INSN_REG_SET_RN(insn, i);
100                 if ((uregs & 0x2) && (ARM_INSN_REG_RD(insn) == 15))
101                         ARM_INSN_REG_SET_RD(insn, i);
102                 if ((uregs & 0x4) && (ARM_INSN_REG_RS(insn) == 15))
103                         ARM_INSN_REG_SET_RS(insn, i);
104                 if ((uregs & 0x8) && (ARM_INSN_REG_RM(insn) == 15))
105                         ARM_INSN_REG_SET_RM(insn, i);
106         }
107
108         insns[UPROBES_TRAMP_INSN_IDX] = insn;
109         // set register to restore
110         ARM_INSN_REG_SET_RD(insns[3], i);
111
112         return 0;
113 }
114 EXPORT_SYMBOL_GPL(prep_pc_dep_insn_execbuf);
115
116 int arch_check_insn_arm(unsigned long insn)
117 {
118         /* check instructions that can change PC by nature */
119         if (
120          /* ARM_INSN_MATCH(UNDEF, insn) || */
121             ARM_INSN_MATCH(AUNDEF, insn) ||
122             ARM_INSN_MATCH(SWI, insn) ||
123             ARM_INSN_MATCH(BREAK, insn) ||
124             ARM_INSN_MATCH(BXJ, insn)) {
125                 goto bad_insn;
126 #ifndef CONFIG_CPU_V7
127         /* check instructions that can write result to PC */
128         } else if ((ARM_INSN_MATCH(DPIS, insn) ||
129                     ARM_INSN_MATCH(DPRS, insn) ||
130                     ARM_INSN_MATCH(DPI, insn) ||
131                     ARM_INSN_MATCH(LIO, insn) ||
132                     ARM_INSN_MATCH(LRO, insn)) &&
133                    (ARM_INSN_REG_RD(insn) == 15)) {
134                 goto bad_insn;
135 #endif /* CONFIG_CPU_V7 */
136         /* check special instruction loads store multiple registers */
137         } else if ((ARM_INSN_MATCH(LM, insn) || ARM_INSN_MATCH(SM, insn)) &&
138                         /* store PC or load to PC */
139                    (ARM_INSN_REG_MR(insn, 15) ||
140                          /* store/load with PC update */
141                     ((ARM_INSN_REG_RN(insn) == 15) && (insn & 0x200000)))) {
142                 goto bad_insn;
143         }
144
145         return 0;
146
147 bad_insn:
148         printk("Bad insn arch_check_insn_arm: %lx\n", insn);
149         return -EFAULT;
150 }
151 EXPORT_SYMBOL_GPL(arch_check_insn_arm);
152
153 int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
154 {
155         kprobe_opcode_t insns[KPROBES_TRAMP_LEN];
156         int uregs, pc_dep, ret = 0;
157         kprobe_opcode_t insn[MAX_INSN_SIZE];
158         struct arch_specific_insn ainsn;
159
160         /* insn: must be on special executable page on i386. */
161         p->ainsn.insn = alloc_insn_slot(sm);
162         if (!p->ainsn.insn)
163                 return -ENOMEM;
164
165         memcpy(insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
166         ainsn.insn_arm = ainsn.insn = insn;
167         ret = arch_check_insn_arm(insn[0]);
168         if (!ret) {
169                 p->opcode = *p->addr;
170                 uregs = pc_dep = 0;
171
172                 // Rn, Rm ,Rd
173                 if (ARM_INSN_MATCH(DPIS, insn[0]) || ARM_INSN_MATCH(LRO, insn[0]) ||
174                     ARM_INSN_MATCH(SRO, insn[0])) {
175                         uregs = 0xb;
176                         if ((ARM_INSN_REG_RN(insn[0]) == 15) || (ARM_INSN_REG_RM(insn[0]) == 15) ||
177                             (ARM_INSN_MATCH(SRO, insn[0]) && (ARM_INSN_REG_RD(insn[0]) == 15))) {
178                                 DBPRINTF ("Unboostable insn %lx, DPIS/LRO/SRO\n", insn[0]);
179                                 pc_dep = 1;
180                         }
181
182                 // Rn ,Rd
183                 } else if( ARM_INSN_MATCH(DPI, insn[0]) || ARM_INSN_MATCH(LIO, insn[0]) ||
184                            ARM_INSN_MATCH(SIO, insn[0])) {
185                         uregs = 0x3;
186                         if ((ARM_INSN_REG_RN(insn[0]) == 15) || (ARM_INSN_MATCH(SIO, insn[0]) &&
187                             (ARM_INSN_REG_RD (insn[0]) == 15))) {
188                                 pc_dep = 1;
189                                 DBPRINTF ("Unboostable insn %lx/%p, DPI/LIO/SIO\n", insn[0], p);
190                         }
191                 // Rn, Rm, Rs
192                 } else if (ARM_INSN_MATCH(DPRS, insn[0])) {
193                         uregs = 0xd;
194                         if ((ARM_INSN_REG_RN(insn[0]) == 15) || (ARM_INSN_REG_RM(insn[0]) == 15) ||
195                             (ARM_INSN_REG_RS (insn[0]) == 15)) {
196                                 pc_dep = 1;
197                                 DBPRINTF ("Unboostable insn %lx, DPRS\n", insn[0]);
198                         }
199                 // register list
200                 } else if(ARM_INSN_MATCH(SM, insn[0])) {
201                         uregs = 0x10;
202                         if (ARM_INSN_REG_MR(insn[0], 15)) {
203                                 DBPRINTF ("Unboostable insn %lx, SM\n", insn[0]);
204                                 pc_dep = 1;
205                         }
206                 }
207
208                 // check instructions that can write result to SP andu uses PC
209                 if (pc_dep  && (ARM_INSN_REG_RD(ainsn.insn[0]) == 13)) {
210                         free_insn_slot(sm, p->ainsn.insn);
211                         ret = -EFAULT;
212                 } else {
213                         if (uregs && pc_dep) {
214                                 memcpy(insns, pc_dep_insn_execbuf, sizeof(insns));
215                                 if (prep_pc_dep_insn_execbuf(insns, insn[0], uregs) != 0) {
216                                         DBPRINTF ("failed to prepare exec buffer for insn %lx!", insn[0]);
217                                         free_insn_slot(sm, p->ainsn.insn);
218                                         return -EINVAL;
219                                 }
220                                 insns[6] = (kprobe_opcode_t)(p->addr + 2);
221                         } else {
222                                 memcpy(insns, gen_insn_execbuf, sizeof(insns));
223                                 insns[KPROBES_TRAMP_INSN_IDX] = insn[0];
224                         }
225                         insns[7] = (kprobe_opcode_t)(p->addr + 1);
226                         DBPRINTF ("arch_prepare_kprobe: insn %lx", insn[0]);
227                         DBPRINTF ("arch_prepare_kprobe: to %p - %lx %lx %lx %lx %lx %lx %lx %lx %lx",
228                                   p->ainsn.insn, insns[0], insns[1], insns[2], insns[3], insns[4],
229                                   insns[5], insns[6], insns[7], insns[8]);
230                         memcpy(p->ainsn.insn, insns, sizeof(insns));
231                         flush_icache_range((long unsigned)p->ainsn.insn, (long unsigned)(p->ainsn.insn) + sizeof(insns));
232 #ifdef BOARD_tegra
233                         flush_cache_all();
234 #endif
235                 }
236         } else {
237                 free_insn_slot(sm, p->ainsn.insn);
238                 printk("arch_prepare_kprobe: instruction 0x%lx not instrumentation, addr=0x%p\n", insn[0], p->addr);
239         }
240
241         return ret;
242 }
243
244 void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
245 {
246         if (p->ss_addr) {
247                 regs->ARM_pc = (unsigned long)p->ss_addr;
248                 p->ss_addr = NULL;
249         } else {
250                 regs->ARM_pc = (unsigned long)p->ainsn.insn;
251         }
252 }
253 EXPORT_SYMBOL_GPL(prepare_singlestep);
254
255 void save_previous_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p_run)
256 {
257         kcb->prev_kprobe.kp = kprobe_running();
258         kcb->prev_kprobe.status = kcb->kprobe_status;
259 }
260
261 void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
262 {
263         __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
264         kcb->kprobe_status = kcb->prev_kprobe.status;
265 }
266
267 void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
268 {
269         __get_cpu_var(current_kprobe) = p;
270         DBPRINTF ("set_current_kprobe: p=%p addr=%p\n", p, p->addr);
271 }
272
273 static int kprobe_handler(struct pt_regs *regs)
274 {
275         struct kprobe *p, *cur;
276         struct kprobe_ctlblk *kcb;
277
278         kcb = get_kprobe_ctlblk();
279         cur = kprobe_running();
280         p = get_kprobe((void *)regs->ARM_pc);
281
282         if (p) {
283                 if (cur) {
284                         /* Kprobe is pending, so we're recursing. */
285                         switch (kcb->kprobe_status) {
286                         case KPROBE_HIT_ACTIVE:
287                         case KPROBE_HIT_SSDONE:
288                                 /* A pre- or post-handler probe got us here. */
289                                 kprobes_inc_nmissed_count(p);
290                                 save_previous_kprobe(kcb, NULL);
291                                 set_current_kprobe(p, 0, 0);
292                                 kcb->kprobe_status = KPROBE_REENTER;
293                                 prepare_singlestep(p, regs);
294                                 restore_previous_kprobe(kcb);
295                                 break;
296                         default:
297                                 /* impossible cases */
298                                 BUG();
299                         }
300                 } else {
301                         set_current_kprobe(p, 0, 0);
302                         kcb->kprobe_status = KPROBE_HIT_ACTIVE;
303
304                         if (!p->pre_handler || !p->pre_handler(p, regs)) {
305                                 kcb->kprobe_status = KPROBE_HIT_SS;
306                                 prepare_singlestep(p, regs);
307                                 reset_current_kprobe();
308                         }
309                 }
310         } else {
311                 goto no_kprobe;
312         }
313
314         return 0;
315
316 no_kprobe:
317         printk("no_kprobe: Not one of ours: let kernel handle it %p\n",
318                         (unsigned long *)regs->ARM_pc);
319         return 1;
320 }
321
322 int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
323 {
324         int ret;
325         unsigned long flags;
326
327 #ifdef SUPRESS_BUG_MESSAGES
328         int swap_oops_in_progress;
329         /* oops_in_progress used to avoid BUG() messages
330          * that slow down kprobe_handler() execution */
331         swap_oops_in_progress = oops_in_progress;
332         oops_in_progress = 1;
333 #endif
334
335         local_irq_save(flags);
336         preempt_disable();
337         ret = kprobe_handler(regs);
338         preempt_enable_no_resched();
339         local_irq_restore(flags);
340
341 #ifdef SUPRESS_BUG_MESSAGES
342         oops_in_progress = swap_oops_in_progress;
343 #endif
344
345         return ret;
346 }
347
348 int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
349 {
350         struct jprobe *jp = container_of(p, struct jprobe, kp);
351         kprobe_pre_entry_handler_t pre_entry = (kprobe_pre_entry_handler_t)jp->pre_entry;
352         entry_point_t entry = (entry_point_t)jp->entry;
353         pre_entry = (kprobe_pre_entry_handler_t)jp->pre_entry;
354
355         if (pre_entry) {
356                 p->ss_addr = (void *)pre_entry (jp->priv_arg, regs);
357         }
358
359         if (entry) {
360                 entry(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2,
361                       regs->ARM_r3, regs->ARM_r4, regs->ARM_r5);
362         } else {
363                 dbi_jprobe_return();
364         }
365
366         return 0;
367 }
368
369 void dbi_jprobe_return (void)
370 {
371 }
372
373 int longjmp_break_handler (struct kprobe *p, struct pt_regs *regs)
374 {
375         return 0;
376 }
377 EXPORT_SYMBOL_GPL(longjmp_break_handler);
378
379 #ifdef CONFIG_STRICT_MEMORY_RWX
380 extern void mem_text_write_kernel_word(unsigned long *addr, unsigned long word);
381 #endif
382
383 void arch_arm_kprobe(struct kprobe *p)
384 {
385 #ifdef CONFIG_STRICT_MEMORY_RWX
386         mem_text_write_kernel_word(p->addr, BREAKPOINT_INSTRUCTION);
387 #else
388         *p->addr = BREAKPOINT_INSTRUCTION;
389         flush_icache_range((unsigned long)p->addr, (unsigned long)p->addr + sizeof(kprobe_opcode_t));
390 #endif
391 }
392
393 void arch_disarm_kprobe(struct kprobe *p)
394 {
395 #ifdef CONFIG_STRICT_MEMORY_RWX
396         mem_text_write_kernel_word(p->addr, p->opcode);
397 #else
398         *p->addr = p->opcode;
399         flush_icache_range((unsigned long)p->addr, (unsigned long)p->addr + sizeof(kprobe_opcode_t));
400 #endif
401 }
402
403 void __naked kretprobe_trampoline(void)
404 {
405         __asm__ __volatile__ (
406                 "stmdb  sp!, {r0 - r11}         \n\t"
407                 "mov    r1, sp                  \n\t"
408                 "mov    r0, #0                  \n\t"
409                 "bl     trampoline_probe_handler\n\t"
410                 "mov    lr, r0                  \n\t"
411                 "ldmia  sp!, {r0 - r11}         \n\t"
412                 "bx     lr                      \n\t"
413                 : : : "memory");
414 }
415
416 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
417 {
418         unsigned long *ptr_ret_addr;
419
420         /* for __switch_to probe */
421         if ((unsigned long)ri->rp->kp.addr == sched_addr) {
422                 struct thread_info *tinfo = (struct thread_info *)regs->ARM_r2;
423
424                 ptr_ret_addr = (unsigned long *)&tinfo->cpu_context.pc;
425                 ri->sp = NULL;
426                 ri->task = tinfo->task;
427         } else {
428                 ptr_ret_addr = (unsigned long *)&regs->ARM_lr;
429                 ri->sp = (unsigned long *)regs->ARM_sp;
430         }
431
432         /* Save the return address */
433         ri->ret_addr = (unsigned long *)*ptr_ret_addr;
434
435         /* Replace the return addr with trampoline addr */
436         *ptr_ret_addr = (unsigned long)&kretprobe_trampoline;
437 }
438
439 void swap_register_undef_hook(struct undef_hook *hook)
440 {
441         __swap_register_undef_hook(hook);
442 }
443 EXPORT_SYMBOL_GPL(swap_register_undef_hook);
444
445 void swap_unregister_undef_hook(struct undef_hook *hook)
446 {
447         __swap_unregister_undef_hook(hook);
448 }
449 EXPORT_SYMBOL_GPL(swap_unregister_undef_hook);
450
451 // kernel probes hook
452 static struct undef_hook undef_ho_k = {
453         .instr_mask     = 0xffffffff,
454         .instr_val      = BREAKPOINT_INSTRUCTION,
455         .cpsr_mask      = MODE_MASK,
456         .cpsr_val       = SVC_MODE,
457         .fn             = kprobe_trap_handler
458 };
459
460 int arch_init_kprobes(void)
461 {
462         // Register hooks (kprobe_handler)
463         __swap_register_undef_hook = (void *)swap_ksyms("register_undef_hook");
464         if (__swap_register_undef_hook == NULL) {
465                 printk("no register_undef_hook symbol found!\n");
466                 return -1;
467         }
468
469         // Unregister hooks (kprobe_handler)
470         __swap_unregister_undef_hook = (void *)swap_ksyms("unregister_undef_hook");
471         if (__swap_unregister_undef_hook == NULL) {
472                 printk("no unregister_undef_hook symbol found!\n");
473                 return -1;
474         }
475
476         swap_register_undef_hook(&undef_ho_k);
477
478         return 0;
479 }
480
481 void arch_exit_kprobes(void)
482 {
483         swap_unregister_undef_hook(&undef_ho_k);
484 }
485
486 /* export symbol for trampoline_arm.h */
487 EXPORT_SYMBOL_GPL(gen_insn_execbuf);
488 EXPORT_SYMBOL_GPL(pc_dep_insn_execbuf);
489 EXPORT_SYMBOL_GPL(b_r_insn_execbuf);
490 EXPORT_SYMBOL_GPL(b_cond_insn_execbuf);
491 EXPORT_SYMBOL_GPL(blx_off_insn_execbuf);