aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/ftrace.c')
-rw-r--r--arch/mips/kernel/ftrace.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index e363fc69aabd..68b067040d8b 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -148,6 +148,7 @@ int ftrace_disable_ftrace_graph_caller(void)
148 148
149#endif /* !CONFIG_DYNAMIC_FTRACE */ 149#endif /* !CONFIG_DYNAMIC_FTRACE */
150 150
151#ifndef KBUILD_MCOUNT_RA_ADDRESS
151#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ 152#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */
152#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ 153#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */
153#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ 154#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
@@ -201,6 +202,8 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr,
201 return 0; 202 return 0;
202} 203}
203 204
205#endif
206
204/* 207/*
205 * Hook the return address and push it in the stack of return addrs 208 * Hook the return address and push it in the stack of return addrs
206 * in current thread info. 209 * in current thread info.
@@ -218,19 +221,26 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
218 return; 221 return;
219 222
220 /* "parent" is the stack address saved the return address of the caller 223 /* "parent" is the stack address saved the return address of the caller
221 * of _mcount, for a leaf function not save the return address in the 224 * of _mcount.
222 * stack address, so, we "emulate" one in _mcount's stack space, and 225 *
223 * hijack it directly, but for a non-leaf function, it will save the 226 * if the gcc < 4.5, a leaf function does not save the return address
224 * return address to the its stack space, so, we can not hijack the 227 * in the stack address, so, we "emulate" one in _mcount's stack space,
225 * "parent" directly, but need to find the real stack address, 228 * and hijack it directly, but for a non-leaf function, it save the
229 * return address to the its own stack space, we can not hijack it
230 * directly, but need to find the real stack address,
226 * ftrace_get_parent_addr() does it! 231 * ftrace_get_parent_addr() does it!
232 *
233 * if gcc>= 4.5, with the new -mmcount-ra-address option, for a
234 * non-leaf function, the location of the return address will be saved
235 * to $12 for us, and for a leaf function, only put a zero into $12. we
236 * do it in ftrace_graph_caller of mcount.S.
227 */ 237 */
228 238
229 /* old = *parent; */ 239 /* old = *parent; */
230 safe_load_stack(old, parent, faulted); 240 safe_load_stack(old, parent, faulted);
231 if (unlikely(faulted)) 241 if (unlikely(faulted))
232 goto out; 242 goto out;
233 243#ifndef KBUILD_MCOUNT_RA_ADDRESS
234 parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, 244 parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old,
235 (unsigned long)parent, 245 (unsigned long)parent,
236 fp); 246 fp);
@@ -238,7 +248,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
238 * ra, stop function graph tracer and return */ 248 * ra, stop function graph tracer and return */
239 if (parent == 0) 249 if (parent == 0)
240 goto out; 250 goto out;
241 251#endif
242 /* *parent = return_hooker; */ 252 /* *parent = return_hooker; */
243 safe_store_stack(return_hooker, parent, faulted); 253 safe_store_stack(return_hooker, parent, faulted);
244 if (unlikely(faulted)) 254 if (unlikely(faulted))