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(¶ms); 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