xref: /openbmc/linux/tools/perf/util/cs-etm.c (revision 01a6e126)
1 /*
2  * SPDX-License-Identifier: GPL-2.0
3  *
4  * Copyright(C) 2015-2018 Linaro Limited.
5  *
6  * Author: Tor Jeremiassen <tor@ti.com>
7  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
8  */
9 
10 #include <linux/bitops.h>
11 #include <linux/err.h>
12 #include <linux/kernel.h>
13 #include <linux/log2.h>
14 #include <linux/types.h>
15 
16 #include <stdlib.h>
17 
18 #include "auxtrace.h"
19 #include "color.h"
20 #include "cs-etm.h"
21 #include "cs-etm-decoder/cs-etm-decoder.h"
22 #include "debug.h"
23 #include "evlist.h"
24 #include "intlist.h"
25 #include "machine.h"
26 #include "map.h"
27 #include "perf.h"
28 #include "thread.h"
29 #include "thread_map.h"
30 #include "thread-stack.h"
31 #include "util.h"
32 
33 #define MAX_TIMESTAMP (~0ULL)
34 
35 struct cs_etm_auxtrace {
36 	struct auxtrace auxtrace;
37 	struct auxtrace_queues queues;
38 	struct auxtrace_heap heap;
39 	struct itrace_synth_opts synth_opts;
40 	struct perf_session *session;
41 	struct machine *machine;
42 	struct thread *unknown_thread;
43 
44 	u8 timeless_decoding;
45 	u8 snapshot_mode;
46 	u8 data_queued;
47 	u8 sample_branches;
48 
49 	int num_cpu;
50 	u32 auxtrace_type;
51 	u64 branches_sample_type;
52 	u64 branches_id;
53 	u64 **metadata;
54 	u64 kernel_start;
55 	unsigned int pmu_type;
56 };
57 
58 struct cs_etm_queue {
59 	struct cs_etm_auxtrace *etm;
60 	struct thread *thread;
61 	struct cs_etm_decoder *decoder;
62 	struct auxtrace_buffer *buffer;
63 	const struct cs_etm_state *state;
64 	union perf_event *event_buf;
65 	unsigned int queue_nr;
66 	pid_t pid, tid;
67 	int cpu;
68 	u64 time;
69 	u64 timestamp;
70 	u64 offset;
71 };
72 
73 static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);
74 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
75 					   pid_t tid, u64 time_);
76 
77 static void cs_etm__packet_dump(const char *pkt_string)
78 {
79 	const char *color = PERF_COLOR_BLUE;
80 	int len = strlen(pkt_string);
81 
82 	if (len && (pkt_string[len-1] == '\n'))
83 		color_fprintf(stdout, color, "	%s", pkt_string);
84 	else
85 		color_fprintf(stdout, color, "	%s\n", pkt_string);
86 
87 	fflush(stdout);
88 }
89 
90 static void cs_etm__dump_event(struct cs_etm_auxtrace *etm,
91 			       struct auxtrace_buffer *buffer)
92 {
93 	int i, ret;
94 	const char *color = PERF_COLOR_BLUE;
95 	struct cs_etm_decoder_params d_params;
96 	struct cs_etm_trace_params *t_params;
97 	struct cs_etm_decoder *decoder;
98 	size_t buffer_used = 0;
99 
100 	fprintf(stdout, "\n");
101 	color_fprintf(stdout, color,
102 		     ". ... CoreSight ETM Trace data: size %zu bytes\n",
103 		     buffer->size);
104 
105 	/* Use metadata to fill in trace parameters for trace decoder */
106 	t_params = zalloc(sizeof(*t_params) * etm->num_cpu);
107 	for (i = 0; i < etm->num_cpu; i++) {
108 		t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
109 		t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
110 		t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
111 		t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
112 		t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
113 		t_params[i].etmv4.reg_configr =
114 					etm->metadata[i][CS_ETMV4_TRCCONFIGR];
115 		t_params[i].etmv4.reg_traceidr =
116 					etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
117 	}
118 
119 	/* Set decoder parameters to simply print the trace packets */
120 	d_params.packet_printer = cs_etm__packet_dump;
121 	d_params.operation = CS_ETM_OPERATION_PRINT;
122 	d_params.formatted = true;
123 	d_params.fsyncs = false;
124 	d_params.hsyncs = false;
125 	d_params.frame_aligned = true;
126 
127 	decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);
128 
129 	zfree(&t_params);
130 
131 	if (!decoder)
132 		return;
133 	do {
134 		size_t consumed;
135 
136 		ret = cs_etm_decoder__process_data_block(
137 				decoder, buffer->offset,
138 				&((u8 *)buffer->data)[buffer_used],
139 				buffer->size - buffer_used, &consumed);
140 		if (ret)
141 			break;
142 
143 		buffer_used += consumed;
144 	} while (buffer_used < buffer->size);
145 
146 	cs_etm_decoder__free(decoder);
147 }
148 
149 static int cs_etm__flush_events(struct perf_session *session,
150 				struct perf_tool *tool)
151 {
152 	int ret;
153 	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
154 						   struct cs_etm_auxtrace,
155 						   auxtrace);
156 	if (dump_trace)
157 		return 0;
158 
159 	if (!tool->ordered_events)
160 		return -EINVAL;
161 
162 	if (!etm->timeless_decoding)
163 		return -EINVAL;
164 
165 	ret = cs_etm__update_queues(etm);
166 
167 	if (ret < 0)
168 		return ret;
169 
170 	return cs_etm__process_timeless_queues(etm, -1, MAX_TIMESTAMP - 1);
171 }
172 
173 static void cs_etm__free_queue(void *priv)
174 {
175 	struct cs_etm_queue *etmq = priv;
176 
177 	free(etmq);
178 }
179 
180 static void cs_etm__free_events(struct perf_session *session)
181 {
182 	unsigned int i;
183 	struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
184 						   struct cs_etm_auxtrace,
185 						   auxtrace);
186 	struct auxtrace_queues *queues = &aux->queues;
187 
188 	for (i = 0; i < queues->nr_queues; i++) {
189 		cs_etm__free_queue(queues->queue_array[i].priv);
190 		queues->queue_array[i].priv = NULL;
191 	}
192 
193 	auxtrace_queues__free(queues);
194 }
195 
196 static void cs_etm__free(struct perf_session *session)
197 {
198 	int i;
199 	struct int_node *inode, *tmp;
200 	struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
201 						   struct cs_etm_auxtrace,
202 						   auxtrace);
203 	cs_etm__free_events(session);
204 	session->auxtrace = NULL;
205 
206 	/* First remove all traceID/CPU# nodes for the RB tree */
207 	intlist__for_each_entry_safe(inode, tmp, traceid_list)
208 		intlist__remove(traceid_list, inode);
209 	/* Then the RB tree itself */
210 	intlist__delete(traceid_list);
211 
212 	for (i = 0; i < aux->num_cpu; i++)
213 		zfree(&aux->metadata[i]);
214 
215 	zfree(&aux->metadata);
216 	zfree(&aux);
217 }
218 
219 static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address,
220 			      size_t size, u8 *buffer)
221 {
222 	u8  cpumode;
223 	u64 offset;
224 	int len;
225 	struct	 thread *thread;
226 	struct	 machine *machine;
227 	struct	 addr_location al;
228 
229 	if (!etmq)
230 		return -1;
231 
232 	machine = etmq->etm->machine;
233 	if (address >= etmq->etm->kernel_start)
234 		cpumode = PERF_RECORD_MISC_KERNEL;
235 	else
236 		cpumode = PERF_RECORD_MISC_USER;
237 
238 	thread = etmq->thread;
239 	if (!thread) {
240 		if (cpumode != PERF_RECORD_MISC_KERNEL)
241 			return -EINVAL;
242 		thread = etmq->etm->unknown_thread;
243 	}
244 
245 	thread__find_addr_map(thread, cpumode, MAP__FUNCTION, address, &al);
246 
247 	if (!al.map || !al.map->dso)
248 		return 0;
249 
250 	if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
251 	    dso__data_status_seen(al.map->dso, DSO_DATA_STATUS_SEEN_ITRACE))
252 		return 0;
253 
254 	offset = al.map->map_ip(al.map, address);
255 
256 	map__load(al.map);
257 
258 	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
259 
260 	if (len <= 0)
261 		return 0;
262 
263 	return len;
264 }
265 
266 static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm,
267 						unsigned int queue_nr)
268 {
269 	int i;
270 	struct cs_etm_decoder_params d_params;
271 	struct cs_etm_trace_params  *t_params;
272 	struct cs_etm_queue *etmq;
273 
274 	etmq = zalloc(sizeof(*etmq));
275 	if (!etmq)
276 		return NULL;
277 
278 	etmq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
279 	if (!etmq->event_buf)
280 		goto out_free;
281 
282 	etmq->etm = etm;
283 	etmq->queue_nr = queue_nr;
284 	etmq->pid = -1;
285 	etmq->tid = -1;
286 	etmq->cpu = -1;
287 
288 	/* Use metadata to fill in trace parameters for trace decoder */
289 	t_params = zalloc(sizeof(*t_params) * etm->num_cpu);
290 
291 	if (!t_params)
292 		goto out_free;
293 
294 	for (i = 0; i < etm->num_cpu; i++) {
295 		t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
296 		t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
297 		t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
298 		t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
299 		t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
300 		t_params[i].etmv4.reg_configr =
301 					etm->metadata[i][CS_ETMV4_TRCCONFIGR];
302 		t_params[i].etmv4.reg_traceidr =
303 					etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
304 	}
305 
306 	/* Set decoder parameters to simply print the trace packets */
307 	d_params.packet_printer = cs_etm__packet_dump;
308 	d_params.operation = CS_ETM_OPERATION_DECODE;
309 	d_params.formatted = true;
310 	d_params.fsyncs = false;
311 	d_params.hsyncs = false;
312 	d_params.frame_aligned = true;
313 	d_params.data = etmq;
314 
315 	etmq->decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);
316 
317 	zfree(&t_params);
318 
319 	if (!etmq->decoder)
320 		goto out_free;
321 
322 	/*
323 	 * Register a function to handle all memory accesses required by
324 	 * the trace decoder library.
325 	 */
326 	if (cs_etm_decoder__add_mem_access_cb(etmq->decoder,
327 					      0x0L, ((u64) -1L),
328 					      cs_etm__mem_access))
329 		goto out_free_decoder;
330 
331 	etmq->offset = 0;
332 
333 	return etmq;
334 
335 out_free_decoder:
336 	cs_etm_decoder__free(etmq->decoder);
337 out_free:
338 	zfree(&etmq->event_buf);
339 	free(etmq);
340 
341 	return NULL;
342 }
343 
344 static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm,
345 			       struct auxtrace_queue *queue,
346 			       unsigned int queue_nr)
347 {
348 	struct cs_etm_queue *etmq = queue->priv;
349 
350 	if (list_empty(&queue->head) || etmq)
351 		return 0;
352 
353 	etmq = cs_etm__alloc_queue(etm, queue_nr);
354 
355 	if (!etmq)
356 		return -ENOMEM;
357 
358 	queue->priv = etmq;
359 
360 	if (queue->cpu != -1)
361 		etmq->cpu = queue->cpu;
362 
363 	etmq->tid = queue->tid;
364 
365 	return 0;
366 }
367 
368 static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm)
369 {
370 	unsigned int i;
371 	int ret;
372 
373 	for (i = 0; i < etm->queues.nr_queues; i++) {
374 		ret = cs_etm__setup_queue(etm, &etm->queues.queue_array[i], i);
375 		if (ret)
376 			return ret;
377 	}
378 
379 	return 0;
380 }
381 
382 static int cs_etm__update_queues(struct cs_etm_auxtrace *etm)
383 {
384 	if (etm->queues.new_data) {
385 		etm->queues.new_data = false;
386 		return cs_etm__setup_queues(etm);
387 	}
388 
389 	return 0;
390 }
391 
392 static int
393 cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq)
394 {
395 	struct auxtrace_buffer *aux_buffer = etmq->buffer;
396 	struct auxtrace_buffer *old_buffer = aux_buffer;
397 	struct auxtrace_queue *queue;
398 
399 	queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
400 
401 	aux_buffer = auxtrace_buffer__next(queue, aux_buffer);
402 
403 	/* If no more data, drop the previous auxtrace_buffer and return */
404 	if (!aux_buffer) {
405 		if (old_buffer)
406 			auxtrace_buffer__drop_data(old_buffer);
407 		buff->len = 0;
408 		return 0;
409 	}
410 
411 	etmq->buffer = aux_buffer;
412 
413 	/* If the aux_buffer doesn't have data associated, try to load it */
414 	if (!aux_buffer->data) {
415 		/* get the file desc associated with the perf data file */
416 		int fd = perf_data__fd(etmq->etm->session->data);
417 
418 		aux_buffer->data = auxtrace_buffer__get_data(aux_buffer, fd);
419 		if (!aux_buffer->data)
420 			return -ENOMEM;
421 	}
422 
423 	/* If valid, drop the previous buffer */
424 	if (old_buffer)
425 		auxtrace_buffer__drop_data(old_buffer);
426 
427 	buff->offset = aux_buffer->offset;
428 	buff->len = aux_buffer->size;
429 	buff->buf = aux_buffer->data;
430 
431 	buff->ref_timestamp = aux_buffer->reference;
432 
433 	return buff->len;
434 }
435 
436 static void  cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
437 				     struct auxtrace_queue *queue)
438 {
439 	struct cs_etm_queue *etmq = queue->priv;
440 
441 	/* CPU-wide tracing isn't supported yet */
442 	if (queue->tid == -1)
443 		return;
444 
445 	if ((!etmq->thread) && (etmq->tid != -1))
446 		etmq->thread = machine__find_thread(etm->machine, -1,
447 						    etmq->tid);
448 
449 	if (etmq->thread) {
450 		etmq->pid = etmq->thread->pid_;
451 		if (queue->cpu == -1)
452 			etmq->cpu = etmq->thread->cpu;
453 	}
454 }
455 
456 /*
457  * The cs etm packet encodes an instruction range between a branch target
458  * and the next taken branch. Generate sample accordingly.
459  */
460 static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
461 				       struct cs_etm_packet *packet)
462 {
463 	int ret = 0;
464 	struct cs_etm_auxtrace *etm = etmq->etm;
465 	struct perf_sample sample = {.ip = 0,};
466 	union perf_event *event = etmq->event_buf;
467 	u64 start_addr = packet->start_addr;
468 	u64 end_addr = packet->end_addr;
469 
470 	event->sample.header.type = PERF_RECORD_SAMPLE;
471 	event->sample.header.misc = PERF_RECORD_MISC_USER;
472 	event->sample.header.size = sizeof(struct perf_event_header);
473 
474 	sample.ip = start_addr;
475 	sample.pid = etmq->pid;
476 	sample.tid = etmq->tid;
477 	sample.addr = end_addr;
478 	sample.id = etmq->etm->branches_id;
479 	sample.stream_id = etmq->etm->branches_id;
480 	sample.period = 1;
481 	sample.cpu = packet->cpu;
482 	sample.flags = 0;
483 	sample.cpumode = PERF_RECORD_MISC_USER;
484 
485 	ret = perf_session__deliver_synth_event(etm->session, event, &sample);
486 
487 	if (ret)
488 		pr_err(
489 		"CS ETM Trace: failed to deliver instruction event, error %d\n",
490 		ret);
491 
492 	return ret;
493 }
494 
495 struct cs_etm_synth {
496 	struct perf_tool dummy_tool;
497 	struct perf_session *session;
498 };
499 
500 static int cs_etm__event_synth(struct perf_tool *tool,
501 			       union perf_event *event,
502 			       struct perf_sample *sample __maybe_unused,
503 			       struct machine *machine __maybe_unused)
504 {
505 	struct cs_etm_synth *cs_etm_synth =
506 		      container_of(tool, struct cs_etm_synth, dummy_tool);
507 
508 	return perf_session__deliver_synth_event(cs_etm_synth->session,
509 						 event, NULL);
510 }
511 
512 static int cs_etm__synth_event(struct perf_session *session,
513 			       struct perf_event_attr *attr, u64 id)
514 {
515 	struct cs_etm_synth cs_etm_synth;
516 
517 	memset(&cs_etm_synth, 0, sizeof(struct cs_etm_synth));
518 	cs_etm_synth.session = session;
519 
520 	return perf_event__synthesize_attr(&cs_etm_synth.dummy_tool, attr, 1,
521 					   &id, cs_etm__event_synth);
522 }
523 
524 static int cs_etm__synth_events(struct cs_etm_auxtrace *etm,
525 				struct perf_session *session)
526 {
527 	struct perf_evlist *evlist = session->evlist;
528 	struct perf_evsel *evsel;
529 	struct perf_event_attr attr;
530 	bool found = false;
531 	u64 id;
532 	int err;
533 
534 	evlist__for_each_entry(evlist, evsel) {
535 		if (evsel->attr.type == etm->pmu_type) {
536 			found = true;
537 			break;
538 		}
539 	}
540 
541 	if (!found) {
542 		pr_debug("No selected events with CoreSight Trace data\n");
543 		return 0;
544 	}
545 
546 	memset(&attr, 0, sizeof(struct perf_event_attr));
547 	attr.size = sizeof(struct perf_event_attr);
548 	attr.type = PERF_TYPE_HARDWARE;
549 	attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK;
550 	attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
551 			    PERF_SAMPLE_PERIOD;
552 	if (etm->timeless_decoding)
553 		attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
554 	else
555 		attr.sample_type |= PERF_SAMPLE_TIME;
556 
557 	attr.exclude_user = evsel->attr.exclude_user;
558 	attr.exclude_kernel = evsel->attr.exclude_kernel;
559 	attr.exclude_hv = evsel->attr.exclude_hv;
560 	attr.exclude_host = evsel->attr.exclude_host;
561 	attr.exclude_guest = evsel->attr.exclude_guest;
562 	attr.sample_id_all = evsel->attr.sample_id_all;
563 	attr.read_format = evsel->attr.read_format;
564 
565 	/* create new id val to be a fixed offset from evsel id */
566 	id = evsel->id[0] + 1000000000;
567 
568 	if (!id)
569 		id = 1;
570 
571 	if (etm->synth_opts.branches) {
572 		attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
573 		attr.sample_period = 1;
574 		attr.sample_type |= PERF_SAMPLE_ADDR;
575 		err = cs_etm__synth_event(session, &attr, id);
576 		if (err)
577 			return err;
578 		etm->sample_branches = true;
579 		etm->branches_sample_type = attr.sample_type;
580 		etm->branches_id = id;
581 	}
582 
583 	return 0;
584 }
585 
586 static int cs_etm__sample(struct cs_etm_queue *etmq)
587 {
588 	int ret;
589 	struct cs_etm_packet packet;
590 
591 	while (1) {
592 		ret = cs_etm_decoder__get_packet(etmq->decoder, &packet);
593 		if (ret <= 0)
594 			return ret;
595 
596 		/*
597 		 * If the packet contains an instruction range, generate an
598 		 * instruction sequence event.
599 		 */
600 		if (packet.sample_type & CS_ETM_RANGE)
601 			cs_etm__synth_branch_sample(etmq, &packet);
602 	}
603 
604 	return 0;
605 }
606 
607 static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
608 {
609 	struct cs_etm_auxtrace *etm = etmq->etm;
610 	struct cs_etm_buffer buffer;
611 	size_t buffer_used, processed;
612 	int err = 0;
613 
614 	if (!etm->kernel_start)
615 		etm->kernel_start = machine__kernel_start(etm->machine);
616 
617 	/* Go through each buffer in the queue and decode them one by one */
618 more:
619 	buffer_used = 0;
620 	memset(&buffer, 0, sizeof(buffer));
621 	err = cs_etm__get_trace(&buffer, etmq);
622 	if (err <= 0)
623 		return err;
624 	/*
625 	 * We cannot assume consecutive blocks in the data file are contiguous,
626 	 * reset the decoder to force re-sync.
627 	 */
628 	err = cs_etm_decoder__reset(etmq->decoder);
629 	if (err != 0)
630 		return err;
631 
632 	/* Run trace decoder until buffer consumed or end of trace */
633 	do {
634 		processed = 0;
635 
636 		err = cs_etm_decoder__process_data_block(
637 						etmq->decoder,
638 						etmq->offset,
639 						&buffer.buf[buffer_used],
640 						buffer.len - buffer_used,
641 						&processed);
642 
643 		if (err)
644 			return err;
645 
646 		etmq->offset += processed;
647 		buffer_used += processed;
648 
649 		/*
650 		 * Nothing to do with an error condition, let's hope the next
651 		 * chunk will be better.
652 		 */
653 		err = cs_etm__sample(etmq);
654 	} while (buffer.len > buffer_used);
655 
656 goto more;
657 
658 	return err;
659 }
660 
661 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
662 					   pid_t tid, u64 time_)
663 {
664 	unsigned int i;
665 	struct auxtrace_queues *queues = &etm->queues;
666 
667 	for (i = 0; i < queues->nr_queues; i++) {
668 		struct auxtrace_queue *queue = &etm->queues.queue_array[i];
669 		struct cs_etm_queue *etmq = queue->priv;
670 
671 		if (etmq && ((tid == -1) || (etmq->tid == tid))) {
672 			etmq->time = time_;
673 			cs_etm__set_pid_tid_cpu(etm, queue);
674 			cs_etm__run_decoder(etmq);
675 		}
676 	}
677 
678 	return 0;
679 }
680 
681 static int cs_etm__process_event(struct perf_session *session,
682 				 union perf_event *event,
683 				 struct perf_sample *sample,
684 				 struct perf_tool *tool)
685 {
686 	int err = 0;
687 	u64 timestamp;
688 	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
689 						   struct cs_etm_auxtrace,
690 						   auxtrace);
691 
692 	if (dump_trace)
693 		return 0;
694 
695 	if (!tool->ordered_events) {
696 		pr_err("CoreSight ETM Trace requires ordered events\n");
697 		return -EINVAL;
698 	}
699 
700 	if (!etm->timeless_decoding)
701 		return -EINVAL;
702 
703 	if (sample->time && (sample->time != (u64) -1))
704 		timestamp = sample->time;
705 	else
706 		timestamp = 0;
707 
708 	if (timestamp || etm->timeless_decoding) {
709 		err = cs_etm__update_queues(etm);
710 		if (err)
711 			return err;
712 	}
713 
714 	if (event->header.type == PERF_RECORD_EXIT)
715 		return cs_etm__process_timeless_queues(etm,
716 						       event->fork.tid,
717 						       sample->time);
718 
719 	return 0;
720 }
721 
722 static int cs_etm__process_auxtrace_event(struct perf_session *session,
723 					  union perf_event *event,
724 					  struct perf_tool *tool __maybe_unused)
725 {
726 	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
727 						   struct cs_etm_auxtrace,
728 						   auxtrace);
729 	if (!etm->data_queued) {
730 		struct auxtrace_buffer *buffer;
731 		off_t  data_offset;
732 		int fd = perf_data__fd(session->data);
733 		bool is_pipe = perf_data__is_pipe(session->data);
734 		int err;
735 
736 		if (is_pipe)
737 			data_offset = 0;
738 		else {
739 			data_offset = lseek(fd, 0, SEEK_CUR);
740 			if (data_offset == -1)
741 				return -errno;
742 		}
743 
744 		err = auxtrace_queues__add_event(&etm->queues, session,
745 						 event, data_offset, &buffer);
746 		if (err)
747 			return err;
748 
749 		if (dump_trace)
750 			if (auxtrace_buffer__get_data(buffer, fd)) {
751 				cs_etm__dump_event(etm, buffer);
752 				auxtrace_buffer__put_data(buffer);
753 			}
754 	}
755 
756 	return 0;
757 }
758 
759 static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
760 {
761 	struct perf_evsel *evsel;
762 	struct perf_evlist *evlist = etm->session->evlist;
763 	bool timeless_decoding = true;
764 
765 	/*
766 	 * Circle through the list of event and complain if we find one
767 	 * with the time bit set.
768 	 */
769 	evlist__for_each_entry(evlist, evsel) {
770 		if ((evsel->attr.sample_type & PERF_SAMPLE_TIME))
771 			timeless_decoding = false;
772 	}
773 
774 	return timeless_decoding;
775 }
776 
777 static const char * const cs_etm_global_header_fmts[] = {
778 	[CS_HEADER_VERSION_0]	= "	Header version		       %llx\n",
779 	[CS_PMU_TYPE_CPUS]	= "	PMU type/num cpus	       %llx\n",
780 	[CS_ETM_SNAPSHOT]	= "	Snapshot		       %llx\n",
781 };
782 
783 static const char * const cs_etm_priv_fmts[] = {
784 	[CS_ETM_MAGIC]		= "	Magic number		       %llx\n",
785 	[CS_ETM_CPU]		= "	CPU			       %lld\n",
786 	[CS_ETM_ETMCR]		= "	ETMCR			       %llx\n",
787 	[CS_ETM_ETMTRACEIDR]	= "	ETMTRACEIDR		       %llx\n",
788 	[CS_ETM_ETMCCER]	= "	ETMCCER			       %llx\n",
789 	[CS_ETM_ETMIDR]		= "	ETMIDR			       %llx\n",
790 };
791 
792 static const char * const cs_etmv4_priv_fmts[] = {
793 	[CS_ETM_MAGIC]		= "	Magic number		       %llx\n",
794 	[CS_ETM_CPU]		= "	CPU			       %lld\n",
795 	[CS_ETMV4_TRCCONFIGR]	= "	TRCCONFIGR		       %llx\n",
796 	[CS_ETMV4_TRCTRACEIDR]	= "	TRCTRACEIDR		       %llx\n",
797 	[CS_ETMV4_TRCIDR0]	= "	TRCIDR0			       %llx\n",
798 	[CS_ETMV4_TRCIDR1]	= "	TRCIDR1			       %llx\n",
799 	[CS_ETMV4_TRCIDR2]	= "	TRCIDR2			       %llx\n",
800 	[CS_ETMV4_TRCIDR8]	= "	TRCIDR8			       %llx\n",
801 	[CS_ETMV4_TRCAUTHSTATUS] = "	TRCAUTHSTATUS		       %llx\n",
802 };
803 
804 static void cs_etm__print_auxtrace_info(u64 *val, int num)
805 {
806 	int i, j, cpu = 0;
807 
808 	for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
809 		fprintf(stdout, cs_etm_global_header_fmts[i], val[i]);
810 
811 	for (i = CS_HEADER_VERSION_0_MAX; cpu < num; cpu++) {
812 		if (val[i] == __perf_cs_etmv3_magic)
813 			for (j = 0; j < CS_ETM_PRIV_MAX; j++, i++)
814 				fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
815 		else if (val[i] == __perf_cs_etmv4_magic)
816 			for (j = 0; j < CS_ETMV4_PRIV_MAX; j++, i++)
817 				fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
818 		else
819 			/* failure.. return */
820 			return;
821 	}
822 }
823 
824 int cs_etm__process_auxtrace_info(union perf_event *event,
825 				  struct perf_session *session)
826 {
827 	struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info;
828 	struct cs_etm_auxtrace *etm = NULL;
829 	struct int_node *inode;
830 	unsigned int pmu_type;
831 	int event_header_size = sizeof(struct perf_event_header);
832 	int info_header_size;
833 	int total_size = auxtrace_info->header.size;
834 	int priv_size = 0;
835 	int num_cpu;
836 	int err = 0, idx = -1;
837 	int i, j, k;
838 	u64 *ptr, *hdr = NULL;
839 	u64 **metadata = NULL;
840 
841 	/*
842 	 * sizeof(auxtrace_info_event::type) +
843 	 * sizeof(auxtrace_info_event::reserved) == 8
844 	 */
845 	info_header_size = 8;
846 
847 	if (total_size < (event_header_size + info_header_size))
848 		return -EINVAL;
849 
850 	priv_size = total_size - event_header_size - info_header_size;
851 
852 	/* First the global part */
853 	ptr = (u64 *) auxtrace_info->priv;
854 
855 	/* Look for version '0' of the header */
856 	if (ptr[0] != 0)
857 		return -EINVAL;
858 
859 	hdr = zalloc(sizeof(*hdr) * CS_HEADER_VERSION_0_MAX);
860 	if (!hdr)
861 		return -ENOMEM;
862 
863 	/* Extract header information - see cs-etm.h for format */
864 	for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
865 		hdr[i] = ptr[i];
866 	num_cpu = hdr[CS_PMU_TYPE_CPUS] & 0xffffffff;
867 	pmu_type = (unsigned int) ((hdr[CS_PMU_TYPE_CPUS] >> 32) &
868 				    0xffffffff);
869 
870 	/*
871 	 * Create an RB tree for traceID-CPU# tuple. Since the conversion has
872 	 * to be made for each packet that gets decoded, optimizing access in
873 	 * anything other than a sequential array is worth doing.
874 	 */
875 	traceid_list = intlist__new(NULL);
876 	if (!traceid_list) {
877 		err = -ENOMEM;
878 		goto err_free_hdr;
879 	}
880 
881 	metadata = zalloc(sizeof(*metadata) * num_cpu);
882 	if (!metadata) {
883 		err = -ENOMEM;
884 		goto err_free_traceid_list;
885 	}
886 
887 	/*
888 	 * The metadata is stored in the auxtrace_info section and encodes
889 	 * the configuration of the ARM embedded trace macrocell which is
890 	 * required by the trace decoder to properly decode the trace due
891 	 * to its highly compressed nature.
892 	 */
893 	for (j = 0; j < num_cpu; j++) {
894 		if (ptr[i] == __perf_cs_etmv3_magic) {
895 			metadata[j] = zalloc(sizeof(*metadata[j]) *
896 					     CS_ETM_PRIV_MAX);
897 			if (!metadata[j]) {
898 				err = -ENOMEM;
899 				goto err_free_metadata;
900 			}
901 			for (k = 0; k < CS_ETM_PRIV_MAX; k++)
902 				metadata[j][k] = ptr[i + k];
903 
904 			/* The traceID is our handle */
905 			idx = metadata[j][CS_ETM_ETMTRACEIDR];
906 			i += CS_ETM_PRIV_MAX;
907 		} else if (ptr[i] == __perf_cs_etmv4_magic) {
908 			metadata[j] = zalloc(sizeof(*metadata[j]) *
909 					     CS_ETMV4_PRIV_MAX);
910 			if (!metadata[j]) {
911 				err = -ENOMEM;
912 				goto err_free_metadata;
913 			}
914 			for (k = 0; k < CS_ETMV4_PRIV_MAX; k++)
915 				metadata[j][k] = ptr[i + k];
916 
917 			/* The traceID is our handle */
918 			idx = metadata[j][CS_ETMV4_TRCTRACEIDR];
919 			i += CS_ETMV4_PRIV_MAX;
920 		}
921 
922 		/* Get an RB node for this CPU */
923 		inode = intlist__findnew(traceid_list, idx);
924 
925 		/* Something went wrong, no need to continue */
926 		if (!inode) {
927 			err = PTR_ERR(inode);
928 			goto err_free_metadata;
929 		}
930 
931 		/*
932 		 * The node for that CPU should not be taken.
933 		 * Back out if that's the case.
934 		 */
935 		if (inode->priv) {
936 			err = -EINVAL;
937 			goto err_free_metadata;
938 		}
939 		/* All good, associate the traceID with the CPU# */
940 		inode->priv = &metadata[j][CS_ETM_CPU];
941 	}
942 
943 	/*
944 	 * Each of CS_HEADER_VERSION_0_MAX, CS_ETM_PRIV_MAX and
945 	 * CS_ETMV4_PRIV_MAX mark how many double words are in the
946 	 * global metadata, and each cpu's metadata respectively.
947 	 * The following tests if the correct number of double words was
948 	 * present in the auxtrace info section.
949 	 */
950 	if (i * 8 != priv_size) {
951 		err = -EINVAL;
952 		goto err_free_metadata;
953 	}
954 
955 	etm = zalloc(sizeof(*etm));
956 
957 	if (!etm) {
958 		err = -ENOMEM;
959 		goto err_free_metadata;
960 	}
961 
962 	err = auxtrace_queues__init(&etm->queues);
963 	if (err)
964 		goto err_free_etm;
965 
966 	etm->session = session;
967 	etm->machine = &session->machines.host;
968 
969 	etm->num_cpu = num_cpu;
970 	etm->pmu_type = pmu_type;
971 	etm->snapshot_mode = (hdr[CS_ETM_SNAPSHOT] != 0);
972 	etm->metadata = metadata;
973 	etm->auxtrace_type = auxtrace_info->type;
974 	etm->timeless_decoding = cs_etm__is_timeless_decoding(etm);
975 
976 	etm->auxtrace.process_event = cs_etm__process_event;
977 	etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event;
978 	etm->auxtrace.flush_events = cs_etm__flush_events;
979 	etm->auxtrace.free_events = cs_etm__free_events;
980 	etm->auxtrace.free = cs_etm__free;
981 	session->auxtrace = &etm->auxtrace;
982 
983 	if (dump_trace) {
984 		cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
985 		return 0;
986 	}
987 
988 	if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
989 		etm->synth_opts = *session->itrace_synth_opts;
990 	} else {
991 		itrace_synth_opts__set_default(&etm->synth_opts);
992 		etm->synth_opts.callchain = false;
993 	}
994 
995 	err = cs_etm__synth_events(etm, session);
996 	if (err)
997 		goto err_free_queues;
998 
999 	err = auxtrace_queues__process_index(&etm->queues, session);
1000 	if (err)
1001 		goto err_free_queues;
1002 
1003 	etm->data_queued = etm->queues.populated;
1004 
1005 	return 0;
1006 
1007 err_free_queues:
1008 	auxtrace_queues__free(&etm->queues);
1009 	session->auxtrace = NULL;
1010 err_free_etm:
1011 	zfree(&etm);
1012 err_free_metadata:
1013 	/* No need to check @metadata[j], free(NULL) is supported */
1014 	for (j = 0; j < num_cpu; j++)
1015 		free(metadata[j]);
1016 	zfree(&metadata);
1017 err_free_traceid_list:
1018 	intlist__delete(traceid_list);
1019 err_free_hdr:
1020 	zfree(&hdr);
1021 
1022 	return -EINVAL;
1023 }
1024