diff options
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/trace_ksym.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index c538b15b95d6..ddfa0fd43bc0 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c | |||
| @@ -42,9 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | struct trace_ksym { | 43 | struct trace_ksym { |
| 44 | struct perf_event **ksym_hbp; | 44 | struct perf_event **ksym_hbp; |
| 45 | unsigned long ksym_addr; | 45 | struct perf_event_attr attr; |
| 46 | int type; | ||
| 47 | int len; | ||
| 48 | #ifdef CONFIG_PROFILE_KSYM_TRACER | 46 | #ifdef CONFIG_PROFILE_KSYM_TRACER |
| 49 | unsigned long counter; | 47 | unsigned long counter; |
| 50 | #endif | 48 | #endif |
| @@ -71,7 +69,7 @@ void ksym_collect_stats(unsigned long hbp_hit_addr) | |||
| 71 | 69 | ||
| 72 | rcu_read_lock(); | 70 | rcu_read_lock(); |
| 73 | hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) { | 71 | hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) { |
| 74 | if ((entry->ksym_addr == hbp_hit_addr) && | 72 | if ((entry->attr.bp_addr == hbp_hit_addr) && |
| 75 | (entry->counter <= MAX_UL_INT)) { | 73 | (entry->counter <= MAX_UL_INT)) { |
| 76 | entry->counter++; | 74 | entry->counter++; |
| 77 | break; | 75 | break; |
| @@ -192,14 +190,15 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr) | |||
| 192 | if (!entry) | 190 | if (!entry) |
| 193 | return -ENOMEM; | 191 | return -ENOMEM; |
| 194 | 192 | ||
| 195 | entry->type = op; | 193 | hw_breakpoint_init(&entry->attr); |
| 196 | entry->ksym_addr = addr; | 194 | |
| 197 | entry->len = HW_BREAKPOINT_LEN_4; | 195 | entry->attr.bp_type = op; |
| 196 | entry->attr.bp_addr = addr; | ||
| 197 | entry->attr.bp_len = HW_BREAKPOINT_LEN_4; | ||
| 198 | 198 | ||
| 199 | ret = -EAGAIN; | 199 | ret = -EAGAIN; |
| 200 | entry->ksym_hbp = register_wide_hw_breakpoint(entry->ksym_addr, | 200 | entry->ksym_hbp = register_wide_hw_breakpoint(&entry->attr, |
| 201 | entry->len, entry->type, | 201 | ksym_hbp_handler); |
| 202 | ksym_hbp_handler, true); | ||
| 203 | 202 | ||
| 204 | if (IS_ERR(entry->ksym_hbp)) { | 203 | if (IS_ERR(entry->ksym_hbp)) { |
| 205 | ret = PTR_ERR(entry->ksym_hbp); | 204 | ret = PTR_ERR(entry->ksym_hbp); |
| @@ -236,12 +235,12 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf, | |||
| 236 | mutex_lock(&ksym_tracer_mutex); | 235 | mutex_lock(&ksym_tracer_mutex); |
| 237 | 236 | ||
| 238 | hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { | 237 | hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { |
| 239 | ret = trace_seq_printf(s, "%pS:", (void *)entry->ksym_addr); | 238 | ret = trace_seq_printf(s, "%pS:", (void *)entry->attr.bp_addr); |
| 240 | if (entry->type == HW_BREAKPOINT_R) | 239 | if (entry->attr.bp_type == HW_BREAKPOINT_R) |
| 241 | ret = trace_seq_puts(s, "r--\n"); | 240 | ret = trace_seq_puts(s, "r--\n"); |
| 242 | else if (entry->type == HW_BREAKPOINT_W) | 241 | else if (entry->attr.bp_type == HW_BREAKPOINT_W) |
| 243 | ret = trace_seq_puts(s, "-w-\n"); | 242 | ret = trace_seq_puts(s, "-w-\n"); |
| 244 | else if (entry->type == (HW_BREAKPOINT_W | HW_BREAKPOINT_R)) | 243 | else if (entry->attr.bp_type == (HW_BREAKPOINT_W | HW_BREAKPOINT_R)) |
| 245 | ret = trace_seq_puts(s, "rw-\n"); | 244 | ret = trace_seq_puts(s, "rw-\n"); |
| 246 | WARN_ON_ONCE(!ret); | 245 | WARN_ON_ONCE(!ret); |
| 247 | } | 246 | } |
| @@ -317,9 +316,9 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
| 317 | 316 | ||
| 318 | ret = -EINVAL; | 317 | ret = -EINVAL; |
| 319 | hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { | 318 | hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { |
| 320 | if (entry->ksym_addr == ksym_addr) { | 319 | if (entry->attr.bp_addr == ksym_addr) { |
| 321 | /* Check for malformed request: (6) */ | 320 | /* Check for malformed request: (6) */ |
| 322 | if (entry->type != op) | 321 | if (entry->attr.bp_type != op) |
| 323 | changed = 1; | 322 | changed = 1; |
| 324 | else | 323 | else |
| 325 | goto out; | 324 | goto out; |
| @@ -328,13 +327,12 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
| 328 | } | 327 | } |
| 329 | if (changed) { | 328 | if (changed) { |
| 330 | unregister_wide_hw_breakpoint(entry->ksym_hbp); | 329 | unregister_wide_hw_breakpoint(entry->ksym_hbp); |
| 331 | entry->type = op; | 330 | entry->attr.bp_type = op; |
| 332 | ret = 0; | 331 | ret = 0; |
| 333 | if (op > 0) { | 332 | if (op > 0) { |
| 334 | entry->ksym_hbp = | 333 | entry->ksym_hbp = |
| 335 | register_wide_hw_breakpoint(entry->ksym_addr, | 334 | register_wide_hw_breakpoint(&entry->attr, |
| 336 | entry->len, entry->type, | 335 | ksym_hbp_handler); |
| 337 | ksym_hbp_handler, true); | ||
| 338 | if (IS_ERR(entry->ksym_hbp)) | 336 | if (IS_ERR(entry->ksym_hbp)) |
| 339 | ret = PTR_ERR(entry->ksym_hbp); | 337 | ret = PTR_ERR(entry->ksym_hbp); |
| 340 | else | 338 | else |
| @@ -489,7 +487,7 @@ static int ksym_tracer_stat_show(struct seq_file *m, void *v) | |||
| 489 | 487 | ||
| 490 | entry = hlist_entry(stat, struct trace_ksym, ksym_hlist); | 488 | entry = hlist_entry(stat, struct trace_ksym, ksym_hlist); |
| 491 | 489 | ||
| 492 | access_type = entry->type; | 490 | access_type = entry->attr.bp_type; |
| 493 | 491 | ||
| 494 | switch (access_type) { | 492 | switch (access_type) { |
| 495 | case HW_BREAKPOINT_R: | 493 | case HW_BREAKPOINT_R: |
| @@ -505,7 +503,7 @@ static int ksym_tracer_stat_show(struct seq_file *m, void *v) | |||
| 505 | seq_puts(m, " NA "); | 503 | seq_puts(m, " NA "); |
| 506 | } | 504 | } |
| 507 | 505 | ||
| 508 | if (lookup_symbol_name(entry->ksym_addr, fn_name) >= 0) | 506 | if (lookup_symbol_name(entry->attr.bp_addr, fn_name) >= 0) |
| 509 | seq_printf(m, " %-36s", fn_name); | 507 | seq_printf(m, " %-36s", fn_name); |
| 510 | else | 508 | else |
| 511 | seq_printf(m, " %-36s", "<NA>"); | 509 | seq_printf(m, " %-36s", "<NA>"); |
