Commit 72dc43a9eb123d2742bd413c80dbeab0c588f622
Committed by
Russell King
1 parent
3b6c223b1b
Exists in
master
and in
20 other branches
ARM: 6319/1: ftrace: add Thumb-2 support to dynamic ftrace
Handle the different nop and call instructions for Thumb-2. Also, we need to adjust the recorded mcount_loc addresses because they have the lsb set. Cc: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> [recordmcount.pl change] Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 3 changed files with 36 additions and 2 deletions Side-by-side Diff
arch/arm/include/asm/ftrace.h
arch/arm/kernel/ftrace.c
... | ... | @@ -18,7 +18,11 @@ |
18 | 18 | #include <asm/cacheflush.h> |
19 | 19 | #include <asm/ftrace.h> |
20 | 20 | |
21 | +#ifdef CONFIG_THUMB2_KERNEL | |
22 | +#define NOP 0xeb04f85d /* pop.w {lr} */ | |
23 | +#else | |
21 | 24 | #define NOP 0xe8bd4000 /* pop {lr} */ |
25 | +#endif | |
22 | 26 | |
23 | 27 | #ifdef CONFIG_OLD_MCOUNT |
24 | 28 | #define OLD_MCOUNT_ADDR ((unsigned long) mcount) |
25 | 29 | |
26 | 30 | |
... | ... | @@ -56,10 +60,38 @@ |
56 | 60 | #endif |
57 | 61 | |
58 | 62 | /* construct a branch (BL) instruction to addr */ |
63 | +#ifdef CONFIG_THUMB2_KERNEL | |
59 | 64 | static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) |
60 | 65 | { |
66 | + unsigned long s, j1, j2, i1, i2, imm10, imm11; | |
67 | + unsigned long first, second; | |
61 | 68 | long offset; |
62 | 69 | |
70 | + offset = (long)addr - (long)(pc + 4); | |
71 | + if (offset < -16777216 || offset > 16777214) { | |
72 | + WARN_ON_ONCE(1); | |
73 | + return 0; | |
74 | + } | |
75 | + | |
76 | + s = (offset >> 24) & 0x1; | |
77 | + i1 = (offset >> 23) & 0x1; | |
78 | + i2 = (offset >> 22) & 0x1; | |
79 | + imm10 = (offset >> 12) & 0x3ff; | |
80 | + imm11 = (offset >> 1) & 0x7ff; | |
81 | + | |
82 | + j1 = (!i1) ^ s; | |
83 | + j2 = (!i2) ^ s; | |
84 | + | |
85 | + first = 0xf000 | (s << 10) | imm10; | |
86 | + second = 0xd000 | (j1 << 13) | (j2 << 11) | imm11; | |
87 | + | |
88 | + return (second << 16) | first; | |
89 | +} | |
90 | +#else | |
91 | +static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | |
92 | +{ | |
93 | + long offset; | |
94 | + | |
63 | 95 | offset = (long)addr - (long)(pc + 8); |
64 | 96 | if (unlikely(offset < -33554432 || offset > 33554428)) { |
65 | 97 | /* Can't generate branches that far (from ARM ARM). Ftrace |
... | ... | @@ -73,6 +105,7 @@ |
73 | 105 | |
74 | 106 | return 0xeb000000 | offset; |
75 | 107 | } |
108 | +#endif | |
76 | 109 | |
77 | 110 | static int ftrace_modify_code(unsigned long pc, unsigned long old, |
78 | 111 | unsigned long new) |
scripts/recordmcount.pl
... | ... | @@ -270,7 +270,7 @@ |
270 | 270 | } elsif ($arch eq "arm") { |
271 | 271 | $alignment = 2; |
272 | 272 | $section_type = '%progbits'; |
273 | - $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24)" . | |
273 | + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" . | |
274 | 274 | "\\s+(__gnu_mcount_nc|mcount)\$"; |
275 | 275 | |
276 | 276 | } elsif ($arch eq "ia64") { |