LKML Archive on lore.kernel.org help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@intel.com> To: Thomas Gleixner <tglx@linutronix.de>, Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Ingo Molnar <mingo@redhat.com>, Peter Zijlstra <peterz@infradead.org>, Andy Lutomirski <luto@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>, Andi Kleen <ak@linux.intel.com>, Alexander Shishkin <alexander.shishkin@linux.intel.com>, Dave Hansen <dave.hansen@linux.intel.com>, Joerg Roedel <joro@8bytes.org>, Jiri Olsa <jolsa@redhat.com>, linux-kernel@vger.kernel.org, x86@kernel.org Subject: [PATCH V2 12/20] perf tools: Synthesize and process mmap events for x86 PTI entry trampolines Date: Thu, 17 May 2018 12:22:00 +0300 [thread overview] Message-ID: <1526548928-20790-13-git-send-email-adrian.hunter@intel.com> (raw) In-Reply-To: <1526548928-20790-1-git-send-email-adrian.hunter@intel.com> Like the kernel text, the location of x86 PTI entry trampolines must be recorded in the perf.data file. Like the kernel, synthesize a mmap event for that, and add processing for it. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/arch/x86/util/Build | 1 + tools/perf/arch/x86/util/event.c | 76 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/event.c | 34 ++++++++++++++---- tools/perf/util/event.h | 8 +++++ tools/perf/util/machine.c | 28 +++++++++++++++ 5 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 tools/perf/arch/x86/util/event.c diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build index aa1ce5f6cc00..844b8f335532 100644 --- a/tools/perf/arch/x86/util/Build +++ b/tools/perf/arch/x86/util/Build @@ -5,6 +5,7 @@ libperf-y += kvm-stat.o libperf-y += perf_regs.o libperf-y += group.o libperf-y += machine.o +libperf-y += event.o libperf-$(CONFIG_DWARF) += dwarf-regs.o libperf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c new file mode 100644 index 000000000000..675a0213044d --- /dev/null +++ b/tools/perf/arch/x86/util/event.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/types.h> +#include <linux/string.h> + +#include "../../util/machine.h" +#include "../../util/tool.h" +#include "../../util/map.h" +#include "../../util/util.h" +#include "../../util/debug.h" + +#if defined(__x86_64__) + +int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine) +{ + int rc = 0; + struct map *pos; + struct map_groups *kmaps = &machine->kmaps; + struct maps *maps = &kmaps->maps; + union perf_event *event = zalloc(sizeof(event->mmap) + + machine->id_hdr_size); + + if (!event) { + pr_debug("Not enough memory synthesizing mmap event " + "for extra kernel maps\n"); + return -1; + } + + for (pos = maps__first(maps); pos; pos = map__next(pos)) { + struct kmap *kmap; + size_t size; + + if (!__map__is_extra_kernel_map(pos)) + continue; + + kmap = map__kmap(pos); + + size = sizeof(event->mmap) - sizeof(event->mmap.filename) + + PERF_ALIGN(strlen(kmap->name) + 1, sizeof(u64)) + + machine->id_hdr_size; + + memset(event, 0, size); + + event->mmap.header.type = PERF_RECORD_MMAP; + + /* + * kernel uses 0 for user space maps, see kernel/perf_event.c + * __perf_event_mmap + */ + if (machine__is_host(machine)) + event->header.misc = PERF_RECORD_MISC_KERNEL; + else + event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; + + event->mmap.header.size = size; + + event->mmap.start = pos->start; + event->mmap.len = pos->end - pos->start; + event->mmap.pgoff = pos->pgoff; + event->mmap.pid = machine->pid; + + strlcpy(event->mmap.filename, kmap->name, PATH_MAX); + + if (perf_tool__process_synth_event(tool, event, machine, + process) != 0) { + rc = -1; + break; + } + } + + free(event); + return rc; +} + +#endif diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index aafa9878465f..0c8ecf0c78a4 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -88,10 +88,10 @@ static const char *perf_ns__name(unsigned int id) return perf_ns__names[id]; } -static int perf_tool__process_synth_event(struct perf_tool *tool, - union perf_event *event, - struct machine *machine, - perf_event__handler_t process) +int perf_tool__process_synth_event(struct perf_tool *tool, + union perf_event *event, + struct machine *machine, + perf_event__handler_t process) { struct perf_sample synth_sample = { .pid = -1, @@ -888,9 +888,16 @@ int kallsyms__get_function_start(const char *kallsyms_filename, return 0; } -int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine) +int __weak perf_event__synthesize_extra_kmaps(struct perf_tool *tool __maybe_unused, + perf_event__handler_t process __maybe_unused, + struct machine *machine __maybe_unused) +{ + return 0; +} + +static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine) { size_t size; struct map *map = machine__kernel_map(machine); @@ -943,6 +950,19 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, return err; } +int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine) +{ + int err; + + err = __perf_event__synthesize_kernel_mmap(tool, process, machine); + if (err < 0) + return err; + + return perf_event__synthesize_extra_kmaps(tool, process, machine); +} + int perf_event__synthesize_thread_map2(struct perf_tool *tool, struct thread_map *threads, perf_event__handler_t process, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 0f794744919c..bfa60bcafbde 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -750,6 +750,10 @@ int perf_event__process_exit(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); +int perf_tool__process_synth_event(struct perf_tool *tool, + union perf_event *event, + struct machine *machine, + perf_event__handler_t process); int perf_event__process(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -796,6 +800,10 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, bool mmap_data, unsigned int proc_map_timeout); +int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine); + size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index a23aecc7328a..775889ae05b7 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1387,6 +1387,32 @@ static bool machine__uses_kcore(struct machine *machine) return false; } +static bool perf_event__is_extra_kernel_mmap(struct machine *machine, + union perf_event *event) +{ + return machine__is(machine, "x86_64") && + is_entry_trampoline(event->mmap.filename); +} + +static int machine__process_extra_kernel_map(struct machine *machine, + union perf_event *event) +{ + struct map *kernel_map = machine__kernel_map(machine); + struct dso *kernel = kernel_map ? kernel_map->dso : NULL; + struct extra_kernel_map xm = { + .start = event->mmap.start, + .end = event->mmap.start + event->mmap.len, + .pgoff = event->mmap.pgoff, + }; + + if (kernel == NULL) + return -1; + + strlcpy(xm.name, event->mmap.filename, KMAP_NAME_LEN); + + return machine__create_extra_kernel_map(machine, kernel, &xm); +} + static int machine__process_kernel_mmap_event(struct machine *machine, union perf_event *event) { @@ -1490,6 +1516,8 @@ static int machine__process_kernel_mmap_event(struct machine *machine, */ dso__load(kernel, machine__kernel_map(machine)); } + } else if (perf_event__is_extra_kernel_mmap(machine, event)) { + return machine__process_extra_kernel_map(machine, event); } return 0; out_problem: -- 1.9.1
next prev parent reply other threads:[~2018-05-17 9:26 UTC|newest] Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-17 9:21 [PATCH V2 00/20] perf tools and x86 PTI entry trampolines Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 01/20] kallsyms: Simplify update_iter_mod() Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 02/20] kallsyms, x86: Export addresses of syscall trampolines Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 03/20] x86: Add entry trampolines to kcore Adrian Hunter 2018-05-17 17:52 ` Dave Hansen 2018-05-17 18:09 ` Arnaldo Carvalho de Melo 2018-05-17 9:21 ` [PATCH V2 04/20] x86: kcore: Give entry trampolines all the same offset in kcore Adrian Hunter 2018-05-17 17:54 ` Dave Hansen 2018-05-17 9:21 ` [PATCH V2 05/20] perf tools: Add machine__is() to identify machine arch Adrian Hunter 2018-05-19 11:47 ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 06/20] perf tools: Fix kernel_start for PTI on x86 Adrian Hunter 2018-05-19 11:48 ` [tip:perf/core] " tip-bot for Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 07/20] perf tools: Add machine__nr_cpus_avail() Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 08/20] perf tools: Workaround missing maps for x86 PTI entry trampolines Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 09/20] perf tools: Fix map_groups__split_kallsyms() for entry trampoline symbols Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 10/20] perf tools: Allow for extra kernel maps Adrian Hunter 2018-05-17 9:21 ` [PATCH V2 11/20] perf tools: Create maps for x86 PTI entry trampolines Adrian Hunter 2018-05-17 9:22 ` Adrian Hunter [this message] 2018-05-17 9:22 ` [PATCH V2 13/20] perf buildid-cache: kcore_copy: Keep phdr data in a list Adrian Hunter 2018-05-17 9:22 ` [PATCH V2 14/20] perf buildid-cache: kcore_copy: Keep a count of phdrs Adrian Hunter 2018-05-17 9:22 ` [PATCH V2 15/20] perf buildid-cache: kcore_copy: Calculate offset from phnum Adrian Hunter 2018-05-17 9:22 ` [PATCH V2 16/20] perf buildid-cache: kcore_copy: Layout sections Adrian Hunter 2018-05-17 9:22 ` [PATCH V2 17/20] perf buildid-cache: kcore_copy: Iterate phdrs Adrian Hunter 2018-05-17 9:22 ` [PATCH V2 18/20] perf buildid-cache: kcore_copy: Get rid of kernel_map Adrian Hunter 2018-05-17 9:22 ` [PATCH V2 19/20] perf buildid-cache: kcore_copy: Copy x86 PTI entry trampoline sections Adrian Hunter 2018-05-17 9:22 ` [PATCH V2 20/20] perf buildid-cache: kcore_copy: Amend the offset of sections that remap kernel text Adrian Hunter
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1526548928-20790-13-git-send-email-adrian.hunter@intel.com \ --to=adrian.hunter@intel.com \ --cc=acme@kernel.org \ --cc=ak@linux.intel.com \ --cc=alexander.shishkin@linux.intel.com \ --cc=dave.hansen@linux.intel.com \ --cc=hpa@zytor.com \ --cc=jolsa@redhat.com \ --cc=joro@8bytes.org \ --cc=linux-kernel@vger.kernel.org \ --cc=luto@kernel.org \ --cc=mingo@redhat.com \ --cc=peterz@infradead.org \ --cc=tglx@linutronix.de \ --cc=x86@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).