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