aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/ftrace.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 3160254f6c7e..d5bd21f39524 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -348,6 +348,47 @@ ftrace_record_ip(unsigned long ip)
348 return rec; 348 return rec;
349} 349}
350 350
351static void print_ip_ins(const char *fmt, unsigned char *p)
352{
353 int i;
354
355 printk(KERN_CONT "%s", fmt);
356
357 for (i = 0; i < MCOUNT_INSN_SIZE; i++)
358 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
359}
360
361static void ftrace_bug(int failed, unsigned long ip,
362 unsigned char *expected,
363 unsigned char *replace)
364{
365 switch (failed) {
366 case -EFAULT:
367 FTRACE_WARN_ON_ONCE(1);
368 pr_info("ftrace faulted on modifying ");
369 print_ip_sym(ip);
370 break;
371 case -EINVAL:
372 FTRACE_WARN_ON_ONCE(1);
373 pr_info("ftrace failed to modify ");
374 print_ip_sym(ip);
375 print_ip_ins(" expected: ", expected);
376 print_ip_ins(" actual: ", (unsigned char *)ip);
377 print_ip_ins(" replace: ", replace);
378 printk(KERN_CONT "\n");
379 break;
380 case -EPERM:
381 FTRACE_WARN_ON_ONCE(1);
382 pr_info("ftrace faulted on writing ");
383 print_ip_sym(ip);
384 break;
385 default:
386 FTRACE_WARN_ON_ONCE(1);
387 pr_info("ftrace faulted on unknown error ");
388 print_ip_sym(ip);
389 }
390}
391
351#define FTRACE_ADDR ((long)(ftrace_caller)) 392#define FTRACE_ADDR ((long)(ftrace_caller))
352 393
353static int 394static int
@@ -465,22 +506,13 @@ static void ftrace_replace_code(int enable)
465 if ((system_state == SYSTEM_BOOTING) || 506 if ((system_state == SYSTEM_BOOTING) ||
466 !core_kernel_text(rec->ip)) { 507 !core_kernel_text(rec->ip)) {
467 ftrace_free_rec(rec); 508 ftrace_free_rec(rec);
468 } 509 } else
510 ftrace_bug(failed, rec->ip, old, new);
469 } 511 }
470 } 512 }
471 } 513 }
472} 514}
473 515
474static void print_ip_ins(const char *fmt, unsigned char *p)
475{
476 int i;
477
478 printk(KERN_CONT "%s", fmt);
479
480 for (i = 0; i < MCOUNT_INSN_SIZE; i++)
481 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
482}
483
484static int 516static int
485ftrace_code_disable(struct dyn_ftrace *rec) 517ftrace_code_disable(struct dyn_ftrace *rec)
486{ 518{
@@ -495,32 +527,7 @@ ftrace_code_disable(struct dyn_ftrace *rec)
495 527
496 ret = ftrace_modify_code(ip, call, nop); 528 ret = ftrace_modify_code(ip, call, nop);
497 if (ret) { 529 if (ret) {
498 switch (ret) { 530 ftrace_bug(ret, ip, call, nop);
499 case -EFAULT:
500 FTRACE_WARN_ON_ONCE(1);
501 pr_info("ftrace faulted on modifying ");
502 print_ip_sym(ip);
503 break;
504 case -EINVAL:
505 FTRACE_WARN_ON_ONCE(1);
506 pr_info("ftrace failed to modify ");
507 print_ip_sym(ip);
508 print_ip_ins(" expected: ", call);
509 print_ip_ins(" actual: ", (unsigned char *)ip);
510 print_ip_ins(" replace: ", nop);
511 printk(KERN_CONT "\n");
512 break;
513 case -EPERM:
514 FTRACE_WARN_ON_ONCE(1);
515 pr_info("ftrace faulted on writing ");
516 print_ip_sym(ip);
517 break;
518 default:
519 FTRACE_WARN_ON_ONCE(1);
520 pr_info("ftrace faulted on unknown error ");
521 print_ip_sym(ip);
522 }
523
524 rec->flags |= FTRACE_FL_FAILED; 531 rec->flags |= FTRACE_FL_FAILED;
525 return 0; 532 return 0;
526 } 533 }