diff options
author | Rabin Vincent <rabin@rab.in> | 2010-08-10 14:43:28 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-09-02 10:27:40 -0400 |
commit | 3b6c223b1b97ad60bbb0f4efda57d649414ac2a2 (patch) | |
tree | 291dcb285e8cb64415a82ed1c65dc9681921a257 /arch/arm/kernel/entry-common.S | |
parent | f9810a82536e0c730c57844753e6c08cc7f77881 (diff) |
ARM: 6318/1: ftrace: fix and update dynamic ftrace
This adds mcount recording and updates dynamic ftrace for ARM to work
with the new ftrace dyamic tracing implementation. It also adds support
for the mcount format used by newer ARM compilers.
With dynamic tracing, mcount() is implemented as a nop. Callsites are
patched on startup with nops, and dynamically patched to call to the
ftrace_caller() routine as needed.
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>
Diffstat (limited to 'arch/arm/kernel/entry-common.S')
-rw-r--r-- | arch/arm/kernel/entry-common.S | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index f5e75de0203e..e02790f28879 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -127,6 +127,10 @@ ENDPROC(ret_from_fork) | |||
127 | * clobber the ip register. This is OK because the ARM calling convention | 127 | * clobber the ip register. This is OK because the ARM calling convention |
128 | * allows it to be clobbered in subroutines and doesn't use it to hold | 128 | * allows it to be clobbered in subroutines and doesn't use it to hold |
129 | * parameters.) | 129 | * parameters.) |
130 | * | ||
131 | * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0" | ||
132 | * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see | ||
133 | * arch/arm/kernel/ftrace.c). | ||
130 | */ | 134 | */ |
131 | 135 | ||
132 | #ifndef CONFIG_OLD_MCOUNT | 136 | #ifndef CONFIG_OLD_MCOUNT |
@@ -136,30 +140,45 @@ ENDPROC(ret_from_fork) | |||
136 | #endif | 140 | #endif |
137 | 141 | ||
138 | #ifdef CONFIG_DYNAMIC_FTRACE | 142 | #ifdef CONFIG_DYNAMIC_FTRACE |
139 | ENTRY(mcount) | 143 | ENTRY(__gnu_mcount_nc) |
144 | mov ip, lr | ||
145 | ldmia sp!, {lr} | ||
146 | mov pc, ip | ||
147 | ENDPROC(__gnu_mcount_nc) | ||
148 | |||
149 | ENTRY(ftrace_caller) | ||
140 | stmdb sp!, {r0-r3, lr} | 150 | stmdb sp!, {r0-r3, lr} |
141 | mov r0, lr | 151 | mov r0, lr |
142 | sub r0, r0, #MCOUNT_INSN_SIZE | 152 | sub r0, r0, #MCOUNT_INSN_SIZE |
153 | ldr r1, [sp, #20] | ||
143 | 154 | ||
144 | .globl mcount_call | 155 | .global ftrace_call |
145 | mcount_call: | 156 | ftrace_call: |
146 | bl ftrace_stub | 157 | bl ftrace_stub |
147 | ldr lr, [fp, #-4] @ restore lr | 158 | ldmia sp!, {r0-r3, ip, lr} |
148 | ldmia sp!, {r0-r3, pc} | 159 | mov pc, ip |
160 | ENDPROC(ftrace_caller) | ||
161 | |||
162 | #ifdef CONFIG_OLD_MCOUNT | ||
163 | ENTRY(mcount) | ||
164 | stmdb sp!, {lr} | ||
165 | ldr lr, [fp, #-4] | ||
166 | ldmia sp!, {pc} | ||
149 | ENDPROC(mcount) | 167 | ENDPROC(mcount) |
150 | 168 | ||
151 | ENTRY(ftrace_caller) | 169 | ENTRY(ftrace_caller_old) |
152 | stmdb sp!, {r0-r3, lr} | 170 | stmdb sp!, {r0-r3, lr} |
153 | ldr r1, [fp, #-4] | 171 | ldr r1, [fp, #-4] |
154 | mov r0, lr | 172 | mov r0, lr |
155 | sub r0, r0, #MCOUNT_INSN_SIZE | 173 | sub r0, r0, #MCOUNT_INSN_SIZE |
156 | 174 | ||
157 | .globl ftrace_call | 175 | .globl ftrace_call_old |
158 | ftrace_call: | 176 | ftrace_call_old: |
159 | bl ftrace_stub | 177 | bl ftrace_stub |
160 | ldr lr, [fp, #-4] @ restore lr | 178 | ldr lr, [fp, #-4] @ restore lr |
161 | ldmia sp!, {r0-r3, pc} | 179 | ldmia sp!, {r0-r3, pc} |
162 | ENDPROC(ftrace_caller) | 180 | ENDPROC(ftrace_caller_old) |
181 | #endif | ||
163 | 182 | ||
164 | #else | 183 | #else |
165 | 184 | ||