1 /* 2 * Copyright (c) 2014-2019, Intel Corporation 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * * Neither the name of Intel Corporation nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "pt_packet_decoder.h" 30 #include "pt_decoder_function.h" 31 #include "pt_packet.h" 32 #include "pt_sync.h" 33 #include "pt_config.h" 34 #include "pt_opcodes.h" 35 36 #include <string.h> 37 #include <stdlib.h> 38 #include <stddef.h> 39 40 41 int pt_pkt_decoder_init(struct pt_packet_decoder *decoder, 42 const struct pt_config *config) 43 { 44 int errcode; 45 46 if (!decoder || !config) 47 return -pte_invalid; 48 49 memset(decoder, 0, sizeof(*decoder)); 50 51 errcode = pt_config_from_user(&decoder->config, config); 52 if (errcode < 0) 53 return errcode; 54 55 return 0; 56 } 57 58 struct pt_packet_decoder *pt_pkt_alloc_decoder(const struct pt_config *config) 59 { 60 struct pt_packet_decoder *decoder; 61 int errcode; 62 63 decoder = malloc(sizeof(*decoder)); 64 if (!decoder) 65 return NULL; 66 67 errcode = pt_pkt_decoder_init(decoder, config); 68 if (errcode < 0) { 69 free(decoder); 70 return NULL; 71 } 72 73 return decoder; 74 } 75 76 void pt_pkt_decoder_fini(struct pt_packet_decoder *decoder) 77 { 78 (void) decoder; 79 80 /* Nothing to do. */ 81 } 82 83 void pt_pkt_free_decoder(struct pt_packet_decoder *decoder) 84 { 85 pt_pkt_decoder_fini(decoder); 86 free(decoder); 87 } 88 89 int pt_pkt_sync_forward(struct pt_packet_decoder *decoder) 90 { 91 const uint8_t *pos, *sync, *begin; 92 ptrdiff_t space; 93 int errcode; 94 95 if (!decoder) 96 return -pte_invalid; 97 98 begin = decoder->config.begin; 99 sync = decoder->sync; 100 pos = decoder->pos; 101 if (!pos) 102 pos = begin; 103 104 if (pos == sync) 105 pos += ptps_psb; 106 107 if (pos < begin) 108 return -pte_internal; 109 110 /* Start a bit earlier so we find PSB that have been partially consumed 111 * by a preceding packet. 112 */ 113 space = pos - begin; 114 if (ptps_psb <= space) 115 space = ptps_psb - 1; 116 117 pos -= space; 118 119 errcode = pt_sync_forward(&sync, pos, &decoder->config); 120 if (errcode < 0) 121 return errcode; 122 123 decoder->sync = sync; 124 decoder->pos = sync; 125 126 return 0; 127 } 128 129 int pt_pkt_sync_backward(struct pt_packet_decoder *decoder) 130 { 131 const uint8_t *pos, *sync; 132 int errcode; 133 134 if (!decoder) 135 return -pte_invalid; 136 137 pos = decoder->pos; 138 if (!pos) 139 pos = decoder->config.end; 140 141 errcode = pt_sync_backward(&sync, pos, &decoder->config); 142 if (errcode < 0) 143 return errcode; 144 145 decoder->sync = sync; 146 decoder->pos = sync; 147 148 return 0; 149 } 150 151 int pt_pkt_sync_set(struct pt_packet_decoder *decoder, uint64_t offset) 152 { 153 const uint8_t *begin, *end, *pos; 154 155 if (!decoder) 156 return -pte_invalid; 157 158 begin = decoder->config.begin; 159 end = decoder->config.end; 160 pos = begin + offset; 161 162 if (end < pos || pos < begin) 163 return -pte_eos; 164 165 decoder->sync = pos; 166 decoder->pos = pos; 167 168 return 0; 169 } 170 171 int pt_pkt_get_offset(const struct pt_packet_decoder *decoder, uint64_t *offset) 172 { 173 const uint8_t *begin, *pos; 174 175 if (!decoder || !offset) 176 return -pte_invalid; 177 178 begin = decoder->config.begin; 179 pos = decoder->pos; 180 181 if (!pos) 182 return -pte_nosync; 183 184 *offset = (uint64_t) (int64_t) (pos - begin); 185 return 0; 186 } 187 188 int pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder, 189 uint64_t *offset) 190 { 191 const uint8_t *begin, *sync; 192 193 if (!decoder || !offset) 194 return -pte_invalid; 195 196 begin = decoder->config.begin; 197 sync = decoder->sync; 198 199 if (!sync) 200 return -pte_nosync; 201 202 *offset = (uint64_t) (int64_t) (sync - begin); 203 return 0; 204 } 205 206 const struct pt_config * 207 pt_pkt_get_config(const struct pt_packet_decoder *decoder) 208 { 209 if (!decoder) 210 return NULL; 211 212 return &decoder->config; 213 } 214 215 static inline int pkt_to_user(struct pt_packet *upkt, size_t size, 216 const struct pt_packet *pkt) 217 { 218 if (!upkt || !pkt) 219 return -pte_internal; 220 221 if (upkt == pkt) 222 return 0; 223 224 /* Zero out any unknown bytes. */ 225 if (sizeof(*pkt) < size) { 226 memset(upkt + sizeof(*pkt), 0, size - sizeof(*pkt)); 227 228 size = sizeof(*pkt); 229 } 230 231 memcpy(upkt, pkt, size); 232 233 return 0; 234 } 235 236 int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet, 237 size_t psize) 238 { 239 const struct pt_decoder_function *dfun; 240 struct pt_packet pkt, *ppkt; 241 int errcode, size; 242 243 if (!packet || !decoder) 244 return -pte_invalid; 245 246 ppkt = psize == sizeof(pkt) ? packet : &pkt; 247 248 errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config); 249 if (errcode < 0) 250 return errcode; 251 252 if (!dfun) 253 return -pte_internal; 254 255 if (!dfun->packet) 256 return -pte_internal; 257 258 size = dfun->packet(decoder, ppkt); 259 if (size < 0) 260 return size; 261 262 errcode = pkt_to_user(packet, psize, ppkt); 263 if (errcode < 0) 264 return errcode; 265 266 decoder->pos += size; 267 268 return size; 269 } 270 271 int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder, 272 struct pt_packet *packet) 273 { 274 int size; 275 276 if (!decoder) 277 return -pte_internal; 278 279 size = pt_pkt_read_unknown(packet, decoder->pos, &decoder->config); 280 if (size < 0) 281 return size; 282 283 return size; 284 } 285 286 int pt_pkt_decode_pad(struct pt_packet_decoder *decoder, 287 struct pt_packet *packet) 288 { 289 (void) decoder; 290 291 if (!packet) 292 return -pte_internal; 293 294 packet->type = ppt_pad; 295 packet->size = ptps_pad; 296 297 return ptps_pad; 298 } 299 300 int pt_pkt_decode_psb(struct pt_packet_decoder *decoder, 301 struct pt_packet *packet) 302 { 303 int size; 304 305 if (!decoder) 306 return -pte_internal; 307 308 size = pt_pkt_read_psb(decoder->pos, &decoder->config); 309 if (size < 0) 310 return size; 311 312 packet->type = ppt_psb; 313 packet->size = (uint8_t) size; 314 315 return size; 316 } 317 318 int pt_pkt_decode_tip(struct pt_packet_decoder *decoder, 319 struct pt_packet *packet) 320 { 321 int size; 322 323 if (!decoder || !packet) 324 return -pte_internal; 325 326 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos, 327 &decoder->config); 328 if (size < 0) 329 return size; 330 331 packet->type = ppt_tip; 332 packet->size = (uint8_t) size; 333 334 return size; 335 } 336 337 int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder, 338 struct pt_packet *packet) 339 { 340 int size; 341 342 if (!decoder || !packet) 343 return -pte_internal; 344 345 size = pt_pkt_read_tnt_8(&packet->payload.tnt, decoder->pos, 346 &decoder->config); 347 if (size < 0) 348 return size; 349 350 packet->type = ppt_tnt_8; 351 packet->size = (uint8_t) size; 352 353 return size; 354 } 355 356 int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder, 357 struct pt_packet *packet) 358 { 359 int size; 360 361 if (!decoder || !packet) 362 return -pte_internal; 363 364 size = pt_pkt_read_tnt_64(&packet->payload.tnt, decoder->pos, 365 &decoder->config); 366 if (size < 0) 367 return size; 368 369 packet->type = ppt_tnt_64; 370 packet->size = (uint8_t) size; 371 372 return size; 373 } 374 375 int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder, 376 struct pt_packet *packet) 377 { 378 int size; 379 380 if (!decoder || !packet) 381 return -pte_internal; 382 383 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos, 384 &decoder->config); 385 if (size < 0) 386 return size; 387 388 packet->type = ppt_tip_pge; 389 packet->size = (uint8_t) size; 390 391 return size; 392 } 393 394 int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder, 395 struct pt_packet *packet) 396 { 397 int size; 398 399 if (!decoder || !packet) 400 return -pte_internal; 401 402 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos, 403 &decoder->config); 404 if (size < 0) 405 return size; 406 407 packet->type = ppt_tip_pgd; 408 packet->size = (uint8_t) size; 409 410 return size; 411 } 412 413 int pt_pkt_decode_fup(struct pt_packet_decoder *decoder, 414 struct pt_packet *packet) 415 { 416 int size; 417 418 if (!decoder || !packet) 419 return -pte_internal; 420 421 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos, 422 &decoder->config); 423 if (size < 0) 424 return size; 425 426 packet->type = ppt_fup; 427 packet->size = (uint8_t) size; 428 429 return size; 430 } 431 432 int pt_pkt_decode_pip(struct pt_packet_decoder *decoder, 433 struct pt_packet *packet) 434 { 435 int size; 436 437 if (!decoder || !packet) 438 return -pte_internal; 439 440 size = pt_pkt_read_pip(&packet->payload.pip, decoder->pos, 441 &decoder->config); 442 if (size < 0) 443 return size; 444 445 packet->type = ppt_pip; 446 packet->size = (uint8_t) size; 447 448 return size; 449 } 450 451 int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder, 452 struct pt_packet *packet) 453 { 454 (void) decoder; 455 456 if (!packet) 457 return -pte_internal; 458 459 packet->type = ppt_ovf; 460 packet->size = ptps_ovf; 461 462 return ptps_ovf; 463 } 464 465 int pt_pkt_decode_mode(struct pt_packet_decoder *decoder, 466 struct pt_packet *packet) 467 { 468 int size; 469 470 if (!decoder || !packet) 471 return -pte_internal; 472 473 size = pt_pkt_read_mode(&packet->payload.mode, decoder->pos, 474 &decoder->config); 475 if (size < 0) 476 return size; 477 478 packet->type = ppt_mode; 479 packet->size = (uint8_t) size; 480 481 return size; 482 } 483 484 int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder, 485 struct pt_packet *packet) 486 { 487 (void) decoder; 488 489 if (!packet) 490 return -pte_internal; 491 492 packet->type = ppt_psbend; 493 packet->size = ptps_psbend; 494 495 return ptps_psbend; 496 } 497 498 int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder, 499 struct pt_packet *packet) 500 { 501 int size; 502 503 if (!decoder || !packet) 504 return -pte_internal; 505 506 size = pt_pkt_read_tsc(&packet->payload.tsc, decoder->pos, 507 &decoder->config); 508 if (size < 0) 509 return size; 510 511 packet->type = ppt_tsc; 512 packet->size = (uint8_t) size; 513 514 return size; 515 } 516 517 int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder, 518 struct pt_packet *packet) 519 { 520 int size; 521 522 if (!decoder || !packet) 523 return -pte_internal; 524 525 size = pt_pkt_read_cbr(&packet->payload.cbr, decoder->pos, 526 &decoder->config); 527 if (size < 0) 528 return size; 529 530 packet->type = ppt_cbr; 531 packet->size = (uint8_t) size; 532 533 return size; 534 } 535 536 int pt_pkt_decode_tma(struct pt_packet_decoder *decoder, 537 struct pt_packet *packet) 538 { 539 int size; 540 541 if (!decoder || !packet) 542 return -pte_internal; 543 544 size = pt_pkt_read_tma(&packet->payload.tma, decoder->pos, 545 &decoder->config); 546 if (size < 0) 547 return size; 548 549 packet->type = ppt_tma; 550 packet->size = (uint8_t) size; 551 552 return size; 553 } 554 555 int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder, 556 struct pt_packet *packet) 557 { 558 int size; 559 560 if (!decoder || !packet) 561 return -pte_internal; 562 563 size = pt_pkt_read_mtc(&packet->payload.mtc, decoder->pos, 564 &decoder->config); 565 if (size < 0) 566 return size; 567 568 packet->type = ppt_mtc; 569 packet->size = (uint8_t) size; 570 571 return size; 572 } 573 574 int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder, 575 struct pt_packet *packet) 576 { 577 int size; 578 579 if (!decoder || !packet) 580 return -pte_internal; 581 582 size = pt_pkt_read_cyc(&packet->payload.cyc, decoder->pos, 583 &decoder->config); 584 if (size < 0) 585 return size; 586 587 packet->type = ppt_cyc; 588 packet->size = (uint8_t) size; 589 590 return size; 591 } 592 593 int pt_pkt_decode_stop(struct pt_packet_decoder *decoder, 594 struct pt_packet *packet) 595 { 596 (void) decoder; 597 598 if (!packet) 599 return -pte_internal; 600 601 packet->type = ppt_stop; 602 packet->size = ptps_stop; 603 604 return ptps_stop; 605 } 606 607 int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder, 608 struct pt_packet *packet) 609 { 610 int size; 611 612 if (!decoder || !packet) 613 return -pte_internal; 614 615 size = pt_pkt_read_vmcs(&packet->payload.vmcs, decoder->pos, 616 &decoder->config); 617 if (size < 0) 618 return size; 619 620 packet->type = ppt_vmcs; 621 packet->size = (uint8_t) size; 622 623 return size; 624 } 625 626 int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder, 627 struct pt_packet *packet) 628 { 629 int size; 630 631 if (!decoder || !packet) 632 return -pte_internal; 633 634 size = pt_pkt_read_mnt(&packet->payload.mnt, decoder->pos, 635 &decoder->config); 636 if (size < 0) 637 return size; 638 639 packet->type = ppt_mnt; 640 packet->size = (uint8_t) size; 641 642 return size; 643 } 644 645 int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder, 646 struct pt_packet *packet) 647 { 648 int size; 649 650 if (!decoder || !packet) 651 return -pte_internal; 652 653 size = pt_pkt_read_exstop(&packet->payload.exstop, decoder->pos, 654 &decoder->config); 655 if (size < 0) 656 return size; 657 658 packet->type = ppt_exstop; 659 packet->size = (uint8_t) size; 660 661 return size; 662 } 663 664 int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder, 665 struct pt_packet *packet) 666 { 667 int size; 668 669 if (!decoder || !packet) 670 return -pte_internal; 671 672 size = pt_pkt_read_mwait(&packet->payload.mwait, decoder->pos, 673 &decoder->config); 674 if (size < 0) 675 return size; 676 677 packet->type = ppt_mwait; 678 packet->size = (uint8_t) size; 679 680 return size; 681 } 682 683 int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder, 684 struct pt_packet *packet) 685 { 686 int size; 687 688 if (!decoder || !packet) 689 return -pte_internal; 690 691 size = pt_pkt_read_pwre(&packet->payload.pwre, decoder->pos, 692 &decoder->config); 693 if (size < 0) 694 return size; 695 696 packet->type = ppt_pwre; 697 packet->size = (uint8_t) size; 698 699 return size; 700 } 701 702 int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder, 703 struct pt_packet *packet) 704 { 705 int size; 706 707 if (!decoder || !packet) 708 return -pte_internal; 709 710 size = pt_pkt_read_pwrx(&packet->payload.pwrx, decoder->pos, 711 &decoder->config); 712 if (size < 0) 713 return size; 714 715 packet->type = ppt_pwrx; 716 packet->size = (uint8_t) size; 717 718 return size; 719 } 720 721 int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder, 722 struct pt_packet *packet) 723 { 724 int size; 725 726 if (!decoder || !packet) 727 return -pte_internal; 728 729 size = pt_pkt_read_ptw(&packet->payload.ptw, decoder->pos, 730 &decoder->config); 731 if (size < 0) 732 return size; 733 734 packet->type = ppt_ptw; 735 packet->size = (uint8_t) size; 736 737 return size; 738 } 739