aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-06-04 06:13:06 -0400
committerIngo Molnar <mingo@elte.hu>2011-06-04 06:13:06 -0400
commit710054ba25c0d1f8f41c22ce13ba336503fb5318 (patch)
treef9b09b722bf511841539173d946f90a20fc2e59a /tools/perf
parent74c355fbdfedd3820046dba4f537876cea54c207 (diff)
parentb273fa9716aa1564bee88ceee62f9042981cdc81 (diff)
Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Diffstat (limited to 'tools/perf')
-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-test.c2
-rw-r--r--tools/perf/builtin-top.c37
-rw-r--r--tools/perf/util/event.c31
-rw-r--r--tools/perf/util/event.h2
-rw-r--r--tools/perf/util/evlist.c68
-rw-r--r--tools/perf/util/evlist.h6
-rw-r--r--tools/perf/util/evsel.c26
-rw-r--r--tools/perf/util/evsel.h7
-rw-r--r--tools/perf/util/header.c8
-rw-r--r--tools/perf/util/include/linux/const.h1
-rw-r--r--tools/perf/util/python.c14
-rw-r--r--tools/perf/util/session.c12
-rw-r--r--tools/perf/util/symbol.c48
-rw-r--r--tools/perf/util/symbol.h3
19 files changed, 227 insertions, 76 deletions
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-test.c b/tools/perf/builtin-test.c
index b67186228c89..2da9162262b0 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -474,7 +474,7 @@ static int test__basic_mmap(void)
474 unsigned int nr_events[nsyscalls], 474 unsigned int nr_events[nsyscalls],
475 expected_nr_events[nsyscalls], i, j; 475 expected_nr_events[nsyscalls], i, j;
476 struct perf_evsel *evsels[nsyscalls], *evsel; 476 struct perf_evsel *evsels[nsyscalls], *evsel;
477 int sample_size = perf_sample_size(attr.sample_type); 477 int sample_size = __perf_evsel__sample_size(attr.sample_type);
478 478
479 for (i = 0; i < nsyscalls; ++i) { 479 for (i = 0; i < nsyscalls; ++i) {
480 char name[64]; 480 char name[64];
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..3c1b8a632101 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -35,22 +35,6 @@ const char *perf_event__name(unsigned int id)
35 return perf_event__names[id]; 35 return perf_event__names[id];
36} 36}
37 37
38int perf_sample_size(u64 sample_type)
39{
40 u64 mask = sample_type & PERF_SAMPLE_MASK;
41 int size = 0;
42 int i;
43
44 for (i = 0; i < 64; i++) {
45 if (mask & (1ULL << i))
46 size++;
47 }
48
49 size *= sizeof(u64);
50
51 return size;
52}
53
54static struct perf_sample synth_sample = { 38static struct perf_sample synth_sample = {
55 .pid = -1, 39 .pid = -1,
56 .tid = -1, 40 .tid = -1,
@@ -553,9 +537,18 @@ static int perf_event__process_kernel_mmap(union perf_event *event,
553 goto out_problem; 537 goto out_problem;
554 538
555 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); 539 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps);
556 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, 540
557 symbol_name, 541 /*
558 event->mmap.pgoff); 542 * Avoid using a zero address (kptr_restrict) for the ref reloc
543 * symbol. Effectively having zero here means that at record
544 * time /proc/sys/kernel/kptr_restrict was non zero.
545 */
546 if (event->mmap.pgoff != 0) {
547 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
548 symbol_name,
549 event->mmap.pgoff);
550 }
551
559 if (machine__is_default_guest(machine)) { 552 if (machine__is_default_guest(machine)) {
560 /* 553 /*
561 * preload dso of guest kernel and modules 554 * preload dso of guest kernel and modules
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index c08332871408..1d7f66488a88 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -82,8 +82,6 @@ struct perf_sample {
82 struct ip_callchain *callchain; 82 struct ip_callchain *callchain;
83}; 83};
84 84
85int perf_sample_size(u64 sample_type);
86
87#define BUILD_ID_SIZE 20 85#define BUILD_ID_SIZE 20
88 86
89struct build_id_event { 87struct build_id_event {
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 50aa34879c33..b021ea9265c3 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -12,7 +12,6 @@
12#include "evlist.h" 12#include "evlist.h"
13#include "evsel.h" 13#include "evsel.h"
14#include "util.h" 14#include "util.h"
15#include "debug.h"
16 15
17#include <sys/mman.h> 16#include <sys/mman.h>
18 17
@@ -257,19 +256,15 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
257 return evlist->mmap != NULL ? 0 : -ENOMEM; 256 return evlist->mmap != NULL ? 0 : -ENOMEM;
258} 257}
259 258
260static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, 259static int __perf_evlist__mmap(struct perf_evlist *evlist,
261 int idx, int prot, int mask, int fd) 260 int idx, int prot, int mask, int fd)
262{ 261{
263 evlist->mmap[idx].prev = 0; 262 evlist->mmap[idx].prev = 0;
264 evlist->mmap[idx].mask = mask; 263 evlist->mmap[idx].mask = mask;
265 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, 264 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
266 MAP_SHARED, fd, 0); 265 MAP_SHARED, fd, 0);
267 if (evlist->mmap[idx].base == MAP_FAILED) { 266 if (evlist->mmap[idx].base == MAP_FAILED)
268 if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit)
269 ui__warning("Inherit is not allowed on per-task "
270 "events using mmap.\n");
271 return -1; 267 return -1;
272 }
273 268
274 perf_evlist__add_pollfd(evlist, fd); 269 perf_evlist__add_pollfd(evlist, fd);
275 return 0; 270 return 0;
@@ -289,7 +284,7 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int m
289 284
290 if (output == -1) { 285 if (output == -1) {
291 output = fd; 286 output = fd;
292 if (__perf_evlist__mmap(evlist, evsel, cpu, 287 if (__perf_evlist__mmap(evlist, cpu,
293 prot, mask, output) < 0) 288 prot, mask, output) < 0)
294 goto out_unmap; 289 goto out_unmap;
295 } else { 290 } else {
@@ -329,7 +324,7 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in
329 324
330 if (output == -1) { 325 if (output == -1) {
331 output = fd; 326 output = fd;
332 if (__perf_evlist__mmap(evlist, evsel, thread, 327 if (__perf_evlist__mmap(evlist, thread,
333 prot, mask, output) < 0) 328 prot, mask, output) < 0)
334 goto out_unmap; 329 goto out_unmap;
335 } else { 330 } else {
@@ -460,33 +455,46 @@ int perf_evlist__set_filters(struct perf_evlist *evlist)
460 return 0; 455 return 0;
461} 456}
462 457
463u64 perf_evlist__sample_type(struct perf_evlist *evlist) 458bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist)
464{ 459{
465 struct perf_evsel *pos; 460 struct perf_evsel *pos, *first;
466 u64 type = 0; 461
467 462 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
468 list_for_each_entry(pos, &evlist->entries, node) { 463
469 if (!type) 464 list_for_each_entry_continue(pos, &evlist->entries, node) {
470 type = pos->attr.sample_type; 465 if (first->attr.sample_type != pos->attr.sample_type)
471 else if (type != pos->attr.sample_type) 466 return false;
472 die("non matching sample_type");
473 } 467 }
474 468
475 return type; 469 return true;
476} 470}
477 471
478bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) 472u64 perf_evlist__sample_type(const struct perf_evlist *evlist)
473{
474 struct perf_evsel *first;
475
476 first = list_entry(evlist->entries.next, struct perf_evsel, node);
477 return first->attr.sample_type;
478}
479
480bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist)
479{ 481{
480 bool value = false, first = true; 482 struct perf_evsel *pos, *first;
481 struct perf_evsel *pos; 483
482 484 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
483 list_for_each_entry(pos, &evlist->entries, node) { 485
484 if (first) { 486 list_for_each_entry_continue(pos, &evlist->entries, node) {
485 value = pos->attr.sample_id_all; 487 if (first->attr.sample_id_all != pos->attr.sample_id_all)
486 first = false; 488 return false;
487 } else if (value != pos->attr.sample_id_all)
488 die("non matching sample_id_all");
489 } 489 }
490 490
491 return value; 491 return true;
492}
493
494bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
495{
496 struct perf_evsel *first;
497
498 first = list_entry(evlist->entries.next, struct perf_evsel, node);
499 return first->attr.sample_id_all;
492} 500}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 0a1ef1f051f0..b2b862374f37 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -66,7 +66,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
66void perf_evlist__delete_maps(struct perf_evlist *evlist); 66void perf_evlist__delete_maps(struct perf_evlist *evlist);
67int perf_evlist__set_filters(struct perf_evlist *evlist); 67int perf_evlist__set_filters(struct perf_evlist *evlist);
68 68
69u64 perf_evlist__sample_type(struct perf_evlist *evlist); 69u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
70bool perf_evlist__sample_id_all(const struct perf_evlist *evlist); 70bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
71 71
72bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
73bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
72#endif /* __PERF_EVLIST_H */ 74#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index ee0fe0dffa71..0239eb87b232 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -15,6 +15,22 @@
15 15
16#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 16#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
17 17
18int __perf_evsel__sample_size(u64 sample_type)
19{
20 u64 mask = sample_type & PERF_SAMPLE_MASK;
21 int size = 0;
22 int i;
23
24 for (i = 0; i < 64; i++) {
25 if (mask & (1ULL << i))
26 size++;
27 }
28
29 size *= sizeof(u64);
30
31 return size;
32}
33
18void perf_evsel__init(struct perf_evsel *evsel, 34void perf_evsel__init(struct perf_evsel *evsel,
19 struct perf_event_attr *attr, int idx) 35 struct perf_event_attr *attr, int idx)
20{ 36{
@@ -35,7 +51,17 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
35 51
36int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 52int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
37{ 53{
54 int cpu, thread;
38 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); 55 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
56
57 if (evsel->fd) {
58 for (cpu = 0; cpu < ncpus; cpu++) {
59 for (thread = 0; thread < nthreads; thread++) {
60 FD(evsel, cpu, thread) = -1;
61 }
62 }
63 }
64
39 return evsel->fd != NULL ? 0 : -ENOMEM; 65 return evsel->fd != NULL ? 0 : -ENOMEM;
40} 66}
41 67
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index f79bb2c09a6c..7e9366e4490b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -149,4 +149,11 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
149 return __perf_evsel__read(evsel, ncpus, nthreads, true); 149 return __perf_evsel__read(evsel, ncpus, nthreads, true);
150} 150}
151 151
152int __perf_evsel__sample_size(u64 sample_type);
153
154static inline int perf_evsel__sample_size(struct perf_evsel *evsel)
155{
156 return __perf_evsel__sample_size(evsel->attr.sample_type);
157}
158
152#endif /* __PERF_EVSEL_H */ 159#endif /* __PERF_EVSEL_H */
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/python.c b/tools/perf/util/python.c
index 69436b3200a4..a9ac0504aabd 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -674,7 +674,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
674 struct perf_evlist *evlist = &pevlist->evlist; 674 struct perf_evlist *evlist = &pevlist->evlist;
675 union perf_event *event; 675 union perf_event *event;
676 int sample_id_all = 1, cpu; 676 int sample_id_all = 1, cpu;
677 static char *kwlist[] = {"sample_id_all", NULL, NULL}; 677 static char *kwlist[] = {"cpu", "sample_id_all", NULL, NULL};
678 int err; 678 int err;
679 679
680 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, 680 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
@@ -692,16 +692,14 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
692 692
693 first = list_entry(evlist->entries.next, struct perf_evsel, node); 693 first = list_entry(evlist->entries.next, struct perf_evsel, node);
694 err = perf_event__parse_sample(event, first->attr.sample_type, 694 err = perf_event__parse_sample(event, first->attr.sample_type,
695 perf_sample_size(first->attr.sample_type), 695 perf_evsel__sample_size(first),
696 sample_id_all, &pevent->sample); 696 sample_id_all, &pevent->sample);
697 if (err) { 697 if (err)
698 pr_err("Can't parse sample, err = %d\n", err); 698 return PyErr_Format(PyExc_OSError,
699 goto end; 699 "perf: can't parse sample, err=%d", err);
700 }
701
702 return pyevent; 700 return pyevent;
703 } 701 }
704end: 702
705 Py_INCREF(Py_None); 703 Py_INCREF(Py_None);
706 return Py_None; 704 return Py_None;
707} 705}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 64500fc78799..f5a8fbdd3f76 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force)
58 goto out_close; 58 goto out_close;
59 } 59 }
60 60
61 if (!perf_evlist__valid_sample_type(self->evlist)) {
62 pr_err("non matching sample_type");
63 goto out_close;
64 }
65
66 if (!perf_evlist__valid_sample_id_all(self->evlist)) {
67 pr_err("non matching sample_id_all");
68 goto out_close;
69 }
70
61 self->size = input_stat.st_size; 71 self->size = input_stat.st_size;
62 return 0; 72 return 0;
63 73
@@ -97,7 +107,7 @@ out:
97void perf_session__update_sample_type(struct perf_session *self) 107void perf_session__update_sample_type(struct perf_session *self)
98{ 108{
99 self->sample_type = perf_evlist__sample_type(self->evlist); 109 self->sample_type = perf_evlist__sample_type(self->evlist);
100 self->sample_size = perf_sample_size(self->sample_type); 110 self->sample_size = __perf_evsel__sample_size(self->sample_type);
101 self->sample_id_all = perf_evlist__sample_id_all(self->evlist); 111 self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
102 perf_session__id_header_size(self); 112 perf_session__id_header_size(self);
103} 113}
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,