aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/mm/maccess.c4
-rw-r--r--arch/s390/mm/maccess.c4
-rw-r--r--arch/x86/kernel/ftrace.c12
-rw-r--r--arch/x86/oprofile/op_model_amd.c95
-rw-r--r--drivers/oprofile/event_buffer.h2
-rw-r--r--drivers/oprofile/oprof.c2
-rw-r--r--include/linux/ftrace_event.h12
-rw-r--r--include/linux/sched.h2
-rw-r--r--include/linux/uaccess.h8
-rw-r--r--include/trace/events/btrfs.h4
-rw-r--r--include/trace/ftrace.h13
-rw-r--r--kernel/events/core.c8
-rw-r--r--kernel/jump_label.c18
-rw-r--r--kernel/trace/ftrace.c31
-rw-r--r--kernel/trace/ring_buffer.c10
-rw-r--r--kernel/trace/trace.h15
-rw-r--r--kernel/trace/trace_events.c7
-rw-r--r--kernel/trace/trace_output.c27
-rw-r--r--kernel/watchdog.c9
-rw-r--r--mm/maccess.c8
-rw-r--r--scripts/recordmcount.h8
-rwxr-xr-xscripts/tags.sh6
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-record.c10
-rw-r--r--tools/perf/builtin-report.c23
-rw-r--r--tools/perf/builtin-script.c1
-rw-r--r--tools/perf/builtin-top.c37
-rw-r--r--tools/perf/util/event.c15
-rw-r--r--tools/perf/util/evsel.c10
-rw-r--r--tools/perf/util/header.c8
-rw-r--r--tools/perf/util/include/linux/const.h1
-rw-r--r--tools/perf/util/symbol.c48
-rw-r--r--tools/perf/util/symbol.h3
34 files changed, 359 insertions, 106 deletions
diff --git a/arch/blackfin/mm/maccess.c b/arch/blackfin/mm/maccess.c
index b71cebc1f8a3..e2532114c5fd 100644
--- a/arch/blackfin/mm/maccess.c
+++ b/arch/blackfin/mm/maccess.c
@@ -16,7 +16,7 @@ static int validate_memory_access_address(unsigned long addr, int size)
16 return bfin_mem_access_type(addr, size); 16 return bfin_mem_access_type(addr, size);
17} 17}
18 18
19long probe_kernel_read(void *dst, void *src, size_t size) 19long probe_kernel_read(void *dst, const void *src, size_t size)
20{ 20{
21 unsigned long lsrc = (unsigned long)src; 21 unsigned long lsrc = (unsigned long)src;
22 int mem_type; 22 int mem_type;
@@ -55,7 +55,7 @@ long probe_kernel_read(void *dst, void *src, size_t size)
55 return -EFAULT; 55 return -EFAULT;
56} 56}
57 57
58long probe_kernel_write(void *dst, void *src, size_t size) 58long probe_kernel_write(void *dst, const void *src, size_t size)
59{ 59{
60 unsigned long ldst = (unsigned long)dst; 60 unsigned long ldst = (unsigned long)dst;
61 int mem_type; 61 int mem_type;
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 71a4b0d34be0..51e5cd9b906a 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -19,7 +19,7 @@
19 * using the stura instruction. 19 * using the stura instruction.
20 * Returns the number of bytes copied or -EFAULT. 20 * Returns the number of bytes copied or -EFAULT.
21 */ 21 */
22static long probe_kernel_write_odd(void *dst, void *src, size_t size) 22static long probe_kernel_write_odd(void *dst, const void *src, size_t size)
23{ 23{
24 unsigned long count, aligned; 24 unsigned long count, aligned;
25 int offset, mask; 25 int offset, mask;
@@ -45,7 +45,7 @@ static long probe_kernel_write_odd(void *dst, void *src, size_t size)
45 return rc ? rc : count; 45 return rc ? rc : count;
46} 46}
47 47
48long probe_kernel_write(void *dst, void *src, size_t size) 48long probe_kernel_write(void *dst, const void *src, size_t size)
49{ 49{
50 long copied = 0; 50 long copied = 0;
51 51
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 0ba15a6cc57e..c9a281f272fd 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -123,7 +123,7 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
123static atomic_t nmi_running = ATOMIC_INIT(0); 123static atomic_t nmi_running = ATOMIC_INIT(0);
124static int mod_code_status; /* holds return value of text write */ 124static int mod_code_status; /* holds return value of text write */
125static void *mod_code_ip; /* holds the IP to write to */ 125static void *mod_code_ip; /* holds the IP to write to */
126static void *mod_code_newcode; /* holds the text to write to the IP */ 126static const void *mod_code_newcode; /* holds the text to write to the IP */
127 127
128static unsigned nmi_wait_count; 128static unsigned nmi_wait_count;
129static atomic_t nmi_update_count = ATOMIC_INIT(0); 129static atomic_t nmi_update_count = ATOMIC_INIT(0);
@@ -225,7 +225,7 @@ within(unsigned long addr, unsigned long start, unsigned long end)
225} 225}
226 226
227static int 227static int
228do_ftrace_mod_code(unsigned long ip, void *new_code) 228do_ftrace_mod_code(unsigned long ip, const void *new_code)
229{ 229{
230 /* 230 /*
231 * On x86_64, kernel text mappings are mapped read-only with 231 * On x86_64, kernel text mappings are mapped read-only with
@@ -266,8 +266,8 @@ static const unsigned char *ftrace_nop_replace(void)
266} 266}
267 267
268static int 268static int
269ftrace_modify_code(unsigned long ip, unsigned char *old_code, 269ftrace_modify_code(unsigned long ip, unsigned const char *old_code,
270 unsigned char *new_code) 270 unsigned const char *new_code)
271{ 271{
272 unsigned char replaced[MCOUNT_INSN_SIZE]; 272 unsigned char replaced[MCOUNT_INSN_SIZE];
273 273
@@ -301,7 +301,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
301int ftrace_make_nop(struct module *mod, 301int ftrace_make_nop(struct module *mod,
302 struct dyn_ftrace *rec, unsigned long addr) 302 struct dyn_ftrace *rec, unsigned long addr)
303{ 303{
304 unsigned char *new, *old; 304 unsigned const char *new, *old;
305 unsigned long ip = rec->ip; 305 unsigned long ip = rec->ip;
306 306
307 old = ftrace_call_replace(ip, addr); 307 old = ftrace_call_replace(ip, addr);
@@ -312,7 +312,7 @@ int ftrace_make_nop(struct module *mod,
312 312
313int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 313int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
314{ 314{
315 unsigned char *new, *old; 315 unsigned const char *new, *old;
316 unsigned long ip = rec->ip; 316 unsigned long ip = rec->ip;
317 317
318 old = ftrace_nop_replace(); 318 old = ftrace_nop_replace();
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index c3b8e24f2b16..9fd8a567fe1e 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -316,16 +316,23 @@ static void op_amd_stop_ibs(void)
316 wrmsrl(MSR_AMD64_IBSOPCTL, 0); 316 wrmsrl(MSR_AMD64_IBSOPCTL, 0);
317} 317}
318 318
319static inline int eilvt_is_available(int offset) 319static inline int get_eilvt(int offset)
320{ 320{
321 /* check if we may assign a vector */
322 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); 321 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
323} 322}
324 323
324static inline int put_eilvt(int offset)
325{
326 return !setup_APIC_eilvt(offset, 0, 0, 1);
327}
328
325static inline int ibs_eilvt_valid(void) 329static inline int ibs_eilvt_valid(void)
326{ 330{
327 int offset; 331 int offset;
328 u64 val; 332 u64 val;
333 int valid = 0;
334
335 preempt_disable();
329 336
330 rdmsrl(MSR_AMD64_IBSCTL, val); 337 rdmsrl(MSR_AMD64_IBSCTL, val);
331 offset = val & IBSCTL_LVT_OFFSET_MASK; 338 offset = val & IBSCTL_LVT_OFFSET_MASK;
@@ -333,16 +340,20 @@ static inline int ibs_eilvt_valid(void)
333 if (!(val & IBSCTL_LVT_OFFSET_VALID)) { 340 if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
334 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", 341 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
335 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); 342 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
336 return 0; 343 goto out;
337 } 344 }
338 345
339 if (!eilvt_is_available(offset)) { 346 if (!get_eilvt(offset)) {
340 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", 347 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
341 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); 348 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
342 return 0; 349 goto out;
343 } 350 }
344 351
345 return 1; 352 valid = 1;
353out:
354 preempt_enable();
355
356 return valid;
346} 357}
347 358
348static inline int get_ibs_offset(void) 359static inline int get_ibs_offset(void)
@@ -600,67 +611,69 @@ static int setup_ibs_ctl(int ibs_eilvt_off)
600 611
601static int force_ibs_eilvt_setup(void) 612static int force_ibs_eilvt_setup(void)
602{ 613{
603 int i; 614 int offset;
604 int ret; 615 int ret;
605 616
606 /* find the next free available EILVT entry */ 617 /*
607 for (i = 1; i < 4; i++) { 618 * find the next free available EILVT entry, skip offset 0,
608 if (!eilvt_is_available(i)) 619 * pin search to this cpu
609 continue; 620 */
610 ret = setup_ibs_ctl(i); 621 preempt_disable();
611 if (ret) 622 for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
612 return ret; 623 if (get_eilvt(offset))
613 pr_err(FW_BUG "using offset %d for IBS interrupts\n", i); 624 break;
614 return 0;
615 } 625 }
626 preempt_enable();
616 627
617 printk(KERN_DEBUG "No EILVT entry available\n"); 628 if (offset == APIC_EILVT_NR_MAX) {
618 629 printk(KERN_DEBUG "No EILVT entry available\n");
619 return -EBUSY; 630 return -EBUSY;
620} 631 }
621
622static int __init_ibs_nmi(void)
623{
624 int ret;
625
626 if (ibs_eilvt_valid())
627 return 0;
628 632
629 ret = force_ibs_eilvt_setup(); 633 ret = setup_ibs_ctl(offset);
630 if (ret) 634 if (ret)
631 return ret; 635 goto out;
632 636
633 if (!ibs_eilvt_valid()) 637 if (!ibs_eilvt_valid()) {
634 return -EFAULT; 638 ret = -EFAULT;
639 goto out;
640 }
635 641
642 pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset);
636 pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); 643 pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
637 644
638 return 0; 645 return 0;
646out:
647 preempt_disable();
648 put_eilvt(offset);
649 preempt_enable();
650 return ret;
639} 651}
640 652
641/* 653/*
642 * check and reserve APIC extended interrupt LVT offset for IBS if 654 * check and reserve APIC extended interrupt LVT offset for IBS if
643 * available 655 * available
644 *
645 * init_ibs() preforms implicitly cpu-local operations, so pin this
646 * thread to its current CPU
647 */ 656 */
648 657
649static void init_ibs(void) 658static void init_ibs(void)
650{ 659{
651 preempt_disable();
652
653 ibs_caps = get_ibs_caps(); 660 ibs_caps = get_ibs_caps();
661
654 if (!ibs_caps) 662 if (!ibs_caps)
663 return;
664
665 if (ibs_eilvt_valid())
655 goto out; 666 goto out;
656 667
657 if (__init_ibs_nmi() < 0) 668 if (!force_ibs_eilvt_setup())
658 ibs_caps = 0; 669 goto out;
659 else 670
660 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); 671 /* Failed to setup ibs */
672 ibs_caps = 0;
673 return;
661 674
662out: 675out:
663 preempt_enable(); 676 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
664} 677}
665 678
666static int (*create_arch_files)(struct super_block *sb, struct dentry *root); 679static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
index 4e70749f8d16..a8d5bb3cba89 100644
--- a/drivers/oprofile/event_buffer.h
+++ b/drivers/oprofile/event_buffer.h
@@ -11,7 +11,7 @@
11#define EVENT_BUFFER_H 11#define EVENT_BUFFER_H
12 12
13#include <linux/types.h> 13#include <linux/types.h>
14#include <asm/mutex.h> 14#include <linux/mutex.h>
15 15
16int alloc_event_buffer(void); 16int alloc_event_buffer(void);
17 17
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index f9bda64fcd1b..dccd8636095c 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -14,7 +14,7 @@
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/workqueue.h> 15#include <linux/workqueue.h>
16#include <linux/time.h> 16#include <linux/time.h>
17#include <asm/mutex.h> 17#include <linux/mutex.h>
18 18
19#include "oprof.h" 19#include "oprof.h"
20#include "event_buffer.h" 20#include "event_buffer.h"
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index b5a550a39a70..59d3ef100eb9 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -16,6 +16,11 @@ struct trace_print_flags {
16 const char *name; 16 const char *name;
17}; 17};
18 18
19struct trace_print_flags_u64 {
20 unsigned long long mask;
21 const char *name;
22};
23
19const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, 24const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
20 unsigned long flags, 25 unsigned long flags,
21 const struct trace_print_flags *flag_array); 26 const struct trace_print_flags *flag_array);
@@ -23,6 +28,13 @@ const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
23const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, 28const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
24 const struct trace_print_flags *symbol_array); 29 const struct trace_print_flags *symbol_array);
25 30
31#if BITS_PER_LONG == 32
32const char *ftrace_print_symbols_seq_u64(struct trace_seq *p,
33 unsigned long long val,
34 const struct trace_print_flags_u64
35 *symbol_array);
36#endif
37
26const char *ftrace_print_hex_seq(struct trace_seq *p, 38const char *ftrace_print_hex_seq(struct trace_seq *p,
27 const unsigned char *buf, int len); 39 const unsigned char *buf, int len);
28 40
diff --git a/include/linux/sched.h b/include/linux/sched.h
index dc8871295a5a..8f441d1c6550 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1546,7 +1546,7 @@ struct task_struct {
1546#ifdef CONFIG_TRACING 1546#ifdef CONFIG_TRACING
1547 /* state flags for use by tracers */ 1547 /* state flags for use by tracers */
1548 unsigned long trace; 1548 unsigned long trace;
1549 /* bitmask of trace recursion */ 1549 /* bitmask and counter of trace recursion */
1550 unsigned long trace_recursion; 1550 unsigned long trace_recursion;
1551#endif /* CONFIG_TRACING */ 1551#endif /* CONFIG_TRACING */
1552#ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ 1552#ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index d512d98dfb7d..5ca0951e1855 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -93,8 +93,8 @@ static inline unsigned long __copy_from_user_nocache(void *to,
93 * Safely read from address @src to the buffer at @dst. If a kernel fault 93 * Safely read from address @src to the buffer at @dst. If a kernel fault
94 * happens, handle that and return -EFAULT. 94 * happens, handle that and return -EFAULT.
95 */ 95 */
96extern long probe_kernel_read(void *dst, void *src, size_t size); 96extern long probe_kernel_read(void *dst, const void *src, size_t size);
97extern long __probe_kernel_read(void *dst, void *src, size_t size); 97extern long __probe_kernel_read(void *dst, const void *src, size_t size);
98 98
99/* 99/*
100 * probe_kernel_write(): safely attempt to write to a location 100 * probe_kernel_write(): safely attempt to write to a location
@@ -105,7 +105,7 @@ extern long __probe_kernel_read(void *dst, void *src, size_t size);
105 * Safely write to address @dst from the buffer at @src. If a kernel fault 105 * Safely write to address @dst from the buffer at @src. If a kernel fault
106 * happens, handle that and return -EFAULT. 106 * happens, handle that and return -EFAULT.
107 */ 107 */
108extern long notrace probe_kernel_write(void *dst, void *src, size_t size); 108extern long notrace probe_kernel_write(void *dst, const void *src, size_t size);
109extern long notrace __probe_kernel_write(void *dst, void *src, size_t size); 109extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size);
110 110
111#endif /* __LINUX_UACCESS_H__ */ 111#endif /* __LINUX_UACCESS_H__ */
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index f445cff66ab7..4114129f0794 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -28,7 +28,7 @@ struct extent_buffer;
28 { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) 28 { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" })
29 29
30#define __show_root_type(obj) \ 30#define __show_root_type(obj) \
31 __print_symbolic(obj, \ 31 __print_symbolic_u64(obj, \
32 { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ 32 { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \
33 { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \ 33 { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \
34 { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \ 34 { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \
@@ -125,7 +125,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict,
125); 125);
126 126
127#define __show_map_type(type) \ 127#define __show_map_type(type) \
128 __print_symbolic(type, \ 128 __print_symbolic_u64(type, \
129 { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ 129 { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \
130 { EXTENT_MAP_HOLE, "HOLE" }, \ 130 { EXTENT_MAP_HOLE, "HOLE" }, \
131 { EXTENT_MAP_INLINE, "INLINE" }, \ 131 { EXTENT_MAP_INLINE, "INLINE" }, \
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 3e68366d485a..533c49f48047 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -205,6 +205,19 @@
205 ftrace_print_symbols_seq(p, value, symbols); \ 205 ftrace_print_symbols_seq(p, value, symbols); \
206 }) 206 })
207 207
208#undef __print_symbolic_u64
209#if BITS_PER_LONG == 32
210#define __print_symbolic_u64(value, symbol_array...) \
211 ({ \
212 static const struct trace_print_flags_u64 symbols[] = \
213 { symbol_array, { -1, NULL } }; \
214 ftrace_print_symbols_seq_u64(p, value, symbols); \
215 })
216#else
217#define __print_symbolic_u64(value, symbol_array...) \
218 __print_symbolic(value, symbol_array)
219#endif
220
208#undef __print_hex 221#undef __print_hex
209#define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) 222#define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len)
210 223
diff --git a/kernel/events/core.c b/kernel/events/core.c
index c09767f7db3e..d863b3c057bb 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5028,6 +5028,14 @@ static int __perf_event_overflow(struct perf_event *event, int nmi,
5028 else 5028 else
5029 perf_event_output(event, nmi, data, regs); 5029 perf_event_output(event, nmi, data, regs);
5030 5030
5031 if (event->fasync && event->pending_kill) {
5032 if (nmi) {
5033 event->pending_wakeup = 1;
5034 irq_work_queue(&event->pending);
5035 } else
5036 perf_event_wakeup(event);
5037 }
5038
5031 return ret; 5039 return ret;
5032} 5040}
5033 5041
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 74d1c099fbd1..fa27e750dbc0 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -105,9 +105,12 @@ static int __jump_label_text_reserved(struct jump_entry *iter_start,
105} 105}
106 106
107static void __jump_label_update(struct jump_label_key *key, 107static void __jump_label_update(struct jump_label_key *key,
108 struct jump_entry *entry, int enable) 108 struct jump_entry *entry,
109 struct jump_entry *stop, int enable)
109{ 110{
110 for (; entry->key == (jump_label_t)(unsigned long)key; entry++) { 111 for (; (entry < stop) &&
112 (entry->key == (jump_label_t)(unsigned long)key);
113 entry++) {
111 /* 114 /*
112 * entry->code set to 0 invalidates module init text sections 115 * entry->code set to 0 invalidates module init text sections
113 * kernel_text_address() verifies we are not in core kernel 116 * kernel_text_address() verifies we are not in core kernel
@@ -181,7 +184,11 @@ static void __jump_label_mod_update(struct jump_label_key *key, int enable)
181 struct jump_label_mod *mod = key->next; 184 struct jump_label_mod *mod = key->next;
182 185
183 while (mod) { 186 while (mod) {
184 __jump_label_update(key, mod->entries, enable); 187 struct module *m = mod->mod;
188
189 __jump_label_update(key, mod->entries,
190 m->jump_entries + m->num_jump_entries,
191 enable);
185 mod = mod->next; 192 mod = mod->next;
186 } 193 }
187} 194}
@@ -245,7 +252,8 @@ static int jump_label_add_module(struct module *mod)
245 key->next = jlm; 252 key->next = jlm;
246 253
247 if (jump_label_enabled(key)) 254 if (jump_label_enabled(key))
248 __jump_label_update(key, iter, JUMP_LABEL_ENABLE); 255 __jump_label_update(key, iter, iter_stop,
256 JUMP_LABEL_ENABLE);
249 } 257 }
250 258
251 return 0; 259 return 0;
@@ -371,7 +379,7 @@ static void jump_label_update(struct jump_label_key *key, int enable)
371 379
372 /* if there are no users, entry can be NULL */ 380 /* if there are no users, entry can be NULL */
373 if (entry) 381 if (entry)
374 __jump_label_update(key, entry, enable); 382 __jump_label_update(key, entry, __stop___jump_table, enable);
375 383
376#ifdef CONFIG_MODULES 384#ifdef CONFIG_MODULES
377 __jump_label_mod_update(key, enable); 385 __jump_label_mod_update(key, enable);
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index d017c2c82c44..1ee417fcbfa5 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -109,12 +109,18 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip);
109static void ftrace_global_list_func(unsigned long ip, 109static void ftrace_global_list_func(unsigned long ip,
110 unsigned long parent_ip) 110 unsigned long parent_ip)
111{ 111{
112 struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ 112 struct ftrace_ops *op;
113
114 if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT)))
115 return;
113 116
117 trace_recursion_set(TRACE_GLOBAL_BIT);
118 op = rcu_dereference_raw(ftrace_global_list); /*see above*/
114 while (op != &ftrace_list_end) { 119 while (op != &ftrace_list_end) {
115 op->func(ip, parent_ip); 120 op->func(ip, parent_ip);
116 op = rcu_dereference_raw(op->next); /*see above*/ 121 op = rcu_dereference_raw(op->next); /*see above*/
117 }; 122 };
123 trace_recursion_clear(TRACE_GLOBAL_BIT);
118} 124}
119 125
120static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) 126static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip)
@@ -1638,12 +1644,12 @@ static void ftrace_startup_enable(int command)
1638 ftrace_run_update_code(command); 1644 ftrace_run_update_code(command);
1639} 1645}
1640 1646
1641static void ftrace_startup(struct ftrace_ops *ops, int command) 1647static int ftrace_startup(struct ftrace_ops *ops, int command)
1642{ 1648{
1643 bool hash_enable = true; 1649 bool hash_enable = true;
1644 1650
1645 if (unlikely(ftrace_disabled)) 1651 if (unlikely(ftrace_disabled))
1646 return; 1652 return -ENODEV;
1647 1653
1648 ftrace_start_up++; 1654 ftrace_start_up++;
1649 command |= FTRACE_ENABLE_CALLS; 1655 command |= FTRACE_ENABLE_CALLS;
@@ -1662,6 +1668,8 @@ static void ftrace_startup(struct ftrace_ops *ops, int command)
1662 ftrace_hash_rec_enable(ops, 1); 1668 ftrace_hash_rec_enable(ops, 1);
1663 1669
1664 ftrace_startup_enable(command); 1670 ftrace_startup_enable(command);
1671
1672 return 0;
1665} 1673}
1666 1674
1667static void ftrace_shutdown(struct ftrace_ops *ops, int command) 1675static void ftrace_shutdown(struct ftrace_ops *ops, int command)
@@ -2501,7 +2509,7 @@ static void __enable_ftrace_function_probe(void)
2501 2509
2502 ret = __register_ftrace_function(&trace_probe_ops); 2510 ret = __register_ftrace_function(&trace_probe_ops);
2503 if (!ret) 2511 if (!ret)
2504 ftrace_startup(&trace_probe_ops, 0); 2512 ret = ftrace_startup(&trace_probe_ops, 0);
2505 2513
2506 ftrace_probe_registered = 1; 2514 ftrace_probe_registered = 1;
2507} 2515}
@@ -3466,7 +3474,11 @@ device_initcall(ftrace_nodyn_init);
3466static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } 3474static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
3467static inline void ftrace_startup_enable(int command) { } 3475static inline void ftrace_startup_enable(int command) { }
3468/* Keep as macros so we do not need to define the commands */ 3476/* Keep as macros so we do not need to define the commands */
3469# define ftrace_startup(ops, command) do { } while (0) 3477# define ftrace_startup(ops, command) \
3478 ({ \
3479 (ops)->flags |= FTRACE_OPS_FL_ENABLED; \
3480 0; \
3481 })
3470# define ftrace_shutdown(ops, command) do { } while (0) 3482# define ftrace_shutdown(ops, command) do { } while (0)
3471# define ftrace_startup_sysctl() do { } while (0) 3483# define ftrace_startup_sysctl() do { } while (0)
3472# define ftrace_shutdown_sysctl() do { } while (0) 3484# define ftrace_shutdown_sysctl() do { } while (0)
@@ -3484,6 +3496,10 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip)
3484{ 3496{
3485 struct ftrace_ops *op; 3497 struct ftrace_ops *op;
3486 3498
3499 if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT)))
3500 return;
3501
3502 trace_recursion_set(TRACE_INTERNAL_BIT);
3487 /* 3503 /*
3488 * Some of the ops may be dynamically allocated, 3504 * Some of the ops may be dynamically allocated,
3489 * they must be freed after a synchronize_sched(). 3505 * they must be freed after a synchronize_sched().
@@ -3496,6 +3512,7 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip)
3496 op = rcu_dereference_raw(op->next); 3512 op = rcu_dereference_raw(op->next);
3497 }; 3513 };
3498 preempt_enable_notrace(); 3514 preempt_enable_notrace();
3515 trace_recursion_clear(TRACE_INTERNAL_BIT);
3499} 3516}
3500 3517
3501static void clear_ftrace_swapper(void) 3518static void clear_ftrace_swapper(void)
@@ -3799,7 +3816,7 @@ int register_ftrace_function(struct ftrace_ops *ops)
3799 3816
3800 ret = __register_ftrace_function(ops); 3817 ret = __register_ftrace_function(ops);
3801 if (!ret) 3818 if (!ret)
3802 ftrace_startup(ops, 0); 3819 ret = ftrace_startup(ops, 0);
3803 3820
3804 3821
3805 out_unlock: 3822 out_unlock:
@@ -4045,7 +4062,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
4045 ftrace_graph_return = retfunc; 4062 ftrace_graph_return = retfunc;
4046 ftrace_graph_entry = entryfunc; 4063 ftrace_graph_entry = entryfunc;
4047 4064
4048 ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); 4065 ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET);
4049 4066
4050out: 4067out:
4051 mutex_unlock(&ftrace_lock); 4068 mutex_unlock(&ftrace_lock);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 0ef7b4b2a1f7..b0c7aa407943 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -2216,7 +2216,7 @@ static noinline void trace_recursive_fail(void)
2216 2216
2217 printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" 2217 printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:"
2218 "HC[%lu]:SC[%lu]:NMI[%lu]\n", 2218 "HC[%lu]:SC[%lu]:NMI[%lu]\n",
2219 current->trace_recursion, 2219 trace_recursion_buffer(),
2220 hardirq_count() >> HARDIRQ_SHIFT, 2220 hardirq_count() >> HARDIRQ_SHIFT,
2221 softirq_count() >> SOFTIRQ_SHIFT, 2221 softirq_count() >> SOFTIRQ_SHIFT,
2222 in_nmi()); 2222 in_nmi());
@@ -2226,9 +2226,9 @@ static noinline void trace_recursive_fail(void)
2226 2226
2227static inline int trace_recursive_lock(void) 2227static inline int trace_recursive_lock(void)
2228{ 2228{
2229 current->trace_recursion++; 2229 trace_recursion_inc();
2230 2230
2231 if (likely(current->trace_recursion < TRACE_RECURSIVE_DEPTH)) 2231 if (likely(trace_recursion_buffer() < TRACE_RECURSIVE_DEPTH))
2232 return 0; 2232 return 0;
2233 2233
2234 trace_recursive_fail(); 2234 trace_recursive_fail();
@@ -2238,9 +2238,9 @@ static inline int trace_recursive_lock(void)
2238 2238
2239static inline void trace_recursive_unlock(void) 2239static inline void trace_recursive_unlock(void)
2240{ 2240{
2241 WARN_ON_ONCE(!current->trace_recursion); 2241 WARN_ON_ONCE(!trace_recursion_buffer());
2242 2242
2243 current->trace_recursion--; 2243 trace_recursion_dec();
2244} 2244}
2245 2245
2246#else 2246#else
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 6b69c4bd306f..229f8591f61d 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -784,4 +784,19 @@ extern const char *__stop___trace_bprintk_fmt[];
784 FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) 784 FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
785#include "trace_entries.h" 785#include "trace_entries.h"
786 786
787/* Only current can touch trace_recursion */
788#define trace_recursion_inc() do { (current)->trace_recursion++; } while (0)
789#define trace_recursion_dec() do { (current)->trace_recursion--; } while (0)
790
791/* Ring buffer has the 10 LSB bits to count */
792#define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff)
793
794/* for function tracing recursion */
795#define TRACE_INTERNAL_BIT (1<<11)
796#define TRACE_GLOBAL_BIT (1<<12)
797
798#define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0)
799#define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0)
800#define trace_recursion_test(bit) ((current)->trace_recursion & (bit))
801
787#endif /* _LINUX_KERNEL_TRACE_H */ 802#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 2fe110341359..686ec399f2a8 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1657,7 +1657,12 @@ static struct ftrace_ops trace_ops __initdata =
1657 1657
1658static __init void event_trace_self_test_with_function(void) 1658static __init void event_trace_self_test_with_function(void)
1659{ 1659{
1660 register_ftrace_function(&trace_ops); 1660 int ret;
1661 ret = register_ftrace_function(&trace_ops);
1662 if (WARN_ON(ret < 0)) {
1663 pr_info("Failed to enable function tracer for event tests\n");
1664 return;
1665 }
1661 pr_info("Running tests again, along with the function tracer\n"); 1666 pr_info("Running tests again, along with the function tracer\n");
1662 event_trace_self_tests(); 1667 event_trace_self_tests();
1663 unregister_ftrace_function(&trace_ops); 1668 unregister_ftrace_function(&trace_ops);
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index cf535ccedc86..e37de492a9e1 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -353,6 +353,33 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
353} 353}
354EXPORT_SYMBOL(ftrace_print_symbols_seq); 354EXPORT_SYMBOL(ftrace_print_symbols_seq);
355 355
356#if BITS_PER_LONG == 32
357const char *
358ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
359 const struct trace_print_flags_u64 *symbol_array)
360{
361 int i;
362 const char *ret = p->buffer + p->len;
363
364 for (i = 0; symbol_array[i].name; i++) {
365
366 if (val != symbol_array[i].mask)
367 continue;
368
369 trace_seq_puts(p, symbol_array[i].name);
370 break;
371 }
372
373 if (!p->len)
374 trace_seq_printf(p, "0x%llx", val);
375
376 trace_seq_putc(p, 0);
377
378 return ret;
379}
380EXPORT_SYMBOL(ftrace_print_symbols_seq_u64);
381#endif
382
356const char * 383const char *
357ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) 384ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len)
358{ 385{
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 7daa4b072e9f..3d0c56ad4792 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -415,15 +415,13 @@ static void watchdog_nmi_disable(int cpu) { return; }
415#endif /* CONFIG_HARDLOCKUP_DETECTOR */ 415#endif /* CONFIG_HARDLOCKUP_DETECTOR */
416 416
417/* prepare/enable/disable routines */ 417/* prepare/enable/disable routines */
418static int watchdog_prepare_cpu(int cpu) 418static void watchdog_prepare_cpu(int cpu)
419{ 419{
420 struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu); 420 struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu);
421 421
422 WARN_ON(per_cpu(softlockup_watchdog, cpu)); 422 WARN_ON(per_cpu(softlockup_watchdog, cpu));
423 hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 423 hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
424 hrtimer->function = watchdog_timer_fn; 424 hrtimer->function = watchdog_timer_fn;
425
426 return 0;
427} 425}
428 426
429static int watchdog_enable(int cpu) 427static int watchdog_enable(int cpu)
@@ -542,17 +540,16 @@ static int __cpuinit
542cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 540cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
543{ 541{
544 int hotcpu = (unsigned long)hcpu; 542 int hotcpu = (unsigned long)hcpu;
545 int err = 0;
546 543
547 switch (action) { 544 switch (action) {
548 case CPU_UP_PREPARE: 545 case CPU_UP_PREPARE:
549 case CPU_UP_PREPARE_FROZEN: 546 case CPU_UP_PREPARE_FROZEN:
550 err = watchdog_prepare_cpu(hotcpu); 547 watchdog_prepare_cpu(hotcpu);
551 break; 548 break;
552 case CPU_ONLINE: 549 case CPU_ONLINE:
553 case CPU_ONLINE_FROZEN: 550 case CPU_ONLINE_FROZEN:
554 if (watchdog_enabled) 551 if (watchdog_enabled)
555 err = watchdog_enable(hotcpu); 552 watchdog_enable(hotcpu);
556 break; 553 break;
557#ifdef CONFIG_HOTPLUG_CPU 554#ifdef CONFIG_HOTPLUG_CPU
558 case CPU_UP_CANCELED: 555 case CPU_UP_CANCELED:
diff --git a/mm/maccess.c b/mm/maccess.c
index e2b6f5634e0d..4cee182ab5f3 100644
--- a/mm/maccess.c
+++ b/mm/maccess.c
@@ -15,10 +15,10 @@
15 * happens, handle that and return -EFAULT. 15 * happens, handle that and return -EFAULT.
16 */ 16 */
17 17
18long __weak probe_kernel_read(void *dst, void *src, size_t size) 18long __weak probe_kernel_read(void *dst, const void *src, size_t size)
19 __attribute__((alias("__probe_kernel_read"))); 19 __attribute__((alias("__probe_kernel_read")));
20 20
21long __probe_kernel_read(void *dst, void *src, size_t size) 21long __probe_kernel_read(void *dst, const void *src, size_t size)
22{ 22{
23 long ret; 23 long ret;
24 mm_segment_t old_fs = get_fs(); 24 mm_segment_t old_fs = get_fs();
@@ -43,10 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
43 * Safely write to address @dst from the buffer at @src. If a kernel fault 43 * Safely write to address @dst from the buffer at @src. If a kernel fault
44 * happens, handle that and return -EFAULT. 44 * happens, handle that and return -EFAULT.
45 */ 45 */
46long __weak probe_kernel_write(void *dst, void *src, size_t size) 46long __weak probe_kernel_write(void *dst, const void *src, size_t size)
47 __attribute__((alias("__probe_kernel_write"))); 47 __attribute__((alias("__probe_kernel_write")));
48 48
49long __probe_kernel_write(void *dst, void *src, size_t size) 49long __probe_kernel_write(void *dst, const void *src, size_t size)
50{ 50{
51 long ret; 51 long ret;
52 mm_segment_t old_fs = get_fs(); 52 mm_segment_t old_fs = get_fs();
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
index 4be60364a405..f40a6af6bf40 100644
--- a/scripts/recordmcount.h
+++ b/scripts/recordmcount.h
@@ -43,6 +43,7 @@
43#undef ELF_R_INFO 43#undef ELF_R_INFO
44#undef Elf_r_info 44#undef Elf_r_info
45#undef ELF_ST_BIND 45#undef ELF_ST_BIND
46#undef ELF_ST_TYPE
46#undef fn_ELF_R_SYM 47#undef fn_ELF_R_SYM
47#undef fn_ELF_R_INFO 48#undef fn_ELF_R_INFO
48#undef uint_t 49#undef uint_t
@@ -76,6 +77,7 @@
76# define ELF_R_INFO ELF64_R_INFO 77# define ELF_R_INFO ELF64_R_INFO
77# define Elf_r_info Elf64_r_info 78# define Elf_r_info Elf64_r_info
78# define ELF_ST_BIND ELF64_ST_BIND 79# define ELF_ST_BIND ELF64_ST_BIND
80# define ELF_ST_TYPE ELF64_ST_TYPE
79# define fn_ELF_R_SYM fn_ELF64_R_SYM 81# define fn_ELF_R_SYM fn_ELF64_R_SYM
80# define fn_ELF_R_INFO fn_ELF64_R_INFO 82# define fn_ELF_R_INFO fn_ELF64_R_INFO
81# define uint_t uint64_t 83# define uint_t uint64_t
@@ -108,6 +110,7 @@
108# define ELF_R_INFO ELF32_R_INFO 110# define ELF_R_INFO ELF32_R_INFO
109# define Elf_r_info Elf32_r_info 111# define Elf_r_info Elf32_r_info
110# define ELF_ST_BIND ELF32_ST_BIND 112# define ELF_ST_BIND ELF32_ST_BIND
113# define ELF_ST_TYPE ELF32_ST_TYPE
111# define fn_ELF_R_SYM fn_ELF32_R_SYM 114# define fn_ELF_R_SYM fn_ELF32_R_SYM
112# define fn_ELF_R_INFO fn_ELF32_R_INFO 115# define fn_ELF_R_INFO fn_ELF32_R_INFO
113# define uint_t uint32_t 116# define uint_t uint32_t
@@ -427,6 +430,11 @@ static unsigned find_secsym_ndx(unsigned const txtndx,
427 if (txtndx == w2(symp->st_shndx) 430 if (txtndx == w2(symp->st_shndx)
428 /* avoid STB_WEAK */ 431 /* avoid STB_WEAK */
429 && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { 432 && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) {
433 /* function symbols on ARM have quirks, avoid them */
434 if (w2(ehdr->e_machine) == EM_ARM
435 && ELF_ST_TYPE(symp->st_info) == STT_FUNC)
436 continue;
437
430 *recvalp = _w(symp->st_value); 438 *recvalp = _w(symp->st_value);
431 return symp - sym0; 439 return symp - sym0;
432 } 440 }
diff --git a/scripts/tags.sh b/scripts/tags.sh
index bd6185d529cf..75c5d24f1993 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -132,7 +132,7 @@ exuberant()
132 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ 132 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \
133 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ 133 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
134 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ 134 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
135 --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' 135 --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/'
136 136
137 all_kconfigs | xargs $1 -a \ 137 all_kconfigs | xargs $1 -a \
138 --langdef=kconfig --language-force=kconfig \ 138 --langdef=kconfig --language-force=kconfig \
@@ -152,7 +152,9 @@ emacs()
152{ 152{
153 all_sources | xargs $1 -a \ 153 all_sources | xargs $1 -a \
154 --regex='/^ENTRY(\([^)]*\)).*/\1/' \ 154 --regex='/^ENTRY(\([^)]*\)).*/\1/' \
155 --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' 155 --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \
156 --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \
157 --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/'
156 158
157 all_kconfigs | xargs $1 -a \ 159 all_kconfigs | xargs $1 -a \
158 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' 160 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 1455413ec7a7..032ba6398a5c 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -215,11 +215,13 @@ LIB_FILE=$(OUTPUT)libperf.a
215LIB_H += ../../include/linux/perf_event.h 215LIB_H += ../../include/linux/perf_event.h
216LIB_H += ../../include/linux/rbtree.h 216LIB_H += ../../include/linux/rbtree.h
217LIB_H += ../../include/linux/list.h 217LIB_H += ../../include/linux/list.h
218LIB_H += ../../include/linux/const.h
218LIB_H += ../../include/linux/hash.h 219LIB_H += ../../include/linux/hash.h
219LIB_H += ../../include/linux/stringify.h 220LIB_H += ../../include/linux/stringify.h
220LIB_H += util/include/linux/bitmap.h 221LIB_H += util/include/linux/bitmap.h
221LIB_H += util/include/linux/bitops.h 222LIB_H += util/include/linux/bitops.h
222LIB_H += util/include/linux/compiler.h 223LIB_H += util/include/linux/compiler.h
224LIB_H += util/include/linux/const.h
223LIB_H += util/include/linux/ctype.h 225LIB_H += util/include/linux/ctype.h
224LIB_H += util/include/linux/kernel.h 226LIB_H += util/include/linux/kernel.h
225LIB_H += util/include/linux/list.h 227LIB_H += util/include/linux/list.h
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index e18eb7ed30ae..7b139e1e7e86 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -8,8 +8,6 @@
8#include "builtin.h" 8#include "builtin.h"
9 9
10#include "util/util.h" 10#include "util/util.h"
11
12#include "util/util.h"
13#include "util/color.h" 11#include "util/color.h"
14#include <linux/list.h> 12#include <linux/list.h>
15#include "util/cache.h" 13#include "util/cache.h"
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 0974f957b8fa..8e2c85798185 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -823,6 +823,16 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
823 823
824 symbol__init(); 824 symbol__init();
825 825
826 if (symbol_conf.kptr_restrict)
827 pr_warning(
828"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
829"check /proc/sys/kernel/kptr_restrict.\n\n"
830"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
831"file is not found in the buildid cache or in the vmlinux path.\n\n"
832"Samples in kernel modules won't be resolved at all.\n\n"
833"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
834"even with a suitable vmlinux or kallsyms file.\n\n");
835
826 if (no_buildid_cache || no_buildid) 836 if (no_buildid_cache || no_buildid)
827 disable_buildid_cache(); 837 disable_buildid_cache();
828 838
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 498c6f70a747..287a173523a7 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -116,6 +116,9 @@ static int process_sample_event(union perf_event *event,
116 if (al.filtered || (hide_unresolved && al.sym == NULL)) 116 if (al.filtered || (hide_unresolved && al.sym == NULL))
117 return 0; 117 return 0;
118 118
119 if (al.map != NULL)
120 al.map->dso->hit = 1;
121
119 if (perf_session__add_hist_entry(session, &al, sample, evsel)) { 122 if (perf_session__add_hist_entry(session, &al, sample, evsel)) {
120 pr_debug("problem incrementing symbol period, skipping event\n"); 123 pr_debug("problem incrementing symbol period, skipping event\n");
121 return -1; 124 return -1;
@@ -249,6 +252,8 @@ static int __cmd_report(void)
249 u64 nr_samples; 252 u64 nr_samples;
250 struct perf_session *session; 253 struct perf_session *session;
251 struct perf_evsel *pos; 254 struct perf_evsel *pos;
255 struct map *kernel_map;
256 struct kmap *kernel_kmap;
252 const char *help = "For a higher level overview, try: perf report --sort comm,dso"; 257 const char *help = "For a higher level overview, try: perf report --sort comm,dso";
253 258
254 signal(SIGINT, sig_handler); 259 signal(SIGINT, sig_handler);
@@ -268,6 +273,24 @@ static int __cmd_report(void)
268 if (ret) 273 if (ret)
269 goto out_delete; 274 goto out_delete;
270 275
276 kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION];
277 kernel_kmap = map__kmap(kernel_map);
278 if (kernel_map == NULL ||
279 (kernel_map->dso->hit &&
280 (kernel_kmap->ref_reloc_sym == NULL ||
281 kernel_kmap->ref_reloc_sym->addr == 0))) {
282 const struct dso *kdso = kernel_map->dso;
283
284 ui__warning(
285"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
286"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
287"Samples in kernel modules can't be resolved as well.\n\n",
288 RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ?
289"As no suitable kallsyms nor vmlinux was found, kernel samples\n"
290"can't be resolved." :
291"If some relocation was applied (e.g. kexec) symbols may be misresolved.");
292 }
293
271 if (dump_trace) { 294 if (dump_trace) {
272 perf_session__fprintf_nr_events(session, stdout); 295 perf_session__fprintf_nr_events(session, stdout);
273 goto out_delete; 296 goto out_delete;
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 974f6d3f4e53..22747de7234b 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -10,7 +10,6 @@
10#include "util/symbol.h" 10#include "util/symbol.h"
11#include "util/thread.h" 11#include "util/thread.h"
12#include "util/trace-event.h" 12#include "util/trace-event.h"
13#include "util/parse-options.h"
14#include "util/util.h" 13#include "util/util.h"
15#include "util/evlist.h" 14#include "util/evlist.h"
16#include "util/evsel.h" 15#include "util/evsel.h"
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 2d7934e9de38..f2f3f4937aa2 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -62,8 +62,6 @@
62#include <linux/unistd.h> 62#include <linux/unistd.h>
63#include <linux/types.h> 63#include <linux/types.h>
64 64
65#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
66
67static struct perf_top top = { 65static struct perf_top top = {
68 .count_filter = 5, 66 .count_filter = 5,
69 .delay_secs = 2, 67 .delay_secs = 2,
@@ -82,6 +80,8 @@ static bool use_tui, use_stdio;
82 80
83static int default_interval = 0; 81static int default_interval = 0;
84 82
83static bool kptr_restrict_warned;
84static bool vmlinux_warned;
85static bool inherit = false; 85static bool inherit = false;
86static int realtime_prio = 0; 86static int realtime_prio = 0;
87static bool group = false; 87static bool group = false;
@@ -740,7 +740,22 @@ static void perf_event__process_sample(const union perf_event *event,
740 al.filtered) 740 al.filtered)
741 return; 741 return;
742 742
743 if (!kptr_restrict_warned &&
744 symbol_conf.kptr_restrict &&
745 al.cpumode == PERF_RECORD_MISC_KERNEL) {
746 ui__warning(
747"Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n"
748"Check /proc/sys/kernel/kptr_restrict.\n\n"
749"Kernel%s samples will not be resolved.\n",
750 !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ?
751 " modules" : "");
752 if (use_browser <= 0)
753 sleep(5);
754 kptr_restrict_warned = true;
755 }
756
743 if (al.sym == NULL) { 757 if (al.sym == NULL) {
758 const char *msg = "Kernel samples will not be resolved.\n";
744 /* 759 /*
745 * As we do lazy loading of symtabs we only will know if the 760 * As we do lazy loading of symtabs we only will know if the
746 * specified vmlinux file is invalid when we actually have a 761 * specified vmlinux file is invalid when we actually have a
@@ -752,12 +767,20 @@ static void perf_event__process_sample(const union perf_event *event,
752 * --hide-kernel-symbols, even if the user specifies an 767 * --hide-kernel-symbols, even if the user specifies an
753 * invalid --vmlinux ;-) 768 * invalid --vmlinux ;-)
754 */ 769 */
755 if (al.map == machine->vmlinux_maps[MAP__FUNCTION] && 770 if (!kptr_restrict_warned && !vmlinux_warned &&
771 al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
756 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 772 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
757 ui__warning("The %s file can't be used\n", 773 if (symbol_conf.vmlinux_name) {
758 symbol_conf.vmlinux_name); 774 ui__warning("The %s file can't be used.\n%s",
759 exit_browser(0); 775 symbol_conf.vmlinux_name, msg);
760 exit(1); 776 } else {
777 ui__warning("A vmlinux file was not found.\n%s",
778 msg);
779 }
780
781 if (use_browser <= 0)
782 sleep(5);
783 vmlinux_warned = true;
761 } 784 }
762 785
763 return; 786 return;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 6635fcd11ca5..0fe9adf76379 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -553,9 +553,18 @@ static int perf_event__process_kernel_mmap(union perf_event *event,
553 goto out_problem; 553 goto out_problem;
554 554
555 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); 555 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps);
556 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, 556
557 symbol_name, 557 /*
558 event->mmap.pgoff); 558 * Avoid using a zero address (kptr_restrict) for the ref reloc
559 * symbol. Effectively having zero here means that at record
560 * time /proc/sys/kernel/kptr_restrict was non zero.
561 */
562 if (event->mmap.pgoff != 0) {
563 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
564 symbol_name,
565 event->mmap.pgoff);
566 }
567
559 if (machine__is_default_guest(machine)) { 568 if (machine__is_default_guest(machine)) {
560 /* 569 /*
561 * preload dso of guest kernel and modules 570 * preload dso of guest kernel and modules
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index ee0fe0dffa71..cca29ededb5b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -35,7 +35,17 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
35 35
36int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 36int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
37{ 37{
38 int cpu, thread;
38 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); 39 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
40
41 if (evsel->fd) {
42 for (cpu = 0; cpu < ncpus; cpu++) {
43 for (thread = 0; thread < nthreads; thread++) {
44 FD(evsel, cpu, thread) = -1;
45 }
46 }
47 }
48
39 return evsel->fd != NULL ? 0 : -ENOMEM; 49 return evsel->fd != NULL ? 0 : -ENOMEM;
40} 50}
41 51
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 0717bebc7649..afb0849fe530 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -193,9 +193,13 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
193 *linkname = malloc(size), *targetname; 193 *linkname = malloc(size), *targetname;
194 int len, err = -1; 194 int len, err = -1;
195 195
196 if (is_kallsyms) 196 if (is_kallsyms) {
197 if (symbol_conf.kptr_restrict) {
198 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n");
199 return 0;
200 }
197 realname = (char *)name; 201 realname = (char *)name;
198 else 202 } else
199 realname = realpath(name, NULL); 203 realname = realpath(name, NULL);
200 204
201 if (realname == NULL || filename == NULL || linkname == NULL) 205 if (realname == NULL || filename == NULL || linkname == NULL)
diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h
new file mode 100644
index 000000000000..1b476c9ae649
--- /dev/null
+++ b/tools/perf/util/include/linux/const.h
@@ -0,0 +1 @@
#include "../../../../include/linux/const.h"
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 516876dfbe52..eec196329fd9 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -676,9 +676,30 @@ discard_symbol: rb_erase(&pos->rb_node, root);
676 return count + moved; 676 return count + moved;
677} 677}
678 678
679static bool symbol__restricted_filename(const char *filename,
680 const char *restricted_filename)
681{
682 bool restricted = false;
683
684 if (symbol_conf.kptr_restrict) {
685 char *r = realpath(filename, NULL);
686
687 if (r != NULL) {
688 restricted = strcmp(r, restricted_filename) == 0;
689 free(r);
690 return restricted;
691 }
692 }
693
694 return restricted;
695}
696
679int dso__load_kallsyms(struct dso *dso, const char *filename, 697int dso__load_kallsyms(struct dso *dso, const char *filename,
680 struct map *map, symbol_filter_t filter) 698 struct map *map, symbol_filter_t filter)
681{ 699{
700 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
701 return -1;
702
682 if (dso__load_all_kallsyms(dso, filename, map) < 0) 703 if (dso__load_all_kallsyms(dso, filename, map) < 0)
683 return -1; 704 return -1;
684 705
@@ -1790,6 +1811,9 @@ static int machine__create_modules(struct machine *machine)
1790 modules = path; 1811 modules = path;
1791 } 1812 }
1792 1813
1814 if (symbol__restricted_filename(path, "/proc/modules"))
1815 return -1;
1816
1793 file = fopen(modules, "r"); 1817 file = fopen(modules, "r");
1794 if (file == NULL) 1818 if (file == NULL)
1795 return -1; 1819 return -1;
@@ -2239,6 +2263,9 @@ static u64 machine__get_kernel_start_addr(struct machine *machine)
2239 } 2263 }
2240 } 2264 }
2241 2265
2266 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
2267 return 0;
2268
2242 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) 2269 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
2243 return 0; 2270 return 0;
2244 2271
@@ -2410,6 +2437,25 @@ static int setup_list(struct strlist **list, const char *list_str,
2410 return 0; 2437 return 0;
2411} 2438}
2412 2439
2440static bool symbol__read_kptr_restrict(void)
2441{
2442 bool value = false;
2443
2444 if (geteuid() != 0) {
2445 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
2446 if (fp != NULL) {
2447 char line[8];
2448
2449 if (fgets(line, sizeof(line), fp) != NULL)
2450 value = atoi(line) != 0;
2451
2452 fclose(fp);
2453 }
2454 }
2455
2456 return value;
2457}
2458
2413int symbol__init(void) 2459int symbol__init(void)
2414{ 2460{
2415 const char *symfs; 2461 const char *symfs;
@@ -2456,6 +2502,8 @@ int symbol__init(void)
2456 if (symfs != symbol_conf.symfs) 2502 if (symfs != symbol_conf.symfs)
2457 free((void *)symfs); 2503 free((void *)symfs);
2458 2504
2505 symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
2506
2459 symbol_conf.initialized = true; 2507 symbol_conf.initialized = true;
2460 return 0; 2508 return 0;
2461 2509
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 242de0101a86..325ee36a9d29 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -75,7 +75,8 @@ struct symbol_conf {
75 use_callchain, 75 use_callchain,
76 exclude_other, 76 exclude_other,
77 show_cpu_utilization, 77 show_cpu_utilization,
78 initialized; 78 initialized,
79 kptr_restrict;
79 const char *vmlinux_name, 80 const char *vmlinux_name,
80 *kallsyms_name, 81 *kallsyms_name,
81 *source_prefix, 82 *source_prefix,