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_encoder.h" 30 #include "pt_config.h" 31 #include "pt_opcodes.h" 32 33 #include <string.h> 34 #include <stdlib.h> 35 36 37 int pt_encoder_init(struct pt_encoder *encoder, const struct pt_config *config) 38 { 39 int errcode; 40 41 if (!encoder) 42 return -pte_invalid; 43 44 memset(encoder, 0, sizeof(*encoder)); 45 46 errcode = pt_config_from_user(&encoder->config, config); 47 if (errcode < 0) 48 return errcode; 49 50 encoder->pos = encoder->config.begin; 51 52 return 0; 53 } 54 55 void pt_encoder_fini(struct pt_encoder *encoder) 56 { 57 (void) encoder; 58 59 /* Nothing to do. */ 60 } 61 62 struct pt_encoder *pt_alloc_encoder(const struct pt_config *config) 63 { 64 struct pt_encoder *encoder; 65 int errcode; 66 67 encoder = malloc(sizeof(*encoder)); 68 if (!encoder) 69 return NULL; 70 71 errcode = pt_encoder_init(encoder, config); 72 if (errcode < 0) { 73 free(encoder); 74 return NULL; 75 } 76 77 return encoder; 78 } 79 80 void pt_free_encoder(struct pt_encoder *encoder) 81 { 82 pt_encoder_fini(encoder); 83 free(encoder); 84 } 85 86 int pt_enc_sync_set(struct pt_encoder *encoder, uint64_t offset) 87 { 88 uint8_t *begin, *end, *pos; 89 90 if (!encoder) 91 return -pte_invalid; 92 93 begin = encoder->config.begin; 94 end = encoder->config.end; 95 pos = begin + offset; 96 97 if (end < pos || pos < begin) 98 return -pte_eos; 99 100 encoder->pos = pos; 101 return 0; 102 } 103 104 int pt_enc_get_offset(const struct pt_encoder *encoder, uint64_t *offset) 105 { 106 const uint8_t *raw, *begin; 107 108 if (!encoder || !offset) 109 return -pte_invalid; 110 111 /* The encoder is synchronized at all times. */ 112 raw = encoder->pos; 113 if (!raw) 114 return -pte_internal; 115 116 begin = encoder->config.begin; 117 if (!begin) 118 return -pte_internal; 119 120 *offset = (uint64_t) (int64_t) (raw - begin); 121 return 0; 122 } 123 124 const struct pt_config *pt_enc_get_config(const struct pt_encoder *encoder) 125 { 126 if (!encoder) 127 return NULL; 128 129 return &encoder->config; 130 } 131 132 /* Check the remaining space. 133 * 134 * Returns zero if there are at least \@size bytes of free space available in 135 * \@encoder's Intel PT buffer. 136 * 137 * Returns -pte_eos if not enough space is available. 138 * Returns -pte_internal if \@encoder is NULL. 139 * Returns -pte_internal if \@encoder is not synchronized. 140 */ 141 static int pt_reserve(const struct pt_encoder *encoder, unsigned int size) 142 { 143 const uint8_t *begin, *end, *pos; 144 145 if (!encoder) 146 return -pte_internal; 147 148 /* The encoder is synchronized at all times. */ 149 pos = encoder->pos; 150 if (!pos) 151 return -pte_internal; 152 153 begin = encoder->config.begin; 154 end = encoder->config.end; 155 156 pos += size; 157 if (pos < begin || end < pos) 158 return -pte_eos; 159 160 return 0; 161 } 162 163 /* Return the size of an IP payload based on its IP compression. 164 * 165 * Returns -pte_bad_packet if \@ipc is not a valid IP compression. 166 */ 167 static int pt_ipc_size(enum pt_ip_compression ipc) 168 { 169 switch (ipc) { 170 case pt_ipc_suppressed: 171 return 0; 172 173 case pt_ipc_update_16: 174 return pt_pl_ip_upd16_size; 175 176 case pt_ipc_update_32: 177 return pt_pl_ip_upd32_size; 178 179 case pt_ipc_update_48: 180 return pt_pl_ip_upd48_size; 181 182 case pt_ipc_sext_48: 183 return pt_pl_ip_sext48_size; 184 185 case pt_ipc_full: 186 return pt_pl_ip_full_size; 187 } 188 189 return -pte_invalid; 190 } 191 192 /* Encode an integer value. 193 * 194 * Writes the \@size least signifficant bytes of \@value starting from \@pos. 195 * 196 * The caller needs to ensure that there is enough space available. 197 * 198 * Returns the updated position. 199 */ 200 static uint8_t *pt_encode_int(uint8_t *pos, uint64_t val, int size) 201 { 202 for (; size; --size, val >>= 8) 203 *pos++ = (uint8_t) val; 204 205 return pos; 206 } 207 208 /* Encode an IP packet. 209 * 210 * Write an IP packet with opcode \@opc and payload from \@packet if there is 211 * enough space in \@encoder's Intel PT buffer. 212 * 213 * Returns the number of bytes written on success. 214 * 215 * Returns -pte_eos if there is not enough space. 216 * Returns -pte_internal if \@encoder or \@packet is NULL. 217 * Returns -pte_invalid if \@packet.ipc is not valid. 218 */ 219 static int pt_encode_ip(struct pt_encoder *encoder, enum pt_opcode op, 220 const struct pt_packet_ip *packet) 221 { 222 uint8_t *pos; 223 uint8_t opc, ipc; 224 int size, errcode; 225 226 if (!encoder || !packet) 227 return pte_internal; 228 229 size = pt_ipc_size(packet->ipc); 230 if (size < 0) 231 return size; 232 233 errcode = pt_reserve(encoder, 234 /* opc size = */ 1u + (unsigned int) size); 235 if (errcode < 0) 236 return errcode; 237 238 /* We already checked the ipc in pt_ipc_size(). */ 239 ipc = (uint8_t) (packet->ipc << pt_opm_ipc_shr); 240 opc = (uint8_t) op; 241 242 pos = encoder->pos; 243 *pos++ = opc | ipc; 244 245 encoder->pos = pt_encode_int(pos, packet->ip, size); 246 return /* opc size = */ 1 + size; 247 } 248 249 int pt_enc_next(struct pt_encoder *encoder, const struct pt_packet *packet) 250 { 251 uint8_t *pos, *begin; 252 int errcode; 253 254 if (!encoder || !packet) 255 return -pte_invalid; 256 257 pos = begin = encoder->pos; 258 switch (packet->type) { 259 case ppt_pad: 260 errcode = pt_reserve(encoder, ptps_pad); 261 if (errcode < 0) 262 return errcode; 263 264 *pos++ = pt_opc_pad; 265 266 encoder->pos = pos; 267 return (int) (pos - begin); 268 269 case ppt_psb: { 270 uint64_t psb; 271 272 errcode = pt_reserve(encoder, ptps_psb); 273 if (errcode < 0) 274 return errcode; 275 276 psb = ((uint64_t) pt_psb_hilo << 48 | 277 (uint64_t) pt_psb_hilo << 32 | 278 (uint64_t) pt_psb_hilo << 16 | 279 (uint64_t) pt_psb_hilo); 280 281 pos = pt_encode_int(pos, psb, 8); 282 pos = pt_encode_int(pos, psb, 8); 283 284 encoder->pos = pos; 285 return (int) (pos - begin); 286 } 287 288 case ppt_psbend: 289 errcode = pt_reserve(encoder, ptps_psbend); 290 if (errcode < 0) 291 return errcode; 292 293 *pos++ = pt_opc_ext; 294 *pos++ = pt_ext_psbend; 295 296 encoder->pos = pos; 297 return (int) (pos - begin); 298 299 case ppt_ovf: 300 errcode = pt_reserve(encoder, ptps_ovf); 301 if (errcode < 0) 302 return errcode; 303 304 *pos++ = pt_opc_ext; 305 *pos++ = pt_ext_ovf; 306 307 encoder->pos = pos; 308 return (int) (pos - begin); 309 310 case ppt_fup: 311 return pt_encode_ip(encoder, pt_opc_fup, &packet->payload.ip); 312 313 case ppt_tip: 314 return pt_encode_ip(encoder, pt_opc_tip, &packet->payload.ip); 315 316 case ppt_tip_pge: 317 return pt_encode_ip(encoder, pt_opc_tip_pge, 318 &packet->payload.ip); 319 320 case ppt_tip_pgd: 321 return pt_encode_ip(encoder, pt_opc_tip_pgd, 322 &packet->payload.ip); 323 324 case ppt_tnt_8: { 325 uint8_t opc, stop; 326 327 if (packet->payload.tnt.bit_size >= 7) 328 return -pte_bad_packet; 329 330 errcode = pt_reserve(encoder, ptps_tnt_8); 331 if (errcode < 0) 332 return errcode; 333 334 stop = packet->payload.tnt.bit_size + pt_opm_tnt_8_shr; 335 opc = (uint8_t) 336 (packet->payload.tnt.payload << pt_opm_tnt_8_shr); 337 338 *pos++ = (uint8_t) (opc | (1u << stop)); 339 340 encoder->pos = pos; 341 return (int) (pos - begin); 342 } 343 344 case ppt_tnt_64: { 345 uint64_t tnt, stop; 346 347 errcode = pt_reserve(encoder, ptps_tnt_64); 348 if (errcode < 0) 349 return errcode; 350 351 if (packet->payload.tnt.bit_size >= pt_pl_tnt_64_bits) 352 return -pte_invalid; 353 354 stop = 1ull << packet->payload.tnt.bit_size; 355 tnt = packet->payload.tnt.payload; 356 357 if (tnt & ~(stop - 1)) 358 return -pte_invalid; 359 360 *pos++ = pt_opc_ext; 361 *pos++ = pt_ext_tnt_64; 362 pos = pt_encode_int(pos, tnt | stop, pt_pl_tnt_64_size); 363 364 encoder->pos = pos; 365 return (int) (pos - begin); 366 } 367 368 case ppt_mode: { 369 uint8_t mode; 370 371 errcode = pt_reserve(encoder, ptps_mode); 372 if (errcode < 0) 373 return errcode; 374 375 switch (packet->payload.mode.leaf) { 376 default: 377 return -pte_bad_packet; 378 379 case pt_mol_exec: 380 mode = pt_mol_exec; 381 382 if (packet->payload.mode.bits.exec.csl) 383 mode |= pt_mob_exec_csl; 384 385 if (packet->payload.mode.bits.exec.csd) 386 mode |= pt_mob_exec_csd; 387 break; 388 389 case pt_mol_tsx: 390 mode = pt_mol_tsx; 391 392 if (packet->payload.mode.bits.tsx.intx) 393 mode |= pt_mob_tsx_intx; 394 395 if (packet->payload.mode.bits.tsx.abrt) 396 mode |= pt_mob_tsx_abrt; 397 break; 398 } 399 400 *pos++ = pt_opc_mode; 401 *pos++ = mode; 402 403 encoder->pos = pos; 404 return (int) (pos - begin); 405 } 406 407 case ppt_pip: { 408 uint64_t cr3; 409 410 errcode = pt_reserve(encoder, ptps_pip); 411 if (errcode < 0) 412 return errcode; 413 414 cr3 = packet->payload.pip.cr3; 415 cr3 >>= pt_pl_pip_shl; 416 cr3 <<= pt_pl_pip_shr; 417 418 if (packet->payload.pip.nr) 419 cr3 |= (uint64_t) pt_pl_pip_nr; 420 421 *pos++ = pt_opc_ext; 422 *pos++ = pt_ext_pip; 423 pos = pt_encode_int(pos, cr3, pt_pl_pip_size); 424 425 encoder->pos = pos; 426 return (int) (pos - begin); 427 } 428 429 case ppt_tsc: 430 errcode = pt_reserve(encoder, ptps_tsc); 431 if (errcode < 0) 432 return errcode; 433 434 *pos++ = pt_opc_tsc; 435 pos = pt_encode_int(pos, packet->payload.tsc.tsc, 436 pt_pl_tsc_size); 437 438 encoder->pos = pos; 439 return (int) (pos - begin); 440 441 case ppt_cbr: 442 errcode = pt_reserve(encoder, ptps_cbr); 443 if (errcode < 0) 444 return errcode; 445 446 *pos++ = pt_opc_ext; 447 *pos++ = pt_ext_cbr; 448 *pos++ = packet->payload.cbr.ratio; 449 *pos++ = 0; 450 451 encoder->pos = pos; 452 return (int) (pos - begin); 453 454 case ppt_tma: { 455 uint16_t ctc, fc; 456 457 errcode = pt_reserve(encoder, ptps_tma); 458 if (errcode < 0) 459 return errcode; 460 461 ctc = packet->payload.tma.ctc; 462 fc = packet->payload.tma.fc; 463 464 if (fc & ~pt_pl_tma_fc_mask) 465 return -pte_bad_packet; 466 467 *pos++ = pt_opc_ext; 468 *pos++ = pt_ext_tma; 469 pos = pt_encode_int(pos, ctc, pt_pl_tma_ctc_size); 470 *pos++ = 0; 471 pos = pt_encode_int(pos, fc, pt_pl_tma_fc_size); 472 473 encoder->pos = pos; 474 return (int) (pos - begin); 475 } 476 477 case ppt_mtc: 478 errcode = pt_reserve(encoder, ptps_mtc); 479 if (errcode < 0) 480 return errcode; 481 482 *pos++ = pt_opc_mtc; 483 *pos++ = packet->payload.mtc.ctc; 484 485 encoder->pos = pos; 486 return (int) (pos - begin); 487 488 case ppt_cyc: { 489 uint8_t byte[pt_pl_cyc_max_size], index, end; 490 uint64_t ctc; 491 492 ctc = (uint8_t) packet->payload.cyc.value; 493 ctc <<= pt_opm_cyc_shr; 494 495 byte[0] = pt_opc_cyc; 496 byte[0] |= (uint8_t) ctc; 497 498 ctc = packet->payload.cyc.value; 499 ctc >>= (8 - pt_opm_cyc_shr); 500 if (ctc) 501 byte[0] |= pt_opm_cyc_ext; 502 503 for (end = 1; ctc; ++end) { 504 /* Check if the CYC payload is too big. */ 505 if (pt_pl_cyc_max_size <= end) 506 return -pte_bad_packet; 507 508 ctc <<= pt_opm_cycx_shr; 509 510 byte[end] = (uint8_t) ctc; 511 512 ctc >>= 8; 513 if (ctc) 514 byte[end] |= pt_opm_cycx_ext; 515 } 516 517 errcode = pt_reserve(encoder, end); 518 if (errcode < 0) 519 return errcode; 520 521 for (index = 0; index < end; ++index) 522 *pos++ = byte[index]; 523 524 encoder->pos = pos; 525 return (int) (pos - begin); 526 } 527 528 case ppt_stop: 529 errcode = pt_reserve(encoder, ptps_stop); 530 if (errcode < 0) 531 return errcode; 532 533 *pos++ = pt_opc_ext; 534 *pos++ = pt_ext_stop; 535 536 encoder->pos = pos; 537 return (int) (pos - begin); 538 539 case ppt_vmcs: 540 errcode = pt_reserve(encoder, ptps_vmcs); 541 if (errcode < 0) 542 return errcode; 543 544 *pos++ = pt_opc_ext; 545 *pos++ = pt_ext_vmcs; 546 pos = pt_encode_int(pos, 547 packet->payload.vmcs.base >> pt_pl_vmcs_shl, 548 pt_pl_vmcs_size); 549 550 encoder->pos = pos; 551 return (int) (pos - begin); 552 553 case ppt_mnt: 554 errcode = pt_reserve(encoder, ptps_mnt); 555 if (errcode < 0) 556 return errcode; 557 558 *pos++ = pt_opc_ext; 559 *pos++ = pt_ext_ext2; 560 *pos++ = pt_ext2_mnt; 561 pos = pt_encode_int(pos, packet->payload.mnt.payload, 562 pt_pl_mnt_size); 563 564 encoder->pos = pos; 565 return (int) (pos - begin); 566 567 case ppt_exstop: { 568 uint8_t ext; 569 570 errcode = pt_reserve(encoder, ptps_exstop); 571 if (errcode < 0) 572 return errcode; 573 574 ext = packet->payload.exstop.ip ? 575 pt_ext_exstop_ip : pt_ext_exstop; 576 577 *pos++ = pt_opc_ext; 578 *pos++ = ext; 579 580 encoder->pos = pos; 581 return (int) (pos - begin); 582 } 583 584 case ppt_mwait: 585 errcode = pt_reserve(encoder, ptps_mwait); 586 if (errcode < 0) 587 return errcode; 588 589 *pos++ = pt_opc_ext; 590 *pos++ = pt_ext_mwait; 591 pos = pt_encode_int(pos, packet->payload.mwait.hints, 592 pt_pl_mwait_hints_size); 593 pos = pt_encode_int(pos, packet->payload.mwait.ext, 594 pt_pl_mwait_ext_size); 595 596 encoder->pos = pos; 597 return (int) (pos - begin); 598 599 case ppt_pwre: { 600 uint64_t payload; 601 602 errcode = pt_reserve(encoder, ptps_pwre); 603 if (errcode < 0) 604 return errcode; 605 606 payload = 0ull; 607 payload |= ((uint64_t) packet->payload.pwre.state << 608 pt_pl_pwre_state_shr) & 609 (uint64_t) pt_pl_pwre_state_mask; 610 payload |= ((uint64_t) packet->payload.pwre.sub_state << 611 pt_pl_pwre_sub_state_shr) & 612 (uint64_t) pt_pl_pwre_sub_state_mask; 613 614 if (packet->payload.pwre.hw) 615 payload |= (uint64_t) pt_pl_pwre_hw_mask; 616 617 *pos++ = pt_opc_ext; 618 *pos++ = pt_ext_pwre; 619 pos = pt_encode_int(pos, payload, pt_pl_pwre_size); 620 621 encoder->pos = pos; 622 return (int) (pos - begin); 623 } 624 625 case ppt_pwrx: { 626 uint64_t payload; 627 628 errcode = pt_reserve(encoder, ptps_pwrx); 629 if (errcode < 0) 630 return errcode; 631 632 payload = 0ull; 633 payload |= ((uint64_t) packet->payload.pwrx.last << 634 pt_pl_pwrx_last_shr) & 635 (uint64_t) pt_pl_pwrx_last_mask; 636 payload |= ((uint64_t) packet->payload.pwrx.deepest << 637 pt_pl_pwrx_deepest_shr) & 638 (uint64_t) pt_pl_pwrx_deepest_mask; 639 640 if (packet->payload.pwrx.interrupt) 641 payload |= (uint64_t) pt_pl_pwrx_wr_int; 642 if (packet->payload.pwrx.store) 643 payload |= (uint64_t) pt_pl_pwrx_wr_store; 644 if (packet->payload.pwrx.autonomous) 645 payload |= (uint64_t) pt_pl_pwrx_wr_hw; 646 647 *pos++ = pt_opc_ext; 648 *pos++ = pt_ext_pwrx; 649 pos = pt_encode_int(pos, payload, pt_pl_pwrx_size); 650 651 encoder->pos = pos; 652 return (int) (pos - begin); 653 } 654 655 case ppt_ptw: { 656 uint8_t plc, ext; 657 int size; 658 659 plc = packet->payload.ptw.plc; 660 661 size = pt_ptw_size(plc); 662 if (size < 0) 663 return size; 664 665 errcode = pt_reserve(encoder, 666 (unsigned int) (pt_opcs_ptw + size)); 667 if (errcode < 0) 668 return errcode; 669 670 ext = pt_ext_ptw; 671 ext |= plc << pt_opm_ptw_pb_shr; 672 673 if (packet->payload.ptw.ip) 674 ext |= (uint8_t) pt_opm_ptw_ip; 675 676 *pos++ = pt_opc_ext; 677 *pos++ = ext; 678 pos = pt_encode_int(pos, packet->payload.ptw.payload, size); 679 680 encoder->pos = pos; 681 return (int) (pos - begin); 682 } 683 684 case ppt_unknown: 685 case ppt_invalid: 686 return -pte_bad_opc; 687 } 688 689 return -pte_bad_opc; 690 } 691 692 int pt_encode_pad(struct pt_encoder *encoder) 693 { 694 struct pt_packet packet; 695 696 packet.type = ppt_pad; 697 698 return pt_enc_next(encoder, &packet); 699 } 700 701 int pt_encode_psb(struct pt_encoder *encoder) 702 { 703 struct pt_packet packet; 704 705 packet.type = ppt_psb; 706 707 return pt_enc_next(encoder, &packet); 708 } 709 710 int pt_encode_psbend(struct pt_encoder *encoder) 711 { 712 struct pt_packet packet; 713 714 packet.type = ppt_psbend; 715 716 return pt_enc_next(encoder, &packet); 717 } 718 719 int pt_encode_tip(struct pt_encoder *encoder, uint64_t ip, 720 enum pt_ip_compression ipc) 721 { 722 struct pt_packet packet; 723 724 packet.type = ppt_tip; 725 packet.payload.ip.ip = ip; 726 packet.payload.ip.ipc = ipc; 727 728 return pt_enc_next(encoder, &packet); 729 } 730 731 int pt_encode_tnt_8(struct pt_encoder *encoder, uint8_t tnt, int size) 732 { 733 struct pt_packet packet; 734 735 packet.type = ppt_tnt_8; 736 packet.payload.tnt.bit_size = (uint8_t) size; 737 packet.payload.tnt.payload = tnt; 738 739 return pt_enc_next(encoder, &packet); 740 } 741 742 int pt_encode_tnt_64(struct pt_encoder *encoder, uint64_t tnt, int size) 743 { 744 struct pt_packet packet; 745 746 packet.type = ppt_tnt_64; 747 packet.payload.tnt.bit_size = (uint8_t) size; 748 packet.payload.tnt.payload = tnt; 749 750 return pt_enc_next(encoder, &packet); 751 } 752 753 int pt_encode_tip_pge(struct pt_encoder *encoder, uint64_t ip, 754 enum pt_ip_compression ipc) 755 { 756 struct pt_packet packet; 757 758 packet.type = ppt_tip_pge; 759 packet.payload.ip.ip = ip; 760 packet.payload.ip.ipc = ipc; 761 762 return pt_enc_next(encoder, &packet); 763 } 764 765 int pt_encode_tip_pgd(struct pt_encoder *encoder, uint64_t ip, 766 enum pt_ip_compression ipc) 767 { 768 struct pt_packet packet; 769 770 packet.type = ppt_tip_pgd; 771 packet.payload.ip.ip = ip; 772 packet.payload.ip.ipc = ipc; 773 774 return pt_enc_next(encoder, &packet); 775 } 776 777 int pt_encode_fup(struct pt_encoder *encoder, uint64_t ip, 778 enum pt_ip_compression ipc) 779 { 780 struct pt_packet packet; 781 782 packet.type = ppt_fup; 783 packet.payload.ip.ip = ip; 784 packet.payload.ip.ipc = ipc; 785 786 return pt_enc_next(encoder, &packet); 787 } 788 789 int pt_encode_pip(struct pt_encoder *encoder, uint64_t cr3, uint8_t flags) 790 { 791 struct pt_packet packet; 792 793 packet.type = ppt_pip; 794 packet.payload.pip.cr3 = cr3; 795 packet.payload.pip.nr = (flags & pt_pl_pip_nr) != 0; 796 797 return pt_enc_next(encoder, &packet); 798 } 799 800 int pt_encode_ovf(struct pt_encoder *encoder) 801 { 802 struct pt_packet packet; 803 804 packet.type = ppt_ovf; 805 806 return pt_enc_next(encoder, &packet); 807 } 808 809 int pt_encode_mode_exec(struct pt_encoder *encoder, enum pt_exec_mode mode) 810 { 811 struct pt_packet packet; 812 813 packet.type = ppt_mode; 814 packet.payload.mode.leaf = pt_mol_exec; 815 packet.payload.mode.bits.exec = pt_set_exec_mode(mode); 816 817 return pt_enc_next(encoder, &packet); 818 } 819 820 821 int pt_encode_mode_tsx(struct pt_encoder *encoder, uint8_t bits) 822 { 823 struct pt_packet packet; 824 825 packet.type = ppt_mode; 826 packet.payload.mode.leaf = pt_mol_tsx; 827 828 if (bits & pt_mob_tsx_intx) 829 packet.payload.mode.bits.tsx.intx = 1; 830 else 831 packet.payload.mode.bits.tsx.intx = 0; 832 833 if (bits & pt_mob_tsx_abrt) 834 packet.payload.mode.bits.tsx.abrt = 1; 835 else 836 packet.payload.mode.bits.tsx.abrt = 0; 837 838 return pt_enc_next(encoder, &packet); 839 } 840 841 int pt_encode_tsc(struct pt_encoder *encoder, uint64_t tsc) 842 { 843 struct pt_packet packet; 844 845 packet.type = ppt_tsc; 846 packet.payload.tsc.tsc = tsc; 847 848 return pt_enc_next(encoder, &packet); 849 } 850 851 int pt_encode_cbr(struct pt_encoder *encoder, uint8_t cbr) 852 { 853 struct pt_packet packet; 854 855 packet.type = ppt_cbr; 856 packet.payload.cbr.ratio = cbr; 857 858 return pt_enc_next(encoder, &packet); 859 } 860 861 int pt_encode_tma(struct pt_encoder *encoder, uint16_t ctc, uint16_t fc) 862 { 863 struct pt_packet packet; 864 865 packet.type = ppt_tma; 866 packet.payload.tma.ctc = ctc; 867 packet.payload.tma.fc = fc; 868 869 return pt_enc_next(encoder, &packet); 870 } 871 872 int pt_encode_mtc(struct pt_encoder *encoder, uint8_t ctc) 873 { 874 struct pt_packet packet; 875 876 packet.type = ppt_mtc; 877 packet.payload.mtc.ctc = ctc; 878 879 return pt_enc_next(encoder, &packet); 880 } 881 882 int pt_encode_cyc(struct pt_encoder *encoder, uint32_t ctc) 883 { 884 struct pt_packet packet; 885 886 packet.type = ppt_cyc; 887 packet.payload.cyc.value = ctc; 888 889 return pt_enc_next(encoder, &packet); 890 } 891 892 int pt_encode_stop(struct pt_encoder *encoder) 893 { 894 struct pt_packet packet; 895 896 packet.type = ppt_stop; 897 898 return pt_enc_next(encoder, &packet); 899 } 900 901 int pt_encode_vmcs(struct pt_encoder *encoder, uint64_t payload) 902 { 903 struct pt_packet packet; 904 905 packet.type = ppt_vmcs; 906 packet.payload.vmcs.base = payload; 907 908 return pt_enc_next(encoder, &packet); 909 } 910 911 int pt_encode_mnt(struct pt_encoder *encoder, uint64_t payload) 912 { 913 struct pt_packet packet; 914 915 packet.type = ppt_mnt; 916 packet.payload.mnt.payload = payload; 917 918 return pt_enc_next(encoder, &packet); 919 } 920