powerpc: ftrace, added missing icache flush
[safe/jmp/linux-2.6] / arch / powerpc / kernel / ftrace.c
1 /*
2  * Code for replacing ftrace calls with jumps.
3  *
4  * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
5  *
6  * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box.
7  *
8  */
9
10 #include <linux/spinlock.h>
11 #include <linux/hardirq.h>
12 #include <linux/uaccess.h>
13 #include <linux/module.h>
14 #include <linux/ftrace.h>
15 #include <linux/percpu.h>
16 #include <linux/init.h>
17 #include <linux/list.h>
18
19 #include <asm/cacheflush.h>
20 #include <asm/code-patching.h>
21 #include <asm/ftrace.h>
22
23 #if 0
24 #define DEBUGP printk
25 #else
26 #define DEBUGP(fmt , ...)       do { } while (0)
27 #endif
28
29 static unsigned int ftrace_nop = PPC_NOP_INSTR;
30
31 #ifdef CONFIG_PPC32
32 # define GET_ADDR(addr) addr
33 #else
34 /* PowerPC64's functions are data that points to the functions */
35 # define GET_ADDR(addr) (*(unsigned long *)addr)
36 #endif
37
38
39 static unsigned int ftrace_calc_offset(long ip, long addr)
40 {
41         return (int)(addr - ip);
42 }
43
44 static unsigned char *ftrace_nop_replace(void)
45 {
46         return (char *)&ftrace_nop;
47 }
48
49 static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
50 {
51         static unsigned int op;
52
53         /*
54          * It would be nice to just use create_function_call, but that will
55          * update the code itself. Here we need to just return the
56          * instruction that is going to be modified, without modifying the
57          * code.
58          */
59         addr = GET_ADDR(addr);
60
61         /* Set to "bl addr" */
62         op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc);
63
64         /*
65          * No locking needed, this must be called via kstop_machine
66          * which in essence is like running on a uniprocessor machine.
67          */
68         return (unsigned char *)&op;
69 }
70
71 #ifdef CONFIG_PPC64
72 # define _ASM_ALIGN     " .align 3 "
73 # define _ASM_PTR       " .llong "
74 #else
75 # define _ASM_ALIGN     " .align 2 "
76 # define _ASM_PTR       " .long "
77 #endif
78
79 static int
80 ftrace_modify_code(unsigned long ip, unsigned char *old_code,
81                    unsigned char *new_code)
82 {
83         unsigned char replaced[MCOUNT_INSN_SIZE];
84
85         /*
86          * Note: Due to modules and __init, code can
87          *  disappear and change, we need to protect against faulting
88          *  as well as code changing. We do this by using the
89          *  probe_kernel_* functions.
90          *
91          * No real locking needed, this code is run through
92          * kstop_machine, or before SMP starts.
93          */
94
95         /* read the text we want to modify */
96         if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
97                 return -EFAULT;
98
99         /* Make sure it is what we expect it to be */
100         if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
101                 return -EINVAL;
102
103         /* replace the text with the new text */
104         if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
105                 return -EPERM;
106
107         flush_icache_range(ip, ip + 8);
108
109         return 0;
110 }
111
112 /*
113  * Helper functions that are the same for both PPC64 and PPC32.
114  */
115 static int test_24bit_addr(unsigned long ip, unsigned long addr)
116 {
117         long diff;
118
119         /*
120          * Can we get to addr from ip in 24 bits?
121          *  (26 really, since we mulitply by 4 for 4 byte alignment)
122          */
123         diff = addr - ip;
124
125         /*
126          * Return true if diff is less than 1 << 25
127          *  and greater than -1 << 26.
128          */
129         return (diff < (1 << 25)) && (diff > (-1 << 26));
130 }
131
132 static int is_bl_op(unsigned int op)
133 {
134         return (op & 0xfc000003) == 0x48000001;
135 }
136
137 static int test_offset(unsigned long offset)
138 {
139         return (offset + 0x2000000 > 0x3ffffff) || ((offset & 3) != 0);
140 }
141
142 static unsigned long find_bl_target(unsigned long ip, unsigned int op)
143 {
144         static int offset;
145
146         offset = (op & 0x03fffffc);
147         /* make it signed */
148         if (offset & 0x02000000)
149                 offset |= 0xfe000000;
150
151         return ip + (long)offset;
152 }
153
154 static unsigned int branch_offset(unsigned long offset)
155 {
156         /* return "bl ip+offset" */
157         return 0x48000001 | (offset & 0x03fffffc);
158 }
159
160 #ifdef CONFIG_PPC64
161 static int
162 __ftrace_make_nop(struct module *mod,
163                   struct dyn_ftrace *rec, unsigned long addr)
164 {
165         unsigned int op;
166         unsigned int jmp[5];
167         unsigned long ptr;
168         unsigned long ip = rec->ip;
169         unsigned long tramp;
170         int offset;
171
172         /* read where this goes */
173         if (probe_kernel_read(&op, (void *)ip, sizeof(int)))
174                 return -EFAULT;
175
176         /* Make sure that that this is still a 24bit jump */
177         if (!is_bl_op(op)) {
178                 printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
179                 return -EINVAL;
180         }
181
182         /* lets find where the pointer goes */
183         tramp = find_bl_target(ip, op);
184
185         /*
186          * On PPC64 the trampoline looks like:
187          * 0x3d, 0x82, 0x00, 0x00,    addis   r12,r2, <high>
188          * 0x39, 0x8c, 0x00, 0x00,    addi    r12,r12, <low>
189          *   Where the bytes 2,3,6 and 7 make up the 32bit offset
190          *   to the TOC that holds the pointer.
191          *   to jump to.
192          * 0xf8, 0x41, 0x00, 0x28,    std     r2,40(r1)
193          * 0xe9, 0x6c, 0x00, 0x20,    ld      r11,32(r12)
194          *   The actually address is 32 bytes from the offset
195          *   into the TOC.
196          * 0xe8, 0x4c, 0x00, 0x28,    ld      r2,40(r12)
197          */
198
199         DEBUGP("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
200
201         /* Find where the trampoline jumps to */
202         if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
203                 printk(KERN_ERR "Failed to read %lx\n", tramp);
204                 return -EFAULT;
205         }
206
207         DEBUGP(" %08x %08x", jmp[0], jmp[1]);
208
209         /* verify that this is what we expect it to be */
210         if (((jmp[0] & 0xffff0000) != 0x3d820000) ||
211             ((jmp[1] & 0xffff0000) != 0x398c0000) ||
212             (jmp[2] != 0xf8410028) ||
213             (jmp[3] != 0xe96c0020) ||
214             (jmp[4] != 0xe84c0028)) {
215                 printk(KERN_ERR "Not a trampoline\n");
216                 return -EINVAL;
217         }
218
219         offset = (unsigned)((unsigned short)jmp[0]) << 16 |
220                 (unsigned)((unsigned short)jmp[1]);
221
222         DEBUGP(" %x ", offset);
223
224         /* get the address this jumps too */
225         tramp = mod->arch.toc + offset + 32;
226         DEBUGP("toc: %lx", tramp);
227
228         if (probe_kernel_read(jmp, (void *)tramp, 8)) {
229                 printk(KERN_ERR "Failed to read %lx\n", tramp);
230                 return -EFAULT;
231         }
232
233         DEBUGP(" %08x %08x\n", jmp[0], jmp[1]);
234
235         ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
236
237         /* This should match what was called */
238         if (ptr != GET_ADDR(addr)) {
239                 printk(KERN_ERR "addr does not match %lx\n", ptr);
240                 return -EINVAL;
241         }
242
243         /*
244          * We want to nop the line, but the next line is
245          *  0xe8, 0x41, 0x00, 0x28   ld r2,40(r1)
246          * This needs to be turned to a nop too.
247          */
248         if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE))
249                 return -EFAULT;
250
251         if (op != 0xe8410028) {
252                 printk(KERN_ERR "Next line is not ld! (%08x)\n", op);
253                 return -EINVAL;
254         }
255
256         /*
257          * Milton Miller pointed out that we can not blindly do nops.
258          * If a task was preempted when calling a trace function,
259          * the nops will remove the way to restore the TOC in r2
260          * and the r2 TOC will get corrupted.
261          */
262
263         /*
264          * Replace:
265          *   bl <tramp>  <==== will be replaced with "b 1f"
266          *   ld r2,40(r1)
267          *  1:
268          */
269         op = 0x48000008;        /* b +8 */
270
271         if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
272                 return -EPERM;
273
274
275         flush_icache_range(ip, ip + 8);
276
277         return 0;
278 }
279
280 #else /* !PPC64 */
281 static int
282 __ftrace_make_nop(struct module *mod,
283                   struct dyn_ftrace *rec, unsigned long addr)
284 {
285         unsigned int op;
286         unsigned int jmp[4];
287         unsigned long ip = rec->ip;
288         unsigned long tramp;
289
290         if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE))
291                 return -EFAULT;
292
293         /* Make sure that that this is still a 24bit jump */
294         if (!is_bl_op(op)) {
295                 printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
296                 return -EINVAL;
297         }
298
299         /* lets find where the pointer goes */
300         tramp = find_bl_target(ip, op);
301
302         /*
303          * On PPC32 the trampoline looks like:
304          *  0x3d, 0x60, 0x00, 0x00  lis r11,sym@ha
305          *  0x39, 0x6b, 0x00, 0x00  addi r11,r11,sym@l
306          *  0x7d, 0x69, 0x03, 0xa6  mtctr r11
307          *  0x4e, 0x80, 0x04, 0x20  bctr
308          */
309
310         DEBUGP("ip:%lx jumps to %lx", ip, tramp);
311
312         /* Find where the trampoline jumps to */
313         if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
314                 printk(KERN_ERR "Failed to read %lx\n", tramp);
315                 return -EFAULT;
316         }
317
318         DEBUGP(" %08x %08x ", jmp[0], jmp[1]);
319
320         /* verify that this is what we expect it to be */
321         if (((jmp[0] & 0xffff0000) != 0x3d600000) ||
322             ((jmp[1] & 0xffff0000) != 0x396b0000) ||
323             (jmp[2] != 0x7d6903a6) ||
324             (jmp[3] != 0x4e800420)) {
325                 printk(KERN_ERR "Not a trampoline\n");
326                 return -EINVAL;
327         }
328
329         tramp = (jmp[1] & 0xffff) |
330                 ((jmp[0] & 0xffff) << 16);
331         if (tramp & 0x8000)
332                 tramp -= 0x10000;
333
334         DEBUGP(" %x ", tramp);
335
336         if (tramp != addr) {
337                 printk(KERN_ERR
338                        "Trampoline location %08lx does not match addr\n",
339                        tramp);
340                 return -EINVAL;
341         }
342
343         op = PPC_NOP_INSTR;
344
345         if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
346                 return -EPERM;
347
348         flush_icache_range(ip, ip + 8);
349
350         return 0;
351 }
352 #endif /* PPC64 */
353
354 int ftrace_make_nop(struct module *mod,
355                     struct dyn_ftrace *rec, unsigned long addr)
356 {
357         unsigned char *old, *new;
358         unsigned long ip = rec->ip;
359
360         /*
361          * If the calling address is more that 24 bits away,
362          * then we had to use a trampoline to make the call.
363          * Otherwise just update the call site.
364          */
365         if (test_24bit_addr(ip, addr)) {
366                 /* within range */
367                 old = ftrace_call_replace(ip, addr);
368                 new = ftrace_nop_replace();
369                 return ftrace_modify_code(ip, old, new);
370         }
371
372         /*
373          * Out of range jumps are called from modules.
374          * We should either already have a pointer to the module
375          * or it has been passed in.
376          */
377         if (!rec->arch.mod) {
378                 if (!mod) {
379                         printk(KERN_ERR "No module loaded addr=%lx\n",
380                                addr);
381                         return -EFAULT;
382                 }
383                 rec->arch.mod = mod;
384         } else if (mod) {
385                 if (mod != rec->arch.mod) {
386                         printk(KERN_ERR
387                                "Record mod %p not equal to passed in mod %p\n",
388                                rec->arch.mod, mod);
389                         return -EINVAL;
390                 }
391                 /* nothing to do if mod == rec->arch.mod */
392         } else
393                 mod = rec->arch.mod;
394
395         return __ftrace_make_nop(mod, rec, addr);
396
397 }
398
399 #ifdef CONFIG_PPC64
400 static int
401 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
402 {
403         unsigned int op[2];
404         unsigned long ip = rec->ip;
405         unsigned long offset;
406
407         /* read where this goes */
408         if (probe_kernel_read(op, (void *)ip, MCOUNT_INSN_SIZE * 2))
409                 return -EFAULT;
410
411         /*
412          * It should be pointing to two nops or
413          *  b +8; ld r2,40(r1)
414          */
415         if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) &&
416             ((op[0] != PPC_NOP_INSTR) || (op[1] != PPC_NOP_INSTR))) {
417                 printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]);
418                 return -EINVAL;
419         }
420
421         /* If we never set up a trampoline to ftrace_caller, then bail */
422         if (!rec->arch.mod->arch.tramp) {
423                 printk(KERN_ERR "No ftrace trampoline\n");
424                 return -EINVAL;
425         }
426
427         /* now calculate a jump to the ftrace caller trampoline */
428         offset = rec->arch.mod->arch.tramp - ip;
429
430         if (test_offset(offset)) {
431                 printk(KERN_ERR "REL24 %li out of range!\n",
432                        (long int)offset);
433                 return -EINVAL;
434         }
435
436         /* Set to "bl addr" */
437         op[0] = branch_offset(offset);
438         /* ld r2,40(r1) */
439         op[1] = 0xe8410028;
440
441         DEBUGP("write to %lx\n", rec->ip);
442
443         if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2))
444                 return -EPERM;
445
446         flush_icache_range(ip, ip + 8);
447
448         return 0;
449 }
450 #else
451 static int
452 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
453 {
454         unsigned int op;
455         unsigned long ip = rec->ip;
456         unsigned long offset;
457
458         /* read where this goes */
459         if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE))
460                 return -EFAULT;
461
462         /* It should be pointing to a nop */
463         if (op != PPC_NOP_INSTR) {
464                 printk(KERN_ERR "Expected NOP but have %x\n", op);
465                 return -EINVAL;
466         }
467
468         /* If we never set up a trampoline to ftrace_caller, then bail */
469         if (!rec->arch.mod->arch.tramp) {
470                 printk(KERN_ERR "No ftrace trampoline\n");
471                 return -EINVAL;
472         }
473
474         /* now calculate a jump to the ftrace caller trampoline */
475         offset = rec->arch.mod->arch.tramp - ip;
476
477         if (test_offset(offset)) {
478                 printk(KERN_ERR "REL24 %li out of range!\n",
479                        (long int)offset);
480                 return -EINVAL;
481         }
482
483         /* Set to "bl addr" */
484         op = branch_offset(offset);
485
486         DEBUGP("write to %lx\n", rec->ip);
487
488         if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
489                 return -EPERM;
490
491         flush_icache_range(ip, ip + 8);
492
493         return 0;
494 }
495 #endif /* CONFIG_PPC64 */
496
497 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
498 {
499         unsigned char *old, *new;
500         unsigned long ip = rec->ip;
501
502         /*
503          * If the calling address is more that 24 bits away,
504          * then we had to use a trampoline to make the call.
505          * Otherwise just update the call site.
506          */
507         if (test_24bit_addr(ip, addr)) {
508                 /* within range */
509                 old = ftrace_nop_replace();
510                 new = ftrace_call_replace(ip, addr);
511                 return ftrace_modify_code(ip, old, new);
512         }
513
514         /*
515          * Out of range jumps are called from modules.
516          * Being that we are converting from nop, it had better
517          * already have a module defined.
518          */
519         if (!rec->arch.mod) {
520                 printk(KERN_ERR "No module loaded\n");
521                 return -EINVAL;
522         }
523
524         return __ftrace_make_call(rec, addr);
525 }
526
527 int ftrace_update_ftrace_func(ftrace_func_t func)
528 {
529         unsigned long ip = (unsigned long)(&ftrace_call);
530         unsigned char old[MCOUNT_INSN_SIZE], *new;
531         int ret;
532
533         memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
534         new = ftrace_call_replace(ip, (unsigned long)func);
535         ret = ftrace_modify_code(ip, old, new);
536
537         return ret;
538 }
539
540 int __init ftrace_dyn_arch_init(void *data)
541 {
542         /* caller expects data to be zero */
543         unsigned long *p = data;
544
545         *p = 0;
546
547         return 0;
548 }