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