Commit | Line | Data |
---|---|---|
a8ce99b0 AH |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/types.h> | |
3 | #include <linux/string.h> | |
7f7c536f | 4 | #include <linux/zalloc.h> |
a8ce99b0 | 5 | |
441b62ac IR |
6 | #include "../../../util/event.h" |
7 | #include "../../../util/synthetic-events.h" | |
8 | #include "../../../util/machine.h" | |
9 | #include "../../../util/tool.h" | |
10 | #include "../../../util/map.h" | |
11 | #include "../../../util/debug.h" | |
a8ce99b0 AH |
12 | |
13 | #if defined(__x86_64__) | |
14 | ||
15 | int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, | |
16 | perf_event__handler_t process, | |
17 | struct machine *machine) | |
18 | { | |
19 | int rc = 0; | |
20 | struct map *pos; | |
79b6bb73 | 21 | struct maps *kmaps = &machine->kmaps; |
a8ce99b0 AH |
22 | union perf_event *event = zalloc(sizeof(event->mmap) + |
23 | machine->id_hdr_size); | |
24 | ||
25 | if (!event) { | |
26 | pr_debug("Not enough memory synthesizing mmap event " | |
27 | "for extra kernel maps\n"); | |
28 | return -1; | |
29 | } | |
30 | ||
79b6bb73 | 31 | maps__for_each_entry(kmaps, pos) { |
a8ce99b0 AH |
32 | struct kmap *kmap; |
33 | size_t size; | |
34 | ||
35 | if (!__map__is_extra_kernel_map(pos)) | |
36 | continue; | |
37 | ||
38 | kmap = map__kmap(pos); | |
39 | ||
40 | size = sizeof(event->mmap) - sizeof(event->mmap.filename) + | |
41 | PERF_ALIGN(strlen(kmap->name) + 1, sizeof(u64)) + | |
42 | machine->id_hdr_size; | |
43 | ||
44 | memset(event, 0, size); | |
45 | ||
46 | event->mmap.header.type = PERF_RECORD_MMAP; | |
47 | ||
48 | /* | |
49 | * kernel uses 0 for user space maps, see kernel/perf_event.c | |
50 | * __perf_event_mmap | |
51 | */ | |
52 | if (machine__is_host(machine)) | |
53 | event->header.misc = PERF_RECORD_MISC_KERNEL; | |
54 | else | |
55 | event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; | |
56 | ||
57 | event->mmap.header.size = size; | |
58 | ||
59 | event->mmap.start = pos->start; | |
60 | event->mmap.len = pos->end - pos->start; | |
61 | event->mmap.pgoff = pos->pgoff; | |
62 | event->mmap.pid = machine->pid; | |
63 | ||
64 | strlcpy(event->mmap.filename, kmap->name, PATH_MAX); | |
65 | ||
66 | if (perf_tool__process_synth_event(tool, event, machine, | |
67 | process) != 0) { | |
68 | rc = -1; | |
69 | break; | |
70 | } | |
71 | } | |
72 | ||
73 | free(event); | |
74 | return rc; | |
75 | } | |
76 | ||
77 | #endif |