ftrace.c 12 KB

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