diff options
Diffstat (limited to 'kernel/trace/trace_ksym.c')
-rw-r--r-- | kernel/trace/trace_ksym.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index cd5cb656c3d2..2fde875ead4c 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c | |||
@@ -163,8 +163,6 @@ static int parse_ksym_trace_str(char *input_string, char **ksymname, | |||
163 | { | 163 | { |
164 | int ret; | 164 | int ret; |
165 | 165 | ||
166 | strstrip(input_string); | ||
167 | |||
168 | *ksymname = strsep(&input_string, ":"); | 166 | *ksymname = strsep(&input_string, ":"); |
169 | *addr = kallsyms_lookup_name(*ksymname); | 167 | *addr = kallsyms_lookup_name(*ksymname); |
170 | 168 | ||
@@ -262,6 +260,25 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf, | |||
262 | return cnt; | 260 | return cnt; |
263 | } | 261 | } |
264 | 262 | ||
263 | static void __ksym_trace_reset(void) | ||
264 | { | ||
265 | struct trace_ksym *entry; | ||
266 | struct hlist_node *node, *node1; | ||
267 | |||
268 | mutex_lock(&ksym_tracer_mutex); | ||
269 | hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head, | ||
270 | ksym_hlist) { | ||
271 | unregister_kernel_hw_breakpoint(entry->ksym_hbp); | ||
272 | ksym_filter_entry_count--; | ||
273 | hlist_del_rcu(&(entry->ksym_hlist)); | ||
274 | synchronize_rcu(); | ||
275 | kfree(entry->ksym_hbp->info.name); | ||
276 | kfree(entry->ksym_hbp); | ||
277 | kfree(entry); | ||
278 | } | ||
279 | mutex_unlock(&ksym_tracer_mutex); | ||
280 | } | ||
281 | |||
265 | static ssize_t ksym_trace_filter_write(struct file *file, | 282 | static ssize_t ksym_trace_filter_write(struct file *file, |
266 | const char __user *buffer, | 283 | const char __user *buffer, |
267 | size_t count, loff_t *ppos) | 284 | size_t count, loff_t *ppos) |
@@ -282,6 +299,21 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
282 | } | 299 | } |
283 | input_string[count] = '\0'; | 300 | input_string[count] = '\0'; |
284 | 301 | ||
302 | strstrip(input_string); | ||
303 | |||
304 | /* | ||
305 | * Clear all breakpoints if: | ||
306 | * 1: echo > ksym_trace_filter | ||
307 | * 2: echo 0 > ksym_trace_filter | ||
308 | * 3: echo "*:---" > ksym_trace_filter | ||
309 | */ | ||
310 | if (!input_string[0] || !strcmp(input_string, "0") || | ||
311 | !strcmp(input_string, "*:---")) { | ||
312 | __ksym_trace_reset(); | ||
313 | kfree(input_string); | ||
314 | return count; | ||
315 | } | ||
316 | |||
285 | ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); | 317 | ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); |
286 | if (ret < 0) { | 318 | if (ret < 0) { |
287 | kfree(input_string); | 319 | kfree(input_string); |
@@ -341,23 +373,8 @@ static const struct file_operations ksym_tracing_fops = { | |||
341 | 373 | ||
342 | static void ksym_trace_reset(struct trace_array *tr) | 374 | static void ksym_trace_reset(struct trace_array *tr) |
343 | { | 375 | { |
344 | struct trace_ksym *entry; | ||
345 | struct hlist_node *node, *node1; | ||
346 | |||
347 | ksym_tracing_enabled = 0; | 376 | ksym_tracing_enabled = 0; |
348 | 377 | __ksym_trace_reset(); | |
349 | mutex_lock(&ksym_tracer_mutex); | ||
350 | hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head, | ||
351 | ksym_hlist) { | ||
352 | unregister_kernel_hw_breakpoint(entry->ksym_hbp); | ||
353 | ksym_filter_entry_count--; | ||
354 | hlist_del_rcu(&(entry->ksym_hlist)); | ||
355 | synchronize_rcu(); | ||
356 | kfree(entry->ksym_hbp->info.name); | ||
357 | kfree(entry->ksym_hbp); | ||
358 | kfree(entry); | ||
359 | } | ||
360 | mutex_unlock(&ksym_tracer_mutex); | ||
361 | } | 378 | } |
362 | 379 | ||
363 | static int ksym_trace_init(struct trace_array *tr) | 380 | static int ksym_trace_init(struct trace_array *tr) |