aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_ksym.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_ksym.c')
-rw-r--r--kernel/trace/trace_ksym.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
index ddfa0fd43bc0..faf37fa4408c 100644
--- a/kernel/trace/trace_ksym.c
+++ b/kernel/trace/trace_ksym.c
@@ -79,11 +79,12 @@ void ksym_collect_stats(unsigned long hbp_hit_addr)
79} 79}
80#endif /* CONFIG_PROFILE_KSYM_TRACER */ 80#endif /* CONFIG_PROFILE_KSYM_TRACER */
81 81
82void ksym_hbp_handler(struct perf_event *hbp, void *data) 82void ksym_hbp_handler(struct perf_event *hbp, int nmi,
83 struct perf_sample_data *data,
84 struct pt_regs *regs)
83{ 85{
84 struct ring_buffer_event *event; 86 struct ring_buffer_event *event;
85 struct ksym_trace_entry *entry; 87 struct ksym_trace_entry *entry;
86 struct pt_regs *regs = data;
87 struct ring_buffer *buffer; 88 struct ring_buffer *buffer;
88 int pc; 89 int pc;
89 90
@@ -235,7 +236,8 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf,
235 mutex_lock(&ksym_tracer_mutex); 236 mutex_lock(&ksym_tracer_mutex);
236 237
237 hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { 238 hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
238 ret = trace_seq_printf(s, "%pS:", (void *)entry->attr.bp_addr); 239 ret = trace_seq_printf(s, "%pS:",
240 (void *)(unsigned long)entry->attr.bp_addr);
239 if (entry->attr.bp_type == HW_BREAKPOINT_R) 241 if (entry->attr.bp_type == HW_BREAKPOINT_R)
240 ret = trace_seq_puts(s, "r--\n"); 242 ret = trace_seq_puts(s, "r--\n");
241 else if (entry->attr.bp_type == HW_BREAKPOINT_W) 243 else if (entry->attr.bp_type == HW_BREAKPOINT_W)
@@ -277,21 +279,20 @@ static ssize_t ksym_trace_filter_write(struct file *file,
277{ 279{
278 struct trace_ksym *entry; 280 struct trace_ksym *entry;
279 struct hlist_node *node; 281 struct hlist_node *node;
280 char *input_string, *ksymname = NULL; 282 char *buf, *input_string, *ksymname = NULL;
281 unsigned long ksym_addr = 0; 283 unsigned long ksym_addr = 0;
282 int ret, op, changed = 0; 284 int ret, op, changed = 0;
283 285
284 input_string = kzalloc(count + 1, GFP_KERNEL); 286 buf = kzalloc(count + 1, GFP_KERNEL);
285 if (!input_string) 287 if (!buf)
286 return -ENOMEM; 288 return -ENOMEM;
287 289
288 if (copy_from_user(input_string, buffer, count)) { 290 ret = -EFAULT;
289 kfree(input_string); 291 if (copy_from_user(buf, buffer, count))
290 return -EFAULT; 292 goto out;
291 }
292 input_string[count] = '\0';
293 293
294 strstrip(input_string); 294 buf[count] = '\0';
295 input_string = strstrip(buf);
295 296
296 /* 297 /*
297 * Clear all breakpoints if: 298 * Clear all breakpoints if:
@@ -299,18 +300,16 @@ static ssize_t ksym_trace_filter_write(struct file *file,
299 * 2: echo 0 > ksym_trace_filter 300 * 2: echo 0 > ksym_trace_filter
300 * 3: echo "*:---" > ksym_trace_filter 301 * 3: echo "*:---" > ksym_trace_filter
301 */ 302 */
302 if (!input_string[0] || !strcmp(input_string, "0") || 303 if (!buf[0] || !strcmp(buf, "0") ||
303 !strcmp(input_string, "*:---")) { 304 !strcmp(buf, "*:---")) {
304 __ksym_trace_reset(); 305 __ksym_trace_reset();
305 kfree(input_string); 306 ret = 0;
306 return count; 307 goto out;
307 } 308 }
308 309
309 ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); 310 ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr);
310 if (ret < 0) { 311 if (ret < 0)
311 kfree(input_string); 312 goto out;
312 return ret;
313 }
314 313
315 mutex_lock(&ksym_tracer_mutex); 314 mutex_lock(&ksym_tracer_mutex);
316 315
@@ -321,7 +320,7 @@ static ssize_t ksym_trace_filter_write(struct file *file,
321 if (entry->attr.bp_type != op) 320 if (entry->attr.bp_type != op)
322 changed = 1; 321 changed = 1;
323 else 322 else
324 goto out; 323 goto out_unlock;
325 break; 324 break;
326 } 325 }
327 } 326 }
@@ -336,28 +335,24 @@ static ssize_t ksym_trace_filter_write(struct file *file,
336 if (IS_ERR(entry->ksym_hbp)) 335 if (IS_ERR(entry->ksym_hbp))
337 ret = PTR_ERR(entry->ksym_hbp); 336 ret = PTR_ERR(entry->ksym_hbp);
338 else 337 else
339 goto out; 338 goto out_unlock;
340 } 339 }
341 /* Error or "symbol:---" case: drop it */ 340 /* Error or "symbol:---" case: drop it */
342 ksym_filter_entry_count--; 341 ksym_filter_entry_count--;
343 hlist_del_rcu(&(entry->ksym_hlist)); 342 hlist_del_rcu(&(entry->ksym_hlist));
344 synchronize_rcu(); 343 synchronize_rcu();
345 kfree(entry); 344 kfree(entry);
346 goto out; 345 goto out_unlock;
347 } else { 346 } else {
348 /* Check for malformed request: (4) */ 347 /* Check for malformed request: (4) */
349 if (op == 0) 348 if (op)
350 goto out; 349 ret = process_new_ksym_entry(ksymname, op, ksym_addr);
351 ret = process_new_ksym_entry(ksymname, op, ksym_addr);
352 } 350 }
353out: 351out_unlock:
354 mutex_unlock(&ksym_tracer_mutex); 352 mutex_unlock(&ksym_tracer_mutex);
355 353out:
356 kfree(input_string); 354 kfree(buf);
357 355 return !ret ? count : ret;
358 if (!ret)
359 ret = count;
360 return ret;
361} 356}
362 357
363static const struct file_operations ksym_tracing_fops = { 358static const struct file_operations ksym_tracing_fops = {