perf machine: Synthesize and process mmap events for x86 PTI entry trampolines

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>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Link: http://lkml.kernel.org/r/1526986485-6562-10-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Adrian Hunter
2018-05-22 13:54:37 +03:00
committed by Arnaldo Carvalho de Melo
parent 1c5aae7710
commit a8ce99b0ee
5 changed files with 140 additions and 7 deletions

View File

@@ -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