ftrace.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  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. * Added function graph tracer code, taken from x86 that was written
  9. * by Frederic Weisbecker, and ported to PPC by Steven Rostedt.
  10. *
  11. */
  12. #include <linux/spinlock.h>
  13. #include <linux/hardirq.h>
  14. #include <linux/uaccess.h>
  15. #include <linux/module.h>
  16. #include <linux/ftrace.h>
  17. #include <linux/percpu.h>
  18. #include <linux/init.h>
  19. #include <linux/list.h>
  20. #include <asm/cacheflush.h>
  21. #include <asm/code-patching.h>
  22. #include <asm/ftrace.h>
  23. #ifdef CONFIG_DYNAMIC_FTRACE
  24. static unsigned int ftrace_nop_replace(void)
  25. {
  26. return PPC_INST_NOP;
  27. }
  28. static unsigned int
  29. ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
  30. {
  31. unsigned int op;
  32. addr = ppc_function_entry((void *)addr);
  33. /* if (link) set op to 'bl' else 'b' */
  34. op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
  35. return op;
  36. }
  37. static int
  38. ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
  39. {
  40. unsigned int replaced;
  41. /*
  42. * Note: Due to modules and __init, code can
  43. * disappear and change, we need to protect against faulting
  44. * as well as code changing. We do this by using the
  45. * probe_kernel_* functions.
  46. *
  47. * No real locking needed, this code is run through
  48. * kstop_machine, or before SMP starts.
  49. */
  50. /* read the text we want to modify */
  51. if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
  52. return -EFAULT;
  53. /* Make sure it is what we expect it to be */
  54. if (replaced != old)
  55. return -EINVAL;
  56. /* replace the text with the new text */
  57. if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE))
  58. return -EPERM;
  59. flush_icache_range(ip, ip + 8);
  60. return 0;
  61. }
  62. /*
  63. * Helper functions that are the same for both PPC64 and PPC32.
  64. */
  65. static int test_24bit_addr(unsigned long ip, unsigned long addr)
  66. {
  67. /* use the create_branch to verify that this offset can be branched */
  68. return create_branch((unsigned int *)ip, addr, 0);
  69. }
  70. #ifdef CONFIG_MODULES
  71. static int is_bl_op(unsigned int op)
  72. {
  73. return (op & 0xfc000003) == 0x48000001;
  74. }
  75. static unsigned long find_bl_target(unsigned long ip, unsigned int op)
  76. {
  77. static int offset;
  78. offset = (op & 0x03fffffc);
  79. /* make it signed */
  80. if (offset & 0x02000000)
  81. offset |= 0xfe000000;
  82. return ip + (long)offset;
  83. }
  84. #ifdef CONFIG_PPC64
  85. static int
  86. __ftrace_make_nop(struct module *mod,
  87. struct dyn_ftrace *rec, unsigned long addr)
  88. {
  89. unsigned int op;
  90. unsigned int jmp[5];
  91. unsigned long ptr;
  92. unsigned long ip = rec->ip;
  93. unsigned long tramp;
  94. int offset;
  95. /* read where this goes */
  96. if (probe_kernel_read(&op, (void *)ip, sizeof(int)))
  97. return -EFAULT;
  98. /* Make sure that that this is still a 24bit jump */
  99. if (!is_bl_op(op)) {
  100. printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
  101. return -EINVAL;
  102. }
  103. /* lets find where the pointer goes */
  104. tramp = find_bl_target(ip, op);
  105. /*
  106. * On PPC64 the trampoline looks like:
  107. * 0x3d, 0x82, 0x00, 0x00, addis r12,r2, <high>
  108. * 0x39, 0x8c, 0x00, 0x00, addi r12,r12, <low>
  109. * Where the bytes 2,3,6 and 7 make up the 32bit offset
  110. * to the TOC that holds the pointer.
  111. * to jump to.
  112. * 0xf8, 0x41, 0x00, 0x28, std r2,40(r1)
  113. * 0xe9, 0x6c, 0x00, 0x20, ld r11,32(r12)
  114. * The actually address is 32 bytes from the offset
  115. * into the TOC.
  116. * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12)
  117. */
  118. pr_devel("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
  119. /* Find where the trampoline jumps to */
  120. if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
  121. printk(KERN_ERR "Failed to read %lx\n", tramp);
  122. return -EFAULT;
  123. }
  124. pr_devel(" %08x %08x", jmp[0], jmp[1]);
  125. /* verify that this is what we expect it to be */
  126. if (((jmp[0] & 0xffff0000) != 0x3d820000) ||
  127. ((jmp[1] & 0xffff0000) != 0x398c0000) ||
  128. (jmp[2] != 0xf8410028) ||
  129. (jmp[3] != 0xe96c0020) ||
  130. (jmp[4] != 0xe84c0028)) {
  131. printk(KERN_ERR "Not a trampoline\n");
  132. return -EINVAL;
  133. }
  134. /* The bottom half is signed extended */
  135. offset = ((unsigned)((unsigned short)jmp[0]) << 16) +
  136. (int)((short)jmp[1]);
  137. pr_devel(" %x ", offset);
  138. /* get the address this jumps too */
  139. tramp = mod->arch.toc + offset + 32;
  140. pr_devel("toc: %lx", tramp);
  141. if (probe_kernel_read(jmp, (void *)tramp, 8)) {
  142. printk(KERN_ERR "Failed to read %lx\n", tramp);
  143. return -EFAULT;
  144. }
  145. pr_devel(" %08x %08x\n", jmp[0], jmp[1]);
  146. ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
  147. /* This should match what was called */
  148. if (ptr != ppc_function_entry((void *)addr)) {
  149. printk(KERN_ERR "addr does not match %lx\n", ptr);
  150. return -EINVAL;
  151. }
  152. /*
  153. * We want to nop the line, but the next line is
  154. * 0xe8, 0x41, 0x00, 0x28 ld r2,40(r1)
  155. * This needs to be turned to a nop too.
  156. */
  157. if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE))
  158. return -EFAULT;
  159. if (op != 0xe8410028) {
  160. printk(KERN_ERR "Next line is not ld! (%08x)\n", op);
  161. return -EINVAL;
  162. }
  163. /*
  164. * Milton Miller pointed out that we can not blindly do nops.
  165. * If a task was preempted when calling a trace function,
  166. * the nops will remove the way to restore the TOC in r2
  167. * and the r2 TOC will get corrupted.
  168. */
  169. /*
  170. * Replace:
  171. * bl <tramp> <==== will be replaced with "b 1f"
  172. * ld r2,40(r1)
  173. * 1:
  174. */
  175. op = 0x48000008; /* b +8 */
  176. if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
  177. return -EPERM;
  178. flush_icache_range(ip, ip + 8);
  179. return 0;
  180. }
  181. #else /* !PPC64 */
  182. static int
  183. __ftrace_make_nop(struct module *mod,
  184. struct dyn_ftrace *rec, unsigned long addr)
  185. {
  186. unsigned int op;
  187. unsigned int jmp[4];
  188. unsigned long ip = rec->ip;
  189. unsigned long tramp;
  190. if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE))
  191. return -EFAULT;
  192. /* Make sure that that this is still a 24bit jump */
  193. if (!is_bl_op(op)) {
  194. printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
  195. return -EINVAL;
  196. }
  197. /* lets find where the pointer goes */
  198. tramp = find_bl_target(ip, op);
  199. /*
  200. * On PPC32 the trampoline looks like:
  201. * 0x3d, 0x60, 0x00, 0x00 lis r11,sym@ha
  202. * 0x39, 0x6b, 0x00, 0x00 addi r11,r11,sym@l
  203. * 0x7d, 0x69, 0x03, 0xa6 mtctr r11
  204. * 0x4e, 0x80, 0x04, 0x20 bctr
  205. */
  206. pr_devel("ip:%lx jumps to %lx", ip, tramp);
  207. /* Find where the trampoline jumps to */
  208. if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
  209. printk(KERN_ERR "Failed to read %lx\n", tramp);
  210. return -EFAULT;
  211. }
  212. pr_devel(" %08x %08x ", jmp[0], jmp[1]);
  213. /* verify that this is what we expect it to be */
  214. if (((jmp[0] & 0xffff0000) != 0x3d600000) ||
  215. ((jmp[1] & 0xffff0000) != 0x396b0000) ||
  216. (jmp[2] != 0x7d6903a6) ||
  217. (jmp[3] != 0x4e800420)) {
  218. printk(KERN_ERR "Not a trampoline\n");
  219. return -EINVAL;
  220. }
  221. tramp = (jmp[1] & 0xffff) |
  222. ((jmp[0] & 0xffff) << 16);
  223. if (tramp & 0x8000)
  224. tramp -= 0x10000;
  225. pr_devel(" %lx ", tramp);
  226. if (tramp != addr) {
  227. printk(KERN_ERR
  228. "Trampoline location %08lx does not match addr\n",
  229. tramp);
  230. return -EINVAL;
  231. }
  232. op = PPC_INST_NOP;
  233. if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
  234. return -EPERM;
  235. flush_icache_range(ip, ip + 8);
  236. return 0;
  237. }
  238. #endif /* PPC64 */
  239. #endif /* CONFIG_MODULES */
  240. int ftrace_make_nop(struct module *mod,
  241. struct dyn_ftrace *rec, unsigned long addr)
  242. {
  243. unsigned long ip = rec->ip;
  244. unsigned int old, new;
  245. /*
  246. * If the calling address is more that 24 bits away,
  247. * then we had to use a trampoline to make the call.
  248. * Otherwise just update the call site.
  249. */
  250. if (test_24bit_addr(ip, addr)) {
  251. /* within range */
  252. old = ftrace_call_replace(ip, addr, 1);
  253. new = ftrace_nop_replace();
  254. return ftrace_modify_code(ip, old, new);
  255. }
  256. #ifdef CONFIG_MODULES
  257. /*
  258. * Out of range jumps are called from modules.
  259. * We should either already have a pointer to the module
  260. * or it has been passed in.
  261. */
  262. if (!rec->arch.mod) {
  263. if (!mod) {
  264. printk(KERN_ERR "No module loaded addr=%lx\n",
  265. addr);
  266. return -EFAULT;
  267. }
  268. rec->arch.mod = mod;
  269. } else if (mod) {
  270. if (mod != rec->arch.mod) {
  271. printk(KERN_ERR
  272. "Record mod %p not equal to passed in mod %p\n",
  273. rec->arch.mod, mod);
  274. return -EINVAL;
  275. }
  276. /* nothing to do if mod == rec->arch.mod */
  277. } else
  278. mod = rec->arch.mod;
  279. return __ftrace_make_nop(mod, rec, addr);
  280. #else
  281. /* We should not get here without modules */
  282. return -EINVAL;
  283. #endif /* CONFIG_MODULES */
  284. }
  285. #ifdef CONFIG_MODULES
  286. #ifdef CONFIG_PPC64
  287. static int
  288. __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  289. {
  290. unsigned int op[2];
  291. unsigned long ip = rec->ip;
  292. /* read where this goes */
  293. if (probe_kernel_read(op, (void *)ip, MCOUNT_INSN_SIZE * 2))
  294. return -EFAULT;
  295. /*
  296. * It should be pointing to two nops or
  297. * b +8; ld r2,40(r1)
  298. */
  299. if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) &&
  300. ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) {
  301. printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]);
  302. return -EINVAL;
  303. }
  304. /* If we never set up a trampoline to ftrace_caller, then bail */
  305. if (!rec->arch.mod->arch.tramp) {
  306. printk(KERN_ERR "No ftrace trampoline\n");
  307. return -EINVAL;
  308. }
  309. /* create the branch to the trampoline */
  310. op[0] = create_branch((unsigned int *)ip,
  311. rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
  312. if (!op[0]) {
  313. printk(KERN_ERR "REL24 out of range!\n");
  314. return -EINVAL;
  315. }
  316. /* ld r2,40(r1) */
  317. op[1] = 0xe8410028;
  318. pr_devel("write to %lx\n", rec->ip);
  319. if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2))
  320. return -EPERM;
  321. flush_icache_range(ip, ip + 8);
  322. return 0;
  323. }
  324. #else
  325. static int
  326. __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  327. {
  328. unsigned int op;
  329. unsigned long ip = rec->ip;
  330. /* read where this goes */
  331. if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE))
  332. return -EFAULT;
  333. /* It should be pointing to a nop */
  334. if (op != PPC_INST_NOP) {
  335. printk(KERN_ERR "Expected NOP but have %x\n", op);
  336. return -EINVAL;
  337. }
  338. /* If we never set up a trampoline to ftrace_caller, then bail */
  339. if (!rec->arch.mod->arch.tramp) {
  340. printk(KERN_ERR "No ftrace trampoline\n");
  341. return -EINVAL;
  342. }
  343. /* create the branch to the trampoline */
  344. op = create_branch((unsigned int *)ip,
  345. rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
  346. if (!op) {
  347. printk(KERN_ERR "REL24 out of range!\n");
  348. return -EINVAL;
  349. }
  350. pr_devel("write to %lx\n", rec->ip);
  351. if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
  352. return -EPERM;
  353. flush_icache_range(ip, ip + 8);
  354. return 0;
  355. }
  356. #endif /* CONFIG_PPC64 */
  357. #endif /* CONFIG_MODULES */
  358. int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  359. {
  360. unsigned long ip = rec->ip;
  361. unsigned int old, new;
  362. /*
  363. * If the calling address is more that 24 bits away,
  364. * then we had to use a trampoline to make the call.
  365. * Otherwise just update the call site.
  366. */
  367. if (test_24bit_addr(ip, addr)) {
  368. /* within range */
  369. old = ftrace_nop_replace();
  370. new = ftrace_call_replace(ip, addr, 1);
  371. return ftrace_modify_code(ip, old, new);
  372. }
  373. #ifdef CONFIG_MODULES
  374. /*
  375. * Out of range jumps are called from modules.
  376. * Being that we are converting from nop, it had better
  377. * already have a module defined.
  378. */
  379. if (!rec->arch.mod) {
  380. printk(KERN_ERR "No module loaded\n");
  381. return -EINVAL;
  382. }
  383. return __ftrace_make_call(rec, addr);
  384. #else
  385. /* We should not get here without modules */
  386. return -EINVAL;
  387. #endif /* CONFIG_MODULES */
  388. }
  389. int ftrace_update_ftrace_func(ftrace_func_t func)
  390. {
  391. unsigned long ip = (unsigned long)(&ftrace_call);
  392. unsigned int old, new;
  393. int ret;
  394. old = *(unsigned int *)&ftrace_call;
  395. new = ftrace_call_replace(ip, (unsigned long)func, 1);
  396. ret = ftrace_modify_code(ip, old, new);
  397. return ret;
  398. }
  399. int __init ftrace_dyn_arch_init(void *data)
  400. {
  401. /* caller expects data to be zero */
  402. unsigned long *p = data;
  403. *p = 0;
  404. return 0;
  405. }
  406. #endif /* CONFIG_DYNAMIC_FTRACE */
  407. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  408. #ifdef CONFIG_DYNAMIC_FTRACE
  409. extern void ftrace_graph_call(void);
  410. extern void ftrace_graph_stub(void);
  411. int ftrace_enable_ftrace_graph_caller(void)
  412. {
  413. unsigned long ip = (unsigned long)(&ftrace_graph_call);
  414. unsigned long addr = (unsigned long)(&ftrace_graph_caller);
  415. unsigned long stub = (unsigned long)(&ftrace_graph_stub);
  416. unsigned int old, new;
  417. old = ftrace_call_replace(ip, stub, 0);
  418. new = ftrace_call_replace(ip, addr, 0);
  419. return ftrace_modify_code(ip, old, new);
  420. }
  421. int ftrace_disable_ftrace_graph_caller(void)
  422. {
  423. unsigned long ip = (unsigned long)(&ftrace_graph_call);
  424. unsigned long addr = (unsigned long)(&ftrace_graph_caller);
  425. unsigned long stub = (unsigned long)(&ftrace_graph_stub);
  426. unsigned int old, new;
  427. old = ftrace_call_replace(ip, addr, 0);
  428. new = ftrace_call_replace(ip, stub, 0);
  429. return ftrace_modify_code(ip, old, new);
  430. }
  431. #endif /* CONFIG_DYNAMIC_FTRACE */
  432. #ifdef CONFIG_PPC64
  433. extern void mod_return_to_handler(void);
  434. #endif
  435. /*
  436. * Hook the return address and push it in the stack of return addrs
  437. * in current thread info.
  438. */
  439. void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
  440. {
  441. unsigned long old;
  442. int faulted;
  443. struct ftrace_graph_ent trace;
  444. unsigned long return_hooker = (unsigned long)&return_to_handler;
  445. if (unlikely(atomic_read(&current->tracing_graph_pause)))
  446. return;
  447. #ifdef CONFIG_PPC64
  448. /* non core kernel code needs to save and restore the TOC */
  449. if (REGION_ID(self_addr) != KERNEL_REGION_ID)
  450. return_hooker = (unsigned long)&mod_return_to_handler;
  451. #endif
  452. return_hooker = ppc_function_entry((void *)return_hooker);
  453. /*
  454. * Protect against fault, even if it shouldn't
  455. * happen. This tool is too much intrusive to
  456. * ignore such a protection.
  457. */
  458. asm volatile(
  459. "1: " PPC_LL "%[old], 0(%[parent])\n"
  460. "2: " PPC_STL "%[return_hooker], 0(%[parent])\n"
  461. " li %[faulted], 0\n"
  462. "3:\n"
  463. ".section .fixup, \"ax\"\n"
  464. "4: li %[faulted], 1\n"
  465. " b 3b\n"
  466. ".previous\n"
  467. ".section __ex_table,\"a\"\n"
  468. PPC_LONG_ALIGN "\n"
  469. PPC_LONG "1b,4b\n"
  470. PPC_LONG "2b,4b\n"
  471. ".previous"
  472. : [old] "=&r" (old), [faulted] "=r" (faulted)
  473. : [parent] "r" (parent), [return_hooker] "r" (return_hooker)
  474. : "memory"
  475. );
  476. if (unlikely(faulted)) {
  477. ftrace_graph_stop();
  478. WARN_ON(1);
  479. return;
  480. }
  481. if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
  482. *parent = old;
  483. return;
  484. }
  485. trace.func = self_addr;
  486. /* Only trace if the calling function expects to */
  487. if (!ftrace_graph_entry(&trace)) {
  488. current->curr_ret_stack--;
  489. *parent = old;
  490. }
  491. }
  492. #endif /* CONFIG_FUNCTION_GRAPH_TRACER */