1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright(C) 2015 Linaro Limited. All rights reserved.
4 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
8 #include <linux/bitops.h>
9 #include <linux/compiler.h>
10 #include <linux/coresight-pmu.h>
11 #include <linux/kernel.h>
12 #include <linux/log2.h>
13 #include <linux/types.h>
16 #include "../../perf.h"
17 #include "../../util/auxtrace.h"
18 #include "../../util/cpumap.h"
19 #include "../../util/evlist.h"
20 #include "../../util/evsel.h"
21 #include "../../util/pmu.h"
22 #include "../../util/thread_map.h"
23 #include "../../util/cs-etm.h"
28 #define ENABLE_SINK_MAX 128
29 #define CS_BUS_DEVICE_PATH "/bus/coresight/devices/"
31 struct cs_etm_recording {
32 struct auxtrace_record itr;
33 struct perf_pmu *cs_etm_pmu;
34 struct perf_evlist *evlist;
41 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu);
43 static int cs_etm_parse_snapshot_options(struct auxtrace_record *itr,
44 struct record_opts *opts,
47 struct cs_etm_recording *ptr =
48 container_of(itr, struct cs_etm_recording, itr);
49 unsigned long long snapshot_size = 0;
53 snapshot_size = strtoull(str, &endptr, 0);
54 if (*endptr || snapshot_size > SIZE_MAX)
58 opts->auxtrace_snapshot_mode = true;
59 opts->auxtrace_snapshot_size = snapshot_size;
60 ptr->snapshot_size = snapshot_size;
65 static int cs_etm_recording_options(struct auxtrace_record *itr,
66 struct perf_evlist *evlist,
67 struct record_opts *opts)
69 struct cs_etm_recording *ptr =
70 container_of(itr, struct cs_etm_recording, itr);
71 struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
72 struct perf_evsel *evsel, *cs_etm_evsel = NULL;
73 const struct cpu_map *cpus = evlist->cpus;
74 bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0);
77 ptr->snapshot_mode = opts->auxtrace_snapshot_mode;
79 evlist__for_each_entry(evlist, evsel) {
80 if (evsel->attr.type == cs_etm_pmu->type) {
82 pr_err("There may be only one %s event\n",
83 CORESIGHT_ETM_PMU_NAME);
87 evsel->attr.sample_period = 1;
89 opts->full_auxtrace = true;
93 /* no need to continue if at least one event of interest was found */
97 if (opts->use_clockid) {
98 pr_err("Cannot use clockid (-k option) with %s\n",
99 CORESIGHT_ETM_PMU_NAME);
103 /* we are in snapshot mode */
104 if (opts->auxtrace_snapshot_mode) {
106 * No size were given to '-S' or '-m,', so go with
109 if (!opts->auxtrace_snapshot_size &&
110 !opts->auxtrace_mmap_pages) {
112 opts->auxtrace_mmap_pages = MiB(4) / page_size;
114 opts->auxtrace_mmap_pages =
115 KiB(128) / page_size;
116 if (opts->mmap_pages == UINT_MAX)
117 opts->mmap_pages = KiB(256) / page_size;
119 } else if (!opts->auxtrace_mmap_pages && !privileged &&
120 opts->mmap_pages == UINT_MAX) {
121 opts->mmap_pages = KiB(256) / page_size;
125 * '-m,xyz' was specified but no snapshot size, so make the
126 * snapshot size as big as the auxtrace mmap area.
128 if (!opts->auxtrace_snapshot_size) {
129 opts->auxtrace_snapshot_size =
130 opts->auxtrace_mmap_pages * (size_t)page_size;
134 * -Sxyz was specified but no auxtrace mmap area, so make the
135 * auxtrace mmap area big enough to fit the requested snapshot
138 if (!opts->auxtrace_mmap_pages) {
139 size_t sz = opts->auxtrace_snapshot_size;
141 sz = round_up(sz, page_size) / page_size;
142 opts->auxtrace_mmap_pages = roundup_pow_of_two(sz);
145 /* Snapshost size can't be bigger than the auxtrace area */
146 if (opts->auxtrace_snapshot_size >
147 opts->auxtrace_mmap_pages * (size_t)page_size) {
148 pr_err("Snapshot size %zu must not be greater than AUX area tracing mmap size %zu\n",
149 opts->auxtrace_snapshot_size,
150 opts->auxtrace_mmap_pages * (size_t)page_size);
154 /* Something went wrong somewhere - this shouldn't happen */
155 if (!opts->auxtrace_snapshot_size ||
156 !opts->auxtrace_mmap_pages) {
157 pr_err("Failed to calculate default snapshot size and/or AUX area tracing mmap pages\n");
162 /* We are in full trace mode but '-m,xyz' wasn't specified */
163 if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
165 opts->auxtrace_mmap_pages = MiB(4) / page_size;
167 opts->auxtrace_mmap_pages = KiB(128) / page_size;
168 if (opts->mmap_pages == UINT_MAX)
169 opts->mmap_pages = KiB(256) / page_size;
174 /* Validate auxtrace_mmap_pages provided by user */
175 if (opts->auxtrace_mmap_pages) {
176 unsigned int max_page = (KiB(128) / page_size);
177 size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
180 opts->auxtrace_mmap_pages > max_page) {
181 opts->auxtrace_mmap_pages = max_page;
182 pr_err("auxtrace too big, truncating to %d\n",
186 if (!is_power_of_2(sz)) {
187 pr_err("Invalid mmap size for %s: must be a power of 2\n",
188 CORESIGHT_ETM_PMU_NAME);
193 if (opts->auxtrace_snapshot_mode)
194 pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME,
195 opts->auxtrace_snapshot_size);
198 * To obtain the auxtrace buffer file descriptor, the auxtrace
199 * event must come first.
201 perf_evlist__to_front(evlist, cs_etm_evsel);
204 * In the case of per-cpu mmaps, we need the CPU on the
207 if (!cpu_map__empty(cpus))
208 perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
210 /* Add dummy event to keep tracking */
211 if (opts->full_auxtrace) {
212 struct perf_evsel *tracking_evsel;
215 err = parse_events(evlist, "dummy:u", NULL);
219 tracking_evsel = perf_evlist__last(evlist);
220 perf_evlist__set_tracking_event(evlist, tracking_evsel);
222 tracking_evsel->attr.freq = 0;
223 tracking_evsel->attr.sample_period = 1;
225 /* In per-cpu case, always need the time of mmap events etc */
226 if (!cpu_map__empty(cpus))
227 perf_evsel__set_sample_bit(tracking_evsel, TIME);
233 static u64 cs_etm_get_config(struct auxtrace_record *itr)
236 struct cs_etm_recording *ptr =
237 container_of(itr, struct cs_etm_recording, itr);
238 struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
239 struct perf_evlist *evlist = ptr->evlist;
240 struct perf_evsel *evsel;
242 evlist__for_each_entry(evlist, evsel) {
243 if (evsel->attr.type == cs_etm_pmu->type) {
245 * Variable perf_event_attr::config is assigned to
246 * ETMv3/PTM. The bit fields have been made to match
247 * the ETMv3.5 ETRMCR register specification. See the
248 * PMU_FORMAT_ATTR() declarations in
249 * drivers/hwtracing/coresight/coresight-perf.c for
252 config = evsel->attr.config;
261 #define BIT(N) (1UL << (N))
264 static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
270 * The perf event variable config bits represent both
271 * the command line options and register programming
272 * bits in ETMv3/PTM. For ETMv4 we must remap options
275 config_opts = cs_etm_get_config(itr);
276 if (config_opts & BIT(ETM_OPT_CYCACC))
277 config |= BIT(ETM4_CFG_BIT_CYCACC);
278 if (config_opts & BIT(ETM_OPT_TS))
279 config |= BIT(ETM4_CFG_BIT_TS);
280 if (config_opts & BIT(ETM_OPT_RETSTK))
281 config |= BIT(ETM4_CFG_BIT_RETSTK);
287 cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
288 struct perf_evlist *evlist __maybe_unused)
291 int etmv3 = 0, etmv4 = 0;
292 struct cpu_map *event_cpus = evlist->cpus;
293 struct cpu_map *online_cpus = cpu_map__new(NULL);
295 /* cpu map is not empty, we have specific CPUs to work with */
296 if (!cpu_map__empty(event_cpus)) {
297 for (i = 0; i < cpu__max_cpu(); i++) {
298 if (!cpu_map__has(event_cpus, i) ||
299 !cpu_map__has(online_cpus, i))
302 if (cs_etm_is_etmv4(itr, i))
308 /* get configuration for all CPUs in the system */
309 for (i = 0; i < cpu__max_cpu(); i++) {
310 if (!cpu_map__has(online_cpus, i))
313 if (cs_etm_is_etmv4(itr, i))
320 cpu_map__put(online_cpus);
322 return (CS_ETM_HEADER_SIZE +
323 (etmv4 * CS_ETMV4_PRIV_SIZE) +
324 (etmv3 * CS_ETMV3_PRIV_SIZE));
327 static const char *metadata_etmv3_ro[CS_ETM_PRIV_MAX] = {
328 [CS_ETM_ETMCCER] = "mgmt/etmccer",
329 [CS_ETM_ETMIDR] = "mgmt/etmidr",
332 static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = {
333 [CS_ETMV4_TRCIDR0] = "trcidr/trcidr0",
334 [CS_ETMV4_TRCIDR1] = "trcidr/trcidr1",
335 [CS_ETMV4_TRCIDR2] = "trcidr/trcidr2",
336 [CS_ETMV4_TRCIDR8] = "trcidr/trcidr8",
337 [CS_ETMV4_TRCAUTHSTATUS] = "mgmt/trcauthstatus",
340 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu)
346 struct cs_etm_recording *ptr =
347 container_of(itr, struct cs_etm_recording, itr);
348 struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
350 /* Take any of the RO files for ETMv4 and see if it present */
351 snprintf(path, PATH_MAX, "cpu%d/%s",
352 cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
353 scan = perf_pmu__scan_file(cs_etm_pmu, path, "%x", &val);
355 /* The file was read successfully, we have a winner */
362 static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
364 char pmu_path[PATH_MAX];
366 unsigned int val = 0;
368 /* Get RO metadata from sysfs */
369 snprintf(pmu_path, PATH_MAX, "cpu%d/%s", cpu, path);
371 scan = perf_pmu__scan_file(pmu, pmu_path, "%x", &val);
373 pr_err("%s: error reading: %s\n", __func__, pmu_path);
378 static void cs_etm_get_metadata(int cpu, u32 *offset,
379 struct auxtrace_record *itr,
380 struct auxtrace_info_event *info)
384 struct cs_etm_recording *ptr =
385 container_of(itr, struct cs_etm_recording, itr);
386 struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
388 /* first see what kind of tracer this cpu is affined to */
389 if (cs_etm_is_etmv4(itr, cpu)) {
390 magic = __perf_cs_etmv4_magic;
391 /* Get trace configuration register */
392 info->priv[*offset + CS_ETMV4_TRCCONFIGR] =
393 cs_etmv4_get_config(itr);
394 /* Get traceID from the framework */
395 info->priv[*offset + CS_ETMV4_TRCTRACEIDR] =
396 coresight_get_trace_id(cpu);
397 /* Get read-only information from sysFS */
398 info->priv[*offset + CS_ETMV4_TRCIDR0] =
399 cs_etm_get_ro(cs_etm_pmu, cpu,
400 metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
401 info->priv[*offset + CS_ETMV4_TRCIDR1] =
402 cs_etm_get_ro(cs_etm_pmu, cpu,
403 metadata_etmv4_ro[CS_ETMV4_TRCIDR1]);
404 info->priv[*offset + CS_ETMV4_TRCIDR2] =
405 cs_etm_get_ro(cs_etm_pmu, cpu,
406 metadata_etmv4_ro[CS_ETMV4_TRCIDR2]);
407 info->priv[*offset + CS_ETMV4_TRCIDR8] =
408 cs_etm_get_ro(cs_etm_pmu, cpu,
409 metadata_etmv4_ro[CS_ETMV4_TRCIDR8]);
410 info->priv[*offset + CS_ETMV4_TRCAUTHSTATUS] =
411 cs_etm_get_ro(cs_etm_pmu, cpu,
413 [CS_ETMV4_TRCAUTHSTATUS]);
415 /* How much space was used */
416 increment = CS_ETMV4_PRIV_MAX;
418 magic = __perf_cs_etmv3_magic;
419 /* Get configuration register */
420 info->priv[*offset + CS_ETM_ETMCR] = cs_etm_get_config(itr);
421 /* Get traceID from the framework */
422 info->priv[*offset + CS_ETM_ETMTRACEIDR] =
423 coresight_get_trace_id(cpu);
424 /* Get read-only information from sysFS */
425 info->priv[*offset + CS_ETM_ETMCCER] =
426 cs_etm_get_ro(cs_etm_pmu, cpu,
427 metadata_etmv3_ro[CS_ETM_ETMCCER]);
428 info->priv[*offset + CS_ETM_ETMIDR] =
429 cs_etm_get_ro(cs_etm_pmu, cpu,
430 metadata_etmv3_ro[CS_ETM_ETMIDR]);
432 /* How much space was used */
433 increment = CS_ETM_PRIV_MAX;
436 /* Build generic header portion */
437 info->priv[*offset + CS_ETM_MAGIC] = magic;
438 info->priv[*offset + CS_ETM_CPU] = cpu;
439 /* Where the next CPU entry should start from */
440 *offset += increment;
443 static int cs_etm_info_fill(struct auxtrace_record *itr,
444 struct perf_session *session,
445 struct auxtrace_info_event *info,
451 struct cpu_map *cpu_map;
452 struct cpu_map *event_cpus = session->evlist->cpus;
453 struct cpu_map *online_cpus = cpu_map__new(NULL);
454 struct cs_etm_recording *ptr =
455 container_of(itr, struct cs_etm_recording, itr);
456 struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
458 if (priv_size != cs_etm_info_priv_size(itr, session->evlist))
461 if (!session->evlist->nr_mmaps)
464 /* If the cpu_map is empty all online CPUs are involved */
465 if (cpu_map__empty(event_cpus)) {
466 cpu_map = online_cpus;
468 /* Make sure all specified CPUs are online */
469 for (i = 0; i < cpu_map__nr(event_cpus); i++) {
470 if (cpu_map__has(event_cpus, i) &&
471 !cpu_map__has(online_cpus, i))
475 cpu_map = event_cpus;
478 nr_cpu = cpu_map__nr(cpu_map);
479 /* Get PMU type as dynamically assigned by the core */
480 type = cs_etm_pmu->type;
482 /* First fill out the session header */
483 info->type = PERF_AUXTRACE_CS_ETM;
484 info->priv[CS_HEADER_VERSION_0] = 0;
485 info->priv[CS_PMU_TYPE_CPUS] = type << 32;
486 info->priv[CS_PMU_TYPE_CPUS] |= nr_cpu;
487 info->priv[CS_ETM_SNAPSHOT] = ptr->snapshot_mode;
489 offset = CS_ETM_SNAPSHOT + 1;
491 for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
492 if (cpu_map__has(cpu_map, i))
493 cs_etm_get_metadata(i, &offset, itr, info);
495 cpu_map__put(online_cpus);
500 static int cs_etm_alloc_wrapped_array(struct cs_etm_recording *ptr, int idx)
503 int cnt = ptr->wrapped_cnt;
505 /* Make @ptr->wrapped as big as @idx */
510 * Free'ed in cs_etm_recording_free(). Using realloc() to avoid
511 * cross compilation problems where the host's system supports
512 * reallocarray() but not the target.
514 wrapped = realloc(ptr->wrapped, cnt * sizeof(bool));
518 wrapped[cnt - 1] = false;
519 ptr->wrapped_cnt = cnt;
520 ptr->wrapped = wrapped;
525 static bool cs_etm_buffer_has_wrapped(unsigned char *buffer,
526 size_t buffer_size, u64 head)
529 u64 *buf = (u64 *)buffer;
530 size_t buf_size = buffer_size;
533 * We want to look the very last 512 byte (chosen arbitrarily) in
536 watermark = buf_size - 512;
539 * @head is continuously increasing - if its value is equal or greater
540 * than the size of the ring buffer, it has wrapped around.
542 if (head >= buffer_size)
546 * The value of @head is somewhere within the size of the ring buffer.
547 * This can be that there hasn't been enough data to fill the ring
548 * buffer yet or the trace time was so long that @head has numerically
549 * wrapped around. To find we need to check if we have data at the very
550 * end of the ring buffer. We can reliably do this because mmap'ed
551 * pages are zeroed out and there is a fresh mapping with every new
555 /* @head is less than 512 byte from the end of the ring buffer */
556 if (head > watermark)
560 * Speed things up by using 64 bit transactions (see "u64 *buf" above)
566 * If we find trace data at the end of the ring buffer, @head has
567 * been there and has numerically wrapped around at least once.
569 for (i = watermark; i < buf_size; i++)
576 static int cs_etm_find_snapshot(struct auxtrace_record *itr,
577 int idx, struct auxtrace_mmap *mm,
583 struct cs_etm_recording *ptr =
584 container_of(itr, struct cs_etm_recording, itr);
587 * Allocate memory to keep track of wrapping if this is the first
588 * time we deal with this *mm.
590 if (idx >= ptr->wrapped_cnt) {
591 err = cs_etm_alloc_wrapped_array(ptr, idx);
597 * Check to see if *head has wrapped around. If it hasn't only the
598 * amount of data between *head and *old is snapshot'ed to avoid
599 * bloating the perf.data file with zeros. But as soon as *head has
600 * wrapped around the entire size of the AUX ring buffer it taken.
602 wrapped = ptr->wrapped[idx];
603 if (!wrapped && cs_etm_buffer_has_wrapped(data, mm->len, *head)) {
605 ptr->wrapped[idx] = true;
608 pr_debug3("%s: mmap index %d old head %zu new head %zu size %zu\n",
609 __func__, idx, (size_t)*old, (size_t)*head, mm->len);
611 /* No wrap has occurred, we can just use *head and *old. */
616 * *head has wrapped around - adjust *head and *old to pickup the
617 * entire content of the AUX buffer.
619 if (*head >= mm->len) {
620 *old = *head - mm->len;
623 *old = *head - mm->len;
629 static int cs_etm_snapshot_start(struct auxtrace_record *itr)
631 struct cs_etm_recording *ptr =
632 container_of(itr, struct cs_etm_recording, itr);
633 struct perf_evsel *evsel;
635 evlist__for_each_entry(ptr->evlist, evsel) {
636 if (evsel->attr.type == ptr->cs_etm_pmu->type)
637 return perf_evsel__disable(evsel);
642 static int cs_etm_snapshot_finish(struct auxtrace_record *itr)
644 struct cs_etm_recording *ptr =
645 container_of(itr, struct cs_etm_recording, itr);
646 struct perf_evsel *evsel;
648 evlist__for_each_entry(ptr->evlist, evsel) {
649 if (evsel->attr.type == ptr->cs_etm_pmu->type)
650 return perf_evsel__enable(evsel);
655 static u64 cs_etm_reference(struct auxtrace_record *itr __maybe_unused)
657 return (((u64) rand() << 0) & 0x00000000FFFFFFFFull) |
658 (((u64) rand() << 32) & 0xFFFFFFFF00000000ull);
661 static void cs_etm_recording_free(struct auxtrace_record *itr)
663 struct cs_etm_recording *ptr =
664 container_of(itr, struct cs_etm_recording, itr);
666 zfree(&ptr->wrapped);
670 static int cs_etm_read_finish(struct auxtrace_record *itr, int idx)
672 struct cs_etm_recording *ptr =
673 container_of(itr, struct cs_etm_recording, itr);
674 struct perf_evsel *evsel;
676 evlist__for_each_entry(ptr->evlist, evsel) {
677 if (evsel->attr.type == ptr->cs_etm_pmu->type)
678 return perf_evlist__enable_event_idx(ptr->evlist,
685 struct auxtrace_record *cs_etm_record_init(int *err)
687 struct perf_pmu *cs_etm_pmu;
688 struct cs_etm_recording *ptr;
690 cs_etm_pmu = perf_pmu__find(CORESIGHT_ETM_PMU_NAME);
697 ptr = zalloc(sizeof(struct cs_etm_recording));
703 ptr->cs_etm_pmu = cs_etm_pmu;
704 ptr->itr.parse_snapshot_options = cs_etm_parse_snapshot_options;
705 ptr->itr.recording_options = cs_etm_recording_options;
706 ptr->itr.info_priv_size = cs_etm_info_priv_size;
707 ptr->itr.info_fill = cs_etm_info_fill;
708 ptr->itr.find_snapshot = cs_etm_find_snapshot;
709 ptr->itr.snapshot_start = cs_etm_snapshot_start;
710 ptr->itr.snapshot_finish = cs_etm_snapshot_finish;
711 ptr->itr.reference = cs_etm_reference;
712 ptr->itr.free = cs_etm_recording_free;
713 ptr->itr.read_finish = cs_etm_read_finish;
721 static FILE *cs_device__open_file(const char *name)
727 sysfs = sysfs__mountpoint();
731 snprintf(path, PATH_MAX,
732 "%s" CS_BUS_DEVICE_PATH "%s", sysfs, name);
734 if (stat(path, &st) < 0)
737 return fopen(path, "w");
741 static int __printf(2, 3) cs_device__print_file(const char *name, const char *fmt, ...)
748 file = cs_device__open_file(name);
750 ret = vfprintf(file, fmt, args);
757 int cs_etm_set_drv_config(struct perf_evsel_config_term *term)
760 char enable_sink[ENABLE_SINK_MAX];
762 snprintf(enable_sink, ENABLE_SINK_MAX, "%s/%s",
763 term->val.drv_cfg, "enable_sink");
765 ret = cs_device__print_file(enable_sink, "%d", 1);