aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-record.c13
-rw-r--r--tools/perf/builtin-report.c26
-rw-r--r--tools/perf/util/event.c15
-rw-r--r--tools/perf/util/header.c8
-rw-r--r--tools/perf/util/symbol.c48
-rw-r--r--tools/perf/util/symbol.h3
6 files changed, 107 insertions, 6 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 0974f957b8fa..2ca107f3efdf 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -823,6 +823,19 @@ 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("WARNING: Kernel address maps "
828 "(/proc/{kallsyms,modules}) are restricted, "
829 "check /proc/sys/kernel/kptr_restrict.\n\n"
830 "Samples in kernel functions may not be resolved "
831 "if a suitable vmlinux file is not found in the "
832 "buildid cache or in the vmlinux path.\n\n"
833 "Samples in kernel modules won't be resolved "
834 "at all.\n\n"
835 "If some relocation was applied (e.g. kexec) "
836 "symbols may be misresolved even with a suitable "
837 "vmlinux or kallsyms file.\n\n");
838
826 if (no_buildid_cache || no_buildid) 839 if (no_buildid_cache || no_buildid)
827 disable_buildid_cache(); 840 disable_buildid_cache();
828 841
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 498c6f70a747..99156c35bc62 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,27 @@ 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("Kernel address maps "
285 "(/proc/{kallsyms,modules}) were restricted, "
286 "check /proc/sys/kernel/kptr_restrict before "
287 "running 'perf record'.\n\n%s\n\n"
288 "Samples in kernel modules can't be resolved "
289 "as well.\n\n",
290 RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ?
291 "As no suitable kallsyms nor vmlinux was found, "
292 "kernel samples can't be resolved." :
293 "If some relocation was applied (e.g. kexec) "
294 "symbols may be misresolved.");
295 }
296
271 if (dump_trace) { 297 if (dump_trace) {
272 perf_session__fprintf_nr_events(session, stdout); 298 perf_session__fprintf_nr_events(session, stdout);
273 goto out_delete; 299 goto out_delete;
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/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/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,