diff options
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-record.c | 13 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 26 | ||||
-rw-r--r-- | tools/perf/util/event.c | 15 | ||||
-rw-r--r-- | tools/perf/util/header.c | 8 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 48 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 3 |
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 | ||
679 | static 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 | |||
679 | int dso__load_kallsyms(struct dso *dso, const char *filename, | 697 | int 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 | ||
2440 | static 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 | |||
2413 | int symbol__init(void) | 2459 | int 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, |