diff options
Diffstat (limited to 'arch/x86/kernel/ftrace.c')
-rw-r--r-- | arch/x86/kernel/ftrace.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index b69795efa226..9f44623e0072 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -109,10 +109,49 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, | |||
109 | return faulted; | 109 | return faulted; |
110 | } | 110 | } |
111 | 111 | ||
112 | int __init ftrace_dyn_arch_init(void) | 112 | notrace int ftrace_update_ftrace_func(ftrace_func_t func) |
113 | { | ||
114 | unsigned long ip = (unsigned long)(&ftrace_call); | ||
115 | unsigned char old[5], *new; | ||
116 | int ret; | ||
117 | |||
118 | ip += CALL_BACK; | ||
119 | |||
120 | memcpy(old, &ftrace_call, 5); | ||
121 | new = ftrace_call_replace(ip, (unsigned long)func); | ||
122 | ret = ftrace_modify_code(ip, old, new); | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | notrace int ftrace_mcount_set(unsigned long *data) | ||
128 | { | ||
129 | unsigned long ip = (long)(&mcount_call); | ||
130 | unsigned long *addr = data; | ||
131 | unsigned char old[5], *new; | ||
132 | |||
133 | /* ip is at the location, but modify code will subtact this */ | ||
134 | ip += CALL_BACK; | ||
135 | |||
136 | /* | ||
137 | * Replace the mcount stub with a pointer to the | ||
138 | * ip recorder function. | ||
139 | */ | ||
140 | memcpy(old, &mcount_call, 5); | ||
141 | new = ftrace_call_replace(ip, *addr); | ||
142 | *addr = ftrace_modify_code(ip, old, new); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | int __init ftrace_dyn_arch_init(void *data) | ||
113 | { | 148 | { |
114 | const unsigned char *const *noptable = find_nop_table(); | 149 | const unsigned char *const *noptable = find_nop_table(); |
115 | 150 | ||
151 | /* This is running in kstop_machine */ | ||
152 | |||
153 | ftrace_mcount_set(data); | ||
154 | |||
116 | ftrace_nop = (unsigned long *)noptable[CALL_BACK]; | 155 | ftrace_nop = (unsigned long *)noptable[CALL_BACK]; |
117 | 156 | ||
118 | return 0; | 157 | return 0; |