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