aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/ftrace.c2
-rw-r--r--arch/x86/kernel/ftrace.c2
-rw-r--r--include/linux/ftrace.h4
-rw-r--r--kernel/trace/ftrace.c38
4 files changed, 34 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 390311c0f03d..e66af6d265e8 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -449,7 +449,7 @@ void ftrace_replace_code(int enable)
449 rec = ftrace_rec_iter_record(iter); 449 rec = ftrace_rec_iter_record(iter);
450 ret = __ftrace_replace_code(rec, enable); 450 ret = __ftrace_replace_code(rec, enable);
451 if (ret) { 451 if (ret) {
452 ftrace_bug(ret, rec->ip); 452 ftrace_bug(ret, rec);
453 return; 453 return;
454 } 454 }
455 } 455 }
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 4cfeca6ffe11..1aea94d336c7 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -583,7 +583,7 @@ void ftrace_replace_code(int enable)
583 583
584 remove_breakpoints: 584 remove_breakpoints:
585 pr_warn("Failed on %s (%d):\n", report, count); 585 pr_warn("Failed on %s (%d):\n", report, count);
586 ftrace_bug(ret, rec ? rec->ip : 0); 586 ftrace_bug(ret, rec);
587 for_ftrace_rec_iter(iter) { 587 for_ftrace_rec_iter(iter) {
588 rec = ftrace_rec_iter_record(iter); 588 rec = ftrace_rec_iter_record(iter);
589 /* 589 /*
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 06e3ca5a5083..619e37cc17fd 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -263,7 +263,9 @@ struct ftrace_func_command {
263int ftrace_arch_code_modify_prepare(void); 263int ftrace_arch_code_modify_prepare(void);
264int ftrace_arch_code_modify_post_process(void); 264int ftrace_arch_code_modify_post_process(void);
265 265
266void ftrace_bug(int err, unsigned long ip); 266struct dyn_ftrace;
267
268void ftrace_bug(int err, struct dyn_ftrace *rec);
267 269
268struct seq_file; 270struct seq_file;
269 271
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index eab3123a1fbe..4043332f6720 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1738,10 +1738,13 @@ static void print_ip_ins(const char *fmt, unsigned char *p)
1738 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); 1738 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
1739} 1739}
1740 1740
1741static struct ftrace_ops *
1742ftrace_find_tramp_ops_any(struct dyn_ftrace *rec);
1743
1741/** 1744/**
1742 * ftrace_bug - report and shutdown function tracer 1745 * ftrace_bug - report and shutdown function tracer
1743 * @failed: The failed type (EFAULT, EINVAL, EPERM) 1746 * @failed: The failed type (EFAULT, EINVAL, EPERM)
1744 * @ip: The address that failed 1747 * @rec: The record that failed
1745 * 1748 *
1746 * The arch code that enables or disables the function tracing 1749 * The arch code that enables or disables the function tracing
1747 * can call ftrace_bug() when it has detected a problem in 1750 * can call ftrace_bug() when it has detected a problem in
@@ -1750,8 +1753,10 @@ static void print_ip_ins(const char *fmt, unsigned char *p)
1750 * EINVAL - if what is read at @ip is not what was expected 1753 * EINVAL - if what is read at @ip is not what was expected
1751 * EPERM - if the problem happens on writting to the @ip address 1754 * EPERM - if the problem happens on writting to the @ip address
1752 */ 1755 */
1753void ftrace_bug(int failed, unsigned long ip) 1756void ftrace_bug(int failed, struct dyn_ftrace *rec)
1754{ 1757{
1758 unsigned long ip = rec ? rec->ip : 0;
1759
1755 switch (failed) { 1760 switch (failed) {
1756 case -EFAULT: 1761 case -EFAULT:
1757 FTRACE_WARN_ON_ONCE(1); 1762 FTRACE_WARN_ON_ONCE(1);
@@ -1763,7 +1768,7 @@ void ftrace_bug(int failed, unsigned long ip)
1763 pr_info("ftrace failed to modify "); 1768 pr_info("ftrace failed to modify ");
1764 print_ip_sym(ip); 1769 print_ip_sym(ip);
1765 print_ip_ins(" actual: ", (unsigned char *)ip); 1770 print_ip_ins(" actual: ", (unsigned char *)ip);
1766 printk(KERN_CONT "\n"); 1771 pr_cont("\n");
1767 break; 1772 break;
1768 case -EPERM: 1773 case -EPERM:
1769 FTRACE_WARN_ON_ONCE(1); 1774 FTRACE_WARN_ON_ONCE(1);
@@ -1775,6 +1780,24 @@ void ftrace_bug(int failed, unsigned long ip)
1775 pr_info("ftrace faulted on unknown error "); 1780 pr_info("ftrace faulted on unknown error ");
1776 print_ip_sym(ip); 1781 print_ip_sym(ip);
1777 } 1782 }
1783 if (rec) {
1784 struct ftrace_ops *ops = NULL;
1785
1786 pr_info("ftrace record flags: %lx\n", rec->flags);
1787 pr_cont(" (%ld)%s", ftrace_rec_count(rec),
1788 rec->flags & FTRACE_FL_REGS ? " R" : " ");
1789 if (rec->flags & FTRACE_FL_TRAMP_EN) {
1790 ops = ftrace_find_tramp_ops_any(rec);
1791 if (ops)
1792 pr_cont("\ttramp: %pS",
1793 (void *)ops->trampoline);
1794 else
1795 pr_cont("\ttramp: ERROR!");
1796
1797 }
1798 ip = ftrace_get_addr_curr(rec);
1799 pr_cont(" expected tramp: %lx\n", ip);
1800 }
1778} 1801}
1779 1802
1780static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) 1803static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update)
@@ -2097,7 +2120,7 @@ void __weak ftrace_replace_code(int enable)
2097 do_for_each_ftrace_rec(pg, rec) { 2120 do_for_each_ftrace_rec(pg, rec) {
2098 failed = __ftrace_replace_code(rec, enable); 2121 failed = __ftrace_replace_code(rec, enable);
2099 if (failed) { 2122 if (failed) {
2100 ftrace_bug(failed, rec->ip); 2123 ftrace_bug(failed, rec);
2101 /* Stop processing */ 2124 /* Stop processing */
2102 return; 2125 return;
2103 } 2126 }
@@ -2179,17 +2202,14 @@ struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter)
2179static int 2202static int
2180ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) 2203ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
2181{ 2204{
2182 unsigned long ip;
2183 int ret; 2205 int ret;
2184 2206
2185 ip = rec->ip;
2186
2187 if (unlikely(ftrace_disabled)) 2207 if (unlikely(ftrace_disabled))
2188 return 0; 2208 return 0;
2189 2209
2190 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR); 2210 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
2191 if (ret) { 2211 if (ret) {
2192 ftrace_bug(ret, ip); 2212 ftrace_bug(ret, rec);
2193 return 0; 2213 return 0;
2194 } 2214 }
2195 return 1; 2215 return 1;
@@ -2633,7 +2653,7 @@ static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs)
2633 if (ftrace_start_up && cnt) { 2653 if (ftrace_start_up && cnt) {
2634 int failed = __ftrace_replace_code(p, 1); 2654 int failed = __ftrace_replace_code(p, 1);
2635 if (failed) 2655 if (failed)
2636 ftrace_bug(failed, p->ip); 2656 ftrace_bug(failed, p);
2637 } 2657 }
2638 } 2658 }
2639 } 2659 }