aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/entry-common.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/entry-common.S')
-rw-r--r--arch/arm/kernel/entry-common.S67
1 files changed, 55 insertions, 12 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index f05a35a59694..2d23ad985180 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -48,6 +48,8 @@ work_pending:
48 beq no_work_pending 48 beq no_work_pending
49 mov r0, sp @ 'regs' 49 mov r0, sp @ 'regs'
50 mov r2, why @ 'syscall' 50 mov r2, why @ 'syscall'
51 tst r1, #_TIF_SIGPENDING @ delivering a signal?
52 movne why, #0 @ prevent further restarts
51 bl do_notify_resume 53 bl do_notify_resume
52 b ret_slow_syscall @ Check work again 54 b ret_slow_syscall @ Check work again
53 55
@@ -127,30 +129,58 @@ ENDPROC(ret_from_fork)
127 * clobber the ip register. This is OK because the ARM calling convention 129 * 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 130 * allows it to be clobbered in subroutines and doesn't use it to hold
129 * parameters.) 131 * parameters.)
132 *
133 * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
134 * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
135 * arch/arm/kernel/ftrace.c).
130 */ 136 */
137
138#ifndef CONFIG_OLD_MCOUNT
139#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
140#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
141#endif
142#endif
143
131#ifdef CONFIG_DYNAMIC_FTRACE 144#ifdef CONFIG_DYNAMIC_FTRACE
132ENTRY(mcount) 145ENTRY(__gnu_mcount_nc)
146 mov ip, lr
147 ldmia sp!, {lr}
148 mov pc, ip
149ENDPROC(__gnu_mcount_nc)
150
151ENTRY(ftrace_caller)
133 stmdb sp!, {r0-r3, lr} 152 stmdb sp!, {r0-r3, lr}
134 mov r0, lr 153 mov r0, lr
135 sub r0, r0, #MCOUNT_INSN_SIZE 154 sub r0, r0, #MCOUNT_INSN_SIZE
155 ldr r1, [sp, #20]
136 156
137 .globl mcount_call 157 .global ftrace_call
138mcount_call: 158ftrace_call:
139 bl ftrace_stub 159 bl ftrace_stub
140 ldr lr, [fp, #-4] @ restore lr 160 ldmia sp!, {r0-r3, ip, lr}
141 ldmia sp!, {r0-r3, pc} 161 mov pc, ip
162ENDPROC(ftrace_caller)
142 163
143ENTRY(ftrace_caller) 164#ifdef CONFIG_OLD_MCOUNT
165ENTRY(mcount)
166 stmdb sp!, {lr}
167 ldr lr, [fp, #-4]
168 ldmia sp!, {pc}
169ENDPROC(mcount)
170
171ENTRY(ftrace_caller_old)
144 stmdb sp!, {r0-r3, lr} 172 stmdb sp!, {r0-r3, lr}
145 ldr r1, [fp, #-4] 173 ldr r1, [fp, #-4]
146 mov r0, lr 174 mov r0, lr
147 sub r0, r0, #MCOUNT_INSN_SIZE 175 sub r0, r0, #MCOUNT_INSN_SIZE
148 176
149 .globl ftrace_call 177 .globl ftrace_call_old
150ftrace_call: 178ftrace_call_old:
151 bl ftrace_stub 179 bl ftrace_stub
152 ldr lr, [fp, #-4] @ restore lr 180 ldr lr, [fp, #-4] @ restore lr
153 ldmia sp!, {r0-r3, pc} 181 ldmia sp!, {r0-r3, pc}
182ENDPROC(ftrace_caller_old)
183#endif
154 184
155#else 185#else
156 186
@@ -158,7 +188,7 @@ ENTRY(__gnu_mcount_nc)
158 stmdb sp!, {r0-r3, lr} 188 stmdb sp!, {r0-r3, lr}
159 ldr r0, =ftrace_trace_function 189 ldr r0, =ftrace_trace_function
160 ldr r2, [r0] 190 ldr r2, [r0]
161 adr r0, ftrace_stub 191 adr r0, .Lftrace_stub
162 cmp r0, r2 192 cmp r0, r2
163 bne gnu_trace 193 bne gnu_trace
164 ldmia sp!, {r0-r3, ip, lr} 194 ldmia sp!, {r0-r3, ip, lr}
@@ -168,11 +198,19 @@ gnu_trace:
168 ldr r1, [sp, #20] @ lr of instrumented routine 198 ldr r1, [sp, #20] @ lr of instrumented routine
169 mov r0, lr 199 mov r0, lr
170 sub r0, r0, #MCOUNT_INSN_SIZE 200 sub r0, r0, #MCOUNT_INSN_SIZE
171 mov lr, pc 201 adr lr, BSYM(1f)
172 mov pc, r2 202 mov pc, r2
2031:
173 ldmia sp!, {r0-r3, ip, lr} 204 ldmia sp!, {r0-r3, ip, lr}
174 mov pc, ip 205 mov pc, ip
206ENDPROC(__gnu_mcount_nc)
175 207
208#ifdef CONFIG_OLD_MCOUNT
209/*
210 * This is under an ifdef in order to force link-time errors for people trying
211 * to build with !FRAME_POINTER with a GCC which doesn't use the new-style
212 * mcount.
213 */
176ENTRY(mcount) 214ENTRY(mcount)
177 stmdb sp!, {r0-r3, lr} 215 stmdb sp!, {r0-r3, lr}
178 ldr r0, =ftrace_trace_function 216 ldr r0, =ftrace_trace_function
@@ -191,12 +229,15 @@ trace:
191 mov pc, r2 229 mov pc, r2
192 ldr lr, [fp, #-4] @ restore lr 230 ldr lr, [fp, #-4] @ restore lr
193 ldmia sp!, {r0-r3, pc} 231 ldmia sp!, {r0-r3, pc}
232ENDPROC(mcount)
233#endif
194 234
195#endif /* CONFIG_DYNAMIC_FTRACE */ 235#endif /* CONFIG_DYNAMIC_FTRACE */
196 236
197 .globl ftrace_stub 237ENTRY(ftrace_stub)
198ftrace_stub: 238.Lftrace_stub:
199 mov pc, lr 239 mov pc, lr
240ENDPROC(ftrace_stub)
200 241
201#endif /* CONFIG_FUNCTION_TRACER */ 242#endif /* CONFIG_FUNCTION_TRACER */
202 243
@@ -418,11 +459,13 @@ ENDPROC(sys_clone_wrapper)
418 459
419sys_sigreturn_wrapper: 460sys_sigreturn_wrapper:
420 add r0, sp, #S_OFF 461 add r0, sp, #S_OFF
462 mov why, #0 @ prevent syscall restart handling
421 b sys_sigreturn 463 b sys_sigreturn
422ENDPROC(sys_sigreturn_wrapper) 464ENDPROC(sys_sigreturn_wrapper)
423 465
424sys_rt_sigreturn_wrapper: 466sys_rt_sigreturn_wrapper:
425 add r0, sp, #S_OFF 467 add r0, sp, #S_OFF
468 mov why, #0 @ prevent syscall restart handling
426 b sys_rt_sigreturn 469 b sys_rt_sigreturn
427ENDPROC(sys_rt_sigreturn_wrapper) 470ENDPROC(sys_rt_sigreturn_wrapper)
428 471