6 #include <linux/list.h>
9 #include <asm/ftrace.h>
11 #ifdef CONFIG_DYNAMIC_FTRACE
12 static const u32 ftrace_nop = 0x01000000;
14 static u32 ftrace_call_replace(
unsigned long ip,
unsigned long addr)
20 call = 0x40000000 | ((
u32)off >> 2);
25 static int ftrace_modify_code(
unsigned long ip,
u32 old,
u32 new)
31 "1: cas [%[ip]], %[old], %[new]\n"
33 " mov 0, %[faulted]\n"
35 " .section .fixup,#alloc,#execinstr\n"
37 "3: sethi %%hi(2b), %[faulted]\n"
38 " jmpl %[faulted] + %%lo(2b), %%g0\n"
39 " mov 1, %[faulted]\n"
41 " .section __ex_table,\"a\"\n"
45 :
"=r" (replaced), [faulted]
"=r" (faulted)
46 : [
new]
"0" (
new), [old]
"r" (old), [ip]
"r" (ip)
49 if (replaced != old && replaced !=
new)
57 unsigned long ip = rec->ip;
60 old = ftrace_call_replace(ip, addr);
62 return ftrace_modify_code(ip, old,
new);
67 unsigned long ip = rec->ip;
71 new = ftrace_call_replace(ip, addr);
72 return ftrace_modify_code(ip, old,
new);
77 unsigned long ip = (
unsigned long)(&ftrace_call);
80 old = *(
u32 *) &ftrace_call;
81 new = ftrace_call_replace(ip, (
unsigned long)func);
82 return ftrace_modify_code(ip, old,
new);
87 unsigned long *
p =
data;
95 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
97 #ifdef CONFIG_DYNAMIC_FTRACE
98 extern void ftrace_graph_call(
void);
100 int ftrace_enable_ftrace_graph_caller(
void)
102 unsigned long ip = (
unsigned long)(&ftrace_graph_call);
105 old = *(
u32 *) &ftrace_graph_call;
106 new = ftrace_call_replace(ip, (
unsigned long) &ftrace_graph_caller);
107 return ftrace_modify_code(ip, old,
new);
110 int ftrace_disable_ftrace_graph_caller(
void)
112 unsigned long ip = (
unsigned long)(&ftrace_graph_call);
115 old = *(
u32 *) &ftrace_graph_call;
116 new = ftrace_call_replace(ip, (
unsigned long) &ftrace_stub);
118 return ftrace_modify_code(ip, old,
new);
127 unsigned long prepare_ftrace_return(
unsigned long parent,
128 unsigned long self_addr,
129 unsigned long frame_pointer)
138 frame_pointer) == -
EBUSY)
141 trace.func = self_addr;
144 if (!ftrace_graph_entry(&
trace)) {
149 return return_hooker;