1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Arm Statistical Profiling Extensions (SPE) support
4 * Copyright (c) 2017-2018, Arm Ltd.
5 */
6
7#include <byteswap.h>
8#include <endian.h>
9#include <errno.h>
10#include <inttypes.h>
11#include <linux/bitops.h>
12#include <linux/kernel.h>
13#include <linux/log2.h>
14#include <linux/types.h>
15#include <linux/zalloc.h>
16#include <stdlib.h>
17#include <unistd.h>
18
19#include "auxtrace.h"
20#include "color.h"
21#include "debug.h"
22#include "evlist.h"
23#include "evsel.h"
24#include "machine.h"
25#include "session.h"
26#include "symbol.h"
27#include "thread.h"
28#include "thread-stack.h"
29#include "tool.h"
30#include "util/synthetic-events.h"
31
32#include "arm-spe.h"
33#include "arm-spe-decoder/arm-spe-decoder.h"
34#include "arm-spe-decoder/arm-spe-pkt-decoder.h"
35
36#define MAX_TIMESTAMP (~0ULL)
37
38struct arm_spe {
39	struct auxtrace			auxtrace;
40	struct auxtrace_queues		queues;
41	struct auxtrace_heap		heap;
42	struct itrace_synth_opts        synth_opts;
43	u32				auxtrace_type;
44	struct perf_session		*session;
45	struct machine			*machine;
46	u32				pmu_type;
47
48	u8				timeless_decoding;
49	u8				data_queued;
50
51	u64				sample_type;
52	u8				sample_flc;
53	u8				sample_llc;
54	u8				sample_tlb;
55	u8				sample_branch;
56	u8				sample_remote_access;
57
58	u64				l1d_miss_id;
59	u64				l1d_access_id;
60	u64				llc_miss_id;
61	u64				llc_access_id;
62	u64				tlb_miss_id;
63	u64				tlb_access_id;
64	u64				branch_miss_id;
65	u64				remote_access_id;
66
67	u64				kernel_start;
68
69	unsigned long			num_events;
70};
71
72struct arm_spe_queue {
73	struct arm_spe			*spe;
74	unsigned int			queue_nr;
75	struct auxtrace_buffer		*buffer;
76	struct auxtrace_buffer		*old_buffer;
77	union perf_event		*event_buf;
78	bool				on_heap;
79	bool				done;
80	pid_t				pid;
81	pid_t				tid;
82	int				cpu;
83	struct arm_spe_decoder		*decoder;
84	u64				time;
85	u64				timestamp;
86	struct thread			*thread;
87};
88
89static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
90			 unsigned char *buf, size_t len)
91{
92	struct arm_spe_pkt packet;
93	size_t pos = 0;
94	int ret, pkt_len, i;
95	char desc[ARM_SPE_PKT_DESC_MAX];
96	const char *color = PERF_COLOR_BLUE;
97
98	color_fprintf(stdout, color,
99		      ". ... ARM SPE data: size %zu bytes\n",
100		      len);
101
102	while (len) {
103		ret = arm_spe_get_packet(buf, len, &packet);
104		if (ret > 0)
105			pkt_len = ret;
106		else
107			pkt_len = 1;
108		printf(".");
109		color_fprintf(stdout, color, "  %08x: ", pos);
110		for (i = 0; i < pkt_len; i++)
111			color_fprintf(stdout, color, " %02x", buf[i]);
112		for (; i < 16; i++)
113			color_fprintf(stdout, color, "   ");
114		if (ret > 0) {
115			ret = arm_spe_pkt_desc(&packet, desc,
116					       ARM_SPE_PKT_DESC_MAX);
117			if (ret > 0)
118				color_fprintf(stdout, color, " %s\n", desc);
119		} else {
120			color_fprintf(stdout, color, " Bad packet!\n");
121		}
122		pos += pkt_len;
123		buf += pkt_len;
124		len -= pkt_len;
125	}
126}
127
128static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
129			       size_t len)
130{
131	printf(".\n");
132	arm_spe_dump(spe, buf, len);
133}
134
135static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
136{
137	struct arm_spe_queue *speq = data;
138	struct auxtrace_buffer *buffer = speq->buffer;
139	struct auxtrace_buffer *old_buffer = speq->old_buffer;
140	struct auxtrace_queue *queue;
141
142	queue = &speq->spe->queues.queue_array[speq->queue_nr];
143
144	buffer = auxtrace_buffer__next(queue, buffer);
145	/* If no more data, drop the previous auxtrace_buffer and return */
146	if (!buffer) {
147		if (old_buffer)
148			auxtrace_buffer__drop_data(old_buffer);
149		b->len = 0;
150		return 0;
151	}
152
153	speq->buffer = buffer;
154
155	/* If the aux_buffer doesn't have data associated, try to load it */
156	if (!buffer->data) {
157		/* get the file desc associated with the perf data file */
158		int fd = perf_data__fd(speq->spe->session->data);
159
160		buffer->data = auxtrace_buffer__get_data(buffer, fd);
161		if (!buffer->data)
162			return -ENOMEM;
163	}
164
165	b->len = buffer->size;
166	b->buf = buffer->data;
167
168	if (b->len) {
169		if (old_buffer)
170			auxtrace_buffer__drop_data(old_buffer);
171		speq->old_buffer = buffer;
172	} else {
173		auxtrace_buffer__drop_data(buffer);
174		return arm_spe_get_trace(b, data);
175	}
176
177	return 0;
178}
179
180static struct arm_spe_queue *arm_spe__alloc_queue(struct arm_spe *spe,
181		unsigned int queue_nr)
182{
183	struct arm_spe_params params = { .get_trace = 0, };
184	struct arm_spe_queue *speq;
185
186	speq = zalloc(sizeof(*speq));
187	if (!speq)
188		return NULL;
189
190	speq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
191	if (!speq->event_buf)
192		goto out_free;
193
194	speq->spe = spe;
195	speq->queue_nr = queue_nr;
196	speq->pid = -1;
197	speq->tid = -1;
198	speq->cpu = -1;
199
200	/* params set */
201	params.get_trace = arm_spe_get_trace;
202	params.data = speq;
203
204	/* create new decoder */
205	speq->decoder = arm_spe_decoder_new(&params);
206	if (!speq->decoder)
207		goto out_free;
208
209	return speq;
210
211out_free:
212	zfree(&speq->event_buf);
213	free(speq);
214
215	return NULL;
216}
217
218static inline u8 arm_spe_cpumode(struct arm_spe *spe, u64 ip)
219{
220	return ip >= spe->kernel_start ?
221		PERF_RECORD_MISC_KERNEL :
222		PERF_RECORD_MISC_USER;
223}
224
225static void arm_spe_prep_sample(struct arm_spe *spe,
226				struct arm_spe_queue *speq,
227				union perf_event *event,
228				struct perf_sample *sample)
229{
230	struct arm_spe_record *record = &speq->decoder->record;
231
232	if (!spe->timeless_decoding)
233		sample->time = speq->timestamp;
234
235	sample->ip = record->from_ip;
236	sample->cpumode = arm_spe_cpumode(spe, sample->ip);
237	sample->pid = speq->pid;
238	sample->tid = speq->tid;
239	sample->addr = record->to_ip;
240	sample->period = 1;
241	sample->cpu = speq->cpu;
242
243	event->sample.header.type = PERF_RECORD_SAMPLE;
244	event->sample.header.misc = sample->cpumode;
245	event->sample.header.size = sizeof(struct perf_event_header);
246}
247
248static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
249{
250	event->header.size = perf_event__sample_event_size(sample, type, 0);
251	return perf_event__synthesize_sample(event, type, 0, sample);
252}
253
254static inline int
255arm_spe_deliver_synth_event(struct arm_spe *spe,
256			    struct arm_spe_queue *speq __maybe_unused,
257			    union perf_event *event,
258			    struct perf_sample *sample)
259{
260	int ret;
261
262	if (spe->synth_opts.inject) {
263		ret = arm_spe__inject_event(event, sample, spe->sample_type);
264		if (ret)
265			return ret;
266	}
267
268	ret = perf_session__deliver_synth_event(spe->session, event, sample);
269	if (ret)
270		pr_err("ARM SPE: failed to deliver event, error %d\n", ret);
271
272	return ret;
273}
274
275static int
276arm_spe_synth_spe_events_sample(struct arm_spe_queue *speq,
277				u64 spe_events_id)
278{
279	struct arm_spe *spe = speq->spe;
280	union perf_event *event = speq->event_buf;
281	struct perf_sample sample = { .ip = 0, };
282
283	arm_spe_prep_sample(spe, speq, event, &sample);
284
285	sample.id = spe_events_id;
286	sample.stream_id = spe_events_id;
287
288	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
289}
290
291static int arm_spe_sample(struct arm_spe_queue *speq)
292{
293	const struct arm_spe_record *record = &speq->decoder->record;
294	struct arm_spe *spe = speq->spe;
295	int err;
296
297	if (spe->sample_flc) {
298		if (record->type & ARM_SPE_L1D_MISS) {
299			err = arm_spe_synth_spe_events_sample(
300					speq, spe->l1d_miss_id);
301			if (err)
302				return err;
303		}
304
305		if (record->type & ARM_SPE_L1D_ACCESS) {
306			err = arm_spe_synth_spe_events_sample(
307					speq, spe->l1d_access_id);
308			if (err)
309				return err;
310		}
311	}
312
313	if (spe->sample_llc) {
314		if (record->type & ARM_SPE_LLC_MISS) {
315			err = arm_spe_synth_spe_events_sample(
316					speq, spe->llc_miss_id);
317			if (err)
318				return err;
319		}
320
321		if (record->type & ARM_SPE_LLC_ACCESS) {
322			err = arm_spe_synth_spe_events_sample(
323					speq, spe->llc_access_id);
324			if (err)
325				return err;
326		}
327	}
328
329	if (spe->sample_tlb) {
330		if (record->type & ARM_SPE_TLB_MISS) {
331			err = arm_spe_synth_spe_events_sample(
332					speq, spe->tlb_miss_id);
333			if (err)
334				return err;
335		}
336
337		if (record->type & ARM_SPE_TLB_ACCESS) {
338			err = arm_spe_synth_spe_events_sample(
339					speq, spe->tlb_access_id);
340			if (err)
341				return err;
342		}
343	}
344
345	if (spe->sample_branch && (record->type & ARM_SPE_BRANCH_MISS)) {
346		err = arm_spe_synth_spe_events_sample(speq,
347						      spe->branch_miss_id);
348		if (err)
349			return err;
350	}
351
352	if (spe->sample_remote_access &&
353	    (record->type & ARM_SPE_REMOTE_ACCESS)) {
354		err = arm_spe_synth_spe_events_sample(speq,
355						      spe->remote_access_id);
356		if (err)
357			return err;
358	}
359
360	return 0;
361}
362
363static int arm_spe_run_decoder(struct arm_spe_queue *speq, u64 *timestamp)
364{
365	struct arm_spe *spe = speq->spe;
366	int ret;
367
368	if (!spe->kernel_start)
369		spe->kernel_start = machine__kernel_start(spe->machine);
370
371	while (1) {
372		ret = arm_spe_decode(speq->decoder);
373		if (!ret) {
374			pr_debug("No data or all data has been processed.\n");
375			return 1;
376		}
377
378		/*
379		 * Error is detected when decode SPE trace data, continue to
380		 * the next trace data and find out more records.
381		 */
382		if (ret < 0)
383			continue;
384
385		ret = arm_spe_sample(speq);
386		if (ret)
387			return ret;
388
389		if (!spe->timeless_decoding && speq->timestamp >= *timestamp) {
390			*timestamp = speq->timestamp;
391			return 0;
392		}
393	}
394
395	return 0;
396}
397
398static int arm_spe__setup_queue(struct arm_spe *spe,
399			       struct auxtrace_queue *queue,
400			       unsigned int queue_nr)
401{
402	struct arm_spe_queue *speq = queue->priv;
403	struct arm_spe_record *record;
404
405	if (list_empty(&queue->head) || speq)
406		return 0;
407
408	speq = arm_spe__alloc_queue(spe, queue_nr);
409
410	if (!speq)
411		return -ENOMEM;
412
413	queue->priv = speq;
414
415	if (queue->cpu != -1)
416		speq->cpu = queue->cpu;
417
418	if (!speq->on_heap) {
419		int ret;
420
421		if (spe->timeless_decoding)
422			return 0;
423
424retry:
425		ret = arm_spe_decode(speq->decoder);
426
427		if (!ret)
428			return 0;
429
430		if (ret < 0)
431			goto retry;
432
433		record = &speq->decoder->record;
434
435		speq->timestamp = record->timestamp;
436		ret = auxtrace_heap__add(&spe->heap, queue_nr, speq->timestamp);
437		if (ret)
438			return ret;
439		speq->on_heap = true;
440	}
441
442	return 0;
443}
444
445static int arm_spe__setup_queues(struct arm_spe *spe)
446{
447	unsigned int i;
448	int ret;
449
450	for (i = 0; i < spe->queues.nr_queues; i++) {
451		ret = arm_spe__setup_queue(spe, &spe->queues.queue_array[i], i);
452		if (ret)
453			return ret;
454	}
455
456	return 0;
457}
458
459static int arm_spe__update_queues(struct arm_spe *spe)
460{
461	if (spe->queues.new_data) {
462		spe->queues.new_data = false;
463		return arm_spe__setup_queues(spe);
464	}
465
466	return 0;
467}
468
469static bool arm_spe__is_timeless_decoding(struct arm_spe *spe)
470{
471	struct evsel *evsel;
472	struct evlist *evlist = spe->session->evlist;
473	bool timeless_decoding = true;
474
475	/*
476	 * Circle through the list of event and complain if we find one
477	 * with the time bit set.
478	 */
479	evlist__for_each_entry(evlist, evsel) {
480		if ((evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
481			timeless_decoding = false;
482	}
483
484	return timeless_decoding;
485}
486
487static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe,
488				    struct auxtrace_queue *queue)
489{
490	struct arm_spe_queue *speq = queue->priv;
491	pid_t tid;
492
493	tid = machine__get_current_tid(spe->machine, speq->cpu);
494	if (tid != -1) {
495		speq->tid = tid;
496		thread__zput(speq->thread);
497	} else
498		speq->tid = queue->tid;
499
500	if ((!speq->thread) && (speq->tid != -1)) {
501		speq->thread = machine__find_thread(spe->machine, -1,
502						    speq->tid);
503	}
504
505	if (speq->thread) {
506		speq->pid = speq->thread->pid_;
507		if (queue->cpu == -1)
508			speq->cpu = speq->thread->cpu;
509	}
510}
511
512static int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp)
513{
514	unsigned int queue_nr;
515	u64 ts;
516	int ret;
517
518	while (1) {
519		struct auxtrace_queue *queue;
520		struct arm_spe_queue *speq;
521
522		if (!spe->heap.heap_cnt)
523			return 0;
524
525		if (spe->heap.heap_array[0].ordinal >= timestamp)
526			return 0;
527
528		queue_nr = spe->heap.heap_array[0].queue_nr;
529		queue = &spe->queues.queue_array[queue_nr];
530		speq = queue->priv;
531
532		auxtrace_heap__pop(&spe->heap);
533
534		if (spe->heap.heap_cnt) {
535			ts = spe->heap.heap_array[0].ordinal + 1;
536			if (ts > timestamp)
537				ts = timestamp;
538		} else {
539			ts = timestamp;
540		}
541
542		arm_spe_set_pid_tid_cpu(spe, queue);
543
544		ret = arm_spe_run_decoder(speq, &ts);
545		if (ret < 0) {
546			auxtrace_heap__add(&spe->heap, queue_nr, ts);
547			return ret;
548		}
549
550		if (!ret) {
551			ret = auxtrace_heap__add(&spe->heap, queue_nr, ts);
552			if (ret < 0)
553				return ret;
554		} else {
555			speq->on_heap = false;
556		}
557	}
558
559	return 0;
560}
561
562static int arm_spe_process_timeless_queues(struct arm_spe *spe, pid_t tid,
563					    u64 time_)
564{
565	struct auxtrace_queues *queues = &spe->queues;
566	unsigned int i;
567	u64 ts = 0;
568
569	for (i = 0; i < queues->nr_queues; i++) {
570		struct auxtrace_queue *queue = &spe->queues.queue_array[i];
571		struct arm_spe_queue *speq = queue->priv;
572
573		if (speq && (tid == -1 || speq->tid == tid)) {
574			speq->time = time_;
575			arm_spe_set_pid_tid_cpu(spe, queue);
576			arm_spe_run_decoder(speq, &ts);
577		}
578	}
579	return 0;
580}
581
582static int arm_spe_process_event(struct perf_session *session,
583				 union perf_event *event,
584				 struct perf_sample *sample,
585				 struct perf_tool *tool)
586{
587	int err = 0;
588	u64 timestamp;
589	struct arm_spe *spe = container_of(session->auxtrace,
590			struct arm_spe, auxtrace);
591
592	if (dump_trace)
593		return 0;
594
595	if (!tool->ordered_events) {
596		pr_err("SPE trace requires ordered events\n");
597		return -EINVAL;
598	}
599
600	if (sample->time && (sample->time != (u64) -1))
601		timestamp = sample->time;
602	else
603		timestamp = 0;
604
605	if (timestamp || spe->timeless_decoding) {
606		err = arm_spe__update_queues(spe);
607		if (err)
608			return err;
609	}
610
611	if (spe->timeless_decoding) {
612		if (event->header.type == PERF_RECORD_EXIT) {
613			err = arm_spe_process_timeless_queues(spe,
614					event->fork.tid,
615					sample->time);
616		}
617	} else if (timestamp) {
618		if (event->header.type == PERF_RECORD_EXIT) {
619			err = arm_spe_process_queues(spe, timestamp);
620			if (err)
621				return err;
622		}
623	}
624
625	return err;
626}
627
628static int arm_spe_process_auxtrace_event(struct perf_session *session,
629					  union perf_event *event,
630					  struct perf_tool *tool __maybe_unused)
631{
632	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
633					     auxtrace);
634
635	if (!spe->data_queued) {
636		struct auxtrace_buffer *buffer;
637		off_t data_offset;
638		int fd = perf_data__fd(session->data);
639		int err;
640
641		if (perf_data__is_pipe(session->data)) {
642			data_offset = 0;
643		} else {
644			data_offset = lseek(fd, 0, SEEK_CUR);
645			if (data_offset == -1)
646				return -errno;
647		}
648
649		err = auxtrace_queues__add_event(&spe->queues, session, event,
650				data_offset, &buffer);
651		if (err)
652			return err;
653
654		/* Dump here now we have copied a piped trace out of the pipe */
655		if (dump_trace) {
656			if (auxtrace_buffer__get_data(buffer, fd)) {
657				arm_spe_dump_event(spe, buffer->data,
658						buffer->size);
659				auxtrace_buffer__put_data(buffer);
660			}
661		}
662	}
663
664	return 0;
665}
666
667static int arm_spe_flush(struct perf_session *session __maybe_unused,
668			 struct perf_tool *tool __maybe_unused)
669{
670	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
671			auxtrace);
672	int ret;
673
674	if (dump_trace)
675		return 0;
676
677	if (!tool->ordered_events)
678		return -EINVAL;
679
680	ret = arm_spe__update_queues(spe);
681	if (ret < 0)
682		return ret;
683
684	if (spe->timeless_decoding)
685		return arm_spe_process_timeless_queues(spe, -1,
686				MAX_TIMESTAMP - 1);
687
688	return arm_spe_process_queues(spe, MAX_TIMESTAMP);
689}
690
691static void arm_spe_free_queue(void *priv)
692{
693	struct arm_spe_queue *speq = priv;
694
695	if (!speq)
696		return;
697	thread__zput(speq->thread);
698	arm_spe_decoder_free(speq->decoder);
699	zfree(&speq->event_buf);
700	free(speq);
701}
702
703static void arm_spe_free_events(struct perf_session *session)
704{
705	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
706					     auxtrace);
707	struct auxtrace_queues *queues = &spe->queues;
708	unsigned int i;
709
710	for (i = 0; i < queues->nr_queues; i++) {
711		arm_spe_free_queue(queues->queue_array[i].priv);
712		queues->queue_array[i].priv = NULL;
713	}
714	auxtrace_queues__free(queues);
715}
716
717static void arm_spe_free(struct perf_session *session)
718{
719	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
720					     auxtrace);
721
722	auxtrace_heap__free(&spe->heap);
723	arm_spe_free_events(session);
724	session->auxtrace = NULL;
725	free(spe);
726}
727
728static bool arm_spe_evsel_is_auxtrace(struct perf_session *session,
729				      struct evsel *evsel)
730{
731	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe, auxtrace);
732
733	return evsel->core.attr.type == spe->pmu_type;
734}
735
736static const char * const arm_spe_info_fmts[] = {
737	[ARM_SPE_PMU_TYPE]		= "  PMU Type           %"PRId64"\n",
738};
739
740static void arm_spe_print_info(__u64 *arr)
741{
742	if (!dump_trace)
743		return;
744
745	fprintf(stdout, arm_spe_info_fmts[ARM_SPE_PMU_TYPE], arr[ARM_SPE_PMU_TYPE]);
746}
747
748struct arm_spe_synth {
749	struct perf_tool dummy_tool;
750	struct perf_session *session;
751};
752
753static int arm_spe_event_synth(struct perf_tool *tool,
754			       union perf_event *event,
755			       struct perf_sample *sample __maybe_unused,
756			       struct machine *machine __maybe_unused)
757{
758	struct arm_spe_synth *arm_spe_synth =
759		      container_of(tool, struct arm_spe_synth, dummy_tool);
760
761	return perf_session__deliver_synth_event(arm_spe_synth->session,
762						 event, NULL);
763}
764
765static int arm_spe_synth_event(struct perf_session *session,
766			       struct perf_event_attr *attr, u64 id)
767{
768	struct arm_spe_synth arm_spe_synth;
769
770	memset(&arm_spe_synth, 0, sizeof(struct arm_spe_synth));
771	arm_spe_synth.session = session;
772
773	return perf_event__synthesize_attr(&arm_spe_synth.dummy_tool, attr, 1,
774					   &id, arm_spe_event_synth);
775}
776
777static void arm_spe_set_event_name(struct evlist *evlist, u64 id,
778				    const char *name)
779{
780	struct evsel *evsel;
781
782	evlist__for_each_entry(evlist, evsel) {
783		if (evsel->core.id && evsel->core.id[0] == id) {
784			if (evsel->name)
785				zfree(&evsel->name);
786			evsel->name = strdup(name);
787			break;
788		}
789	}
790}
791
792static int
793arm_spe_synth_events(struct arm_spe *spe, struct perf_session *session)
794{
795	struct evlist *evlist = session->evlist;
796	struct evsel *evsel;
797	struct perf_event_attr attr;
798	bool found = false;
799	u64 id;
800	int err;
801
802	evlist__for_each_entry(evlist, evsel) {
803		if (evsel->core.attr.type == spe->pmu_type) {
804			found = true;
805			break;
806		}
807	}
808
809	if (!found) {
810		pr_debug("No selected events with SPE trace data\n");
811		return 0;
812	}
813
814	memset(&attr, 0, sizeof(struct perf_event_attr));
815	attr.size = sizeof(struct perf_event_attr);
816	attr.type = PERF_TYPE_HARDWARE;
817	attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK;
818	attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
819		PERF_SAMPLE_PERIOD;
820	if (spe->timeless_decoding)
821		attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
822	else
823		attr.sample_type |= PERF_SAMPLE_TIME;
824
825	spe->sample_type = attr.sample_type;
826
827	attr.exclude_user = evsel->core.attr.exclude_user;
828	attr.exclude_kernel = evsel->core.attr.exclude_kernel;
829	attr.exclude_hv = evsel->core.attr.exclude_hv;
830	attr.exclude_host = evsel->core.attr.exclude_host;
831	attr.exclude_guest = evsel->core.attr.exclude_guest;
832	attr.sample_id_all = evsel->core.attr.sample_id_all;
833	attr.read_format = evsel->core.attr.read_format;
834
835	/* create new id val to be a fixed offset from evsel id */
836	id = evsel->core.id[0] + 1000000000;
837
838	if (!id)
839		id = 1;
840
841	if (spe->synth_opts.flc) {
842		spe->sample_flc = true;
843
844		/* Level 1 data cache miss */
845		err = arm_spe_synth_event(session, &attr, id);
846		if (err)
847			return err;
848		spe->l1d_miss_id = id;
849		arm_spe_set_event_name(evlist, id, "l1d-miss");
850		id += 1;
851
852		/* Level 1 data cache access */
853		err = arm_spe_synth_event(session, &attr, id);
854		if (err)
855			return err;
856		spe->l1d_access_id = id;
857		arm_spe_set_event_name(evlist, id, "l1d-access");
858		id += 1;
859	}
860
861	if (spe->synth_opts.llc) {
862		spe->sample_llc = true;
863
864		/* Last level cache miss */
865		err = arm_spe_synth_event(session, &attr, id);
866		if (err)
867			return err;
868		spe->llc_miss_id = id;
869		arm_spe_set_event_name(evlist, id, "llc-miss");
870		id += 1;
871
872		/* Last level cache access */
873		err = arm_spe_synth_event(session, &attr, id);
874		if (err)
875			return err;
876		spe->llc_access_id = id;
877		arm_spe_set_event_name(evlist, id, "llc-access");
878		id += 1;
879	}
880
881	if (spe->synth_opts.tlb) {
882		spe->sample_tlb = true;
883
884		/* TLB miss */
885		err = arm_spe_synth_event(session, &attr, id);
886		if (err)
887			return err;
888		spe->tlb_miss_id = id;
889		arm_spe_set_event_name(evlist, id, "tlb-miss");
890		id += 1;
891
892		/* TLB access */
893		err = arm_spe_synth_event(session, &attr, id);
894		if (err)
895			return err;
896		spe->tlb_access_id = id;
897		arm_spe_set_event_name(evlist, id, "tlb-access");
898		id += 1;
899	}
900
901	if (spe->synth_opts.branches) {
902		spe->sample_branch = true;
903
904		/* Branch miss */
905		err = arm_spe_synth_event(session, &attr, id);
906		if (err)
907			return err;
908		spe->branch_miss_id = id;
909		arm_spe_set_event_name(evlist, id, "branch-miss");
910		id += 1;
911	}
912
913	if (spe->synth_opts.remote_access) {
914		spe->sample_remote_access = true;
915
916		/* Remote access */
917		err = arm_spe_synth_event(session, &attr, id);
918		if (err)
919			return err;
920		spe->remote_access_id = id;
921		arm_spe_set_event_name(evlist, id, "remote-access");
922		id += 1;
923	}
924
925	return 0;
926}
927
928int arm_spe_process_auxtrace_info(union perf_event *event,
929				  struct perf_session *session)
930{
931	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
932	size_t min_sz = sizeof(u64) * ARM_SPE_AUXTRACE_PRIV_MAX;
933	struct arm_spe *spe;
934	int err;
935
936	if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) +
937					min_sz)
938		return -EINVAL;
939
940	spe = zalloc(sizeof(struct arm_spe));
941	if (!spe)
942		return -ENOMEM;
943
944	err = auxtrace_queues__init(&spe->queues);
945	if (err)
946		goto err_free;
947
948	spe->session = session;
949	spe->machine = &session->machines.host; /* No kvm support */
950	spe->auxtrace_type = auxtrace_info->type;
951	spe->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE];
952
953	spe->timeless_decoding = arm_spe__is_timeless_decoding(spe);
954	spe->auxtrace.process_event = arm_spe_process_event;
955	spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event;
956	spe->auxtrace.flush_events = arm_spe_flush;
957	spe->auxtrace.free_events = arm_spe_free_events;
958	spe->auxtrace.free = arm_spe_free;
959	spe->auxtrace.evsel_is_auxtrace = arm_spe_evsel_is_auxtrace;
960	session->auxtrace = &spe->auxtrace;
961
962	arm_spe_print_info(&auxtrace_info->priv[0]);
963
964	if (dump_trace)
965		return 0;
966
967	if (session->itrace_synth_opts && session->itrace_synth_opts->set)
968		spe->synth_opts = *session->itrace_synth_opts;
969	else
970		itrace_synth_opts__set_default(&spe->synth_opts, false);
971
972	err = arm_spe_synth_events(spe, session);
973	if (err)
974		goto err_free_queues;
975
976	err = auxtrace_queues__process_index(&spe->queues, session);
977	if (err)
978		goto err_free_queues;
979
980	if (spe->queues.populated)
981		spe->data_queued = true;
982
983	return 0;
984
985err_free_queues:
986	auxtrace_queues__free(&spe->queues);
987	session->auxtrace = NULL;
988err_free:
989	free(spe);
990	return err;
991}
992