1 /* 2 * Copyright (c) 2014-2018, 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 = 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, /* opc size = */ 1 + size); 234 if (errcode < 0) 235 return errcode; 236 237 /* We already checked the ipc in pt_ipc_size(). */ 238 ipc = (uint8_t) (packet->ipc << pt_opm_ipc_shr); 239 opc = (uint8_t) op; 240 241 pos = encoder->pos; 242 *pos++ = opc | ipc; 243 244 encoder->pos = pt_encode_int(pos, packet->ip, size); 245 return /* opc size = */ 1 + size; 246 } 247 248 int pt_enc_next(struct pt_encoder *encoder, const struct pt_packet *packet) 249 { 250 uint8_t *pos, *begin; 251 int errcode; 252 253 if (!encoder || !packet) 254 return -pte_invalid; 255 256 pos = begin = encoder->pos; 257 switch (packet->type) { 258 case ppt_pad: 259 errcode = pt_reserve(encoder, ptps_pad); 260 if (errcode < 0) 261 return errcode; 262 263 *pos++ = pt_opc_pad; 264 265 encoder->pos = pos; 266 return (int) (pos - begin); 267 268 case ppt_psb: { 269 uint64_t psb; 270 271 errcode = pt_reserve(encoder, ptps_psb); 272 if (errcode < 0) 273 return errcode; 274 275 psb = ((uint64_t) pt_psb_hilo << 48 | 276 (uint64_t) pt_psb_hilo << 32 | 277 (uint64_t) pt_psb_hilo << 16 | 278 (uint64_t) pt_psb_hilo); 279 280 pos = pt_encode_int(pos, psb, 8); 281 pos = pt_encode_int(pos, psb, 8); 282 283 encoder->pos = pos; 284 return (int) (pos - begin); 285 } 286 287 case ppt_psbend: 288 errcode = pt_reserve(encoder, ptps_psbend); 289 if (errcode < 0) 290 return errcode; 291 292 *pos++ = pt_opc_ext; 293 *pos++ = pt_ext_psbend; 294 295 encoder->pos = pos; 296 return (int) (pos - begin); 297 298 case ppt_ovf: 299 errcode = pt_reserve(encoder, ptps_ovf); 300 if (errcode < 0) 301 return errcode; 302 303 *pos++ = pt_opc_ext; 304 *pos++ = pt_ext_ovf; 305 306 encoder->pos = pos; 307 return (int) (pos - begin); 308 309 case ppt_fup: 310 return pt_encode_ip(encoder, pt_opc_fup, &packet->payload.ip); 311 312 case ppt_tip: 313 return pt_encode_ip(encoder, pt_opc_tip, &packet->payload.ip); 314 315 case ppt_tip_pge: 316 return pt_encode_ip(encoder, pt_opc_tip_pge, 317 &packet->payload.ip); 318 319 case ppt_tip_pgd: 320 return pt_encode_ip(encoder, pt_opc_tip_pgd, 321 &packet->payload.ip); 322 323 case ppt_tnt_8: { 324 uint8_t opc, stop; 325 326 if (packet->payload.tnt.bit_size >= 7) 327 return -pte_bad_packet; 328 329 errcode = pt_reserve(encoder, ptps_tnt_8); 330 if (errcode < 0) 331 return errcode; 332 333 stop = packet->payload.tnt.bit_size + pt_opm_tnt_8_shr; 334 opc = (uint8_t) 335 (packet->payload.tnt.payload << pt_opm_tnt_8_shr); 336 337 *pos++ = (uint8_t) (opc | (1u << stop)); 338 339 encoder->pos = pos; 340 return (int) (pos - begin); 341 } 342 343 case ppt_tnt_64: { 344 uint64_t tnt, stop; 345 346 errcode = pt_reserve(encoder, ptps_tnt_64); 347 if (errcode < 0) 348 return errcode; 349 350 if (packet->payload.tnt.bit_size >= pt_pl_tnt_64_bits) 351 return -pte_invalid; 352 353 stop = 1ull << packet->payload.tnt.bit_size; 354 tnt = packet->payload.tnt.payload; 355 356 if (tnt & ~(stop - 1)) 357 return -pte_invalid; 358 359 *pos++ = pt_opc_ext; 360 *pos++ = pt_ext_tnt_64; 361 pos = pt_encode_int(pos, tnt | stop, pt_pl_tnt_64_size); 362 363 encoder->pos = pos; 364 return (int) (pos - begin); 365 } 366 367 case ppt_mode: { 368 uint8_t mode; 369 370 errcode = pt_reserve(encoder, ptps_mode); 371 if (errcode < 0) 372 return errcode; 373 374 switch (packet->payload.mode.leaf) { 375 default: 376 return -pte_bad_packet; 377 378 case pt_mol_exec: 379 mode = pt_mol_exec; 380 381 if (packet->payload.mode.bits.exec.csl) 382 mode |= pt_mob_exec_csl; 383 384 if (packet->payload.mode.bits.exec.csd) 385 mode |= pt_mob_exec_csd; 386 break; 387 388 case pt_mol_tsx: 389 mode = pt_mol_tsx; 390 391 if (packet->payload.mode.bits.tsx.intx) 392 mode |= pt_mob_tsx_intx; 393 394 if (packet->payload.mode.bits.tsx.abrt) 395 mode |= pt_mob_tsx_abrt; 396 break; 397 } 398 399 *pos++ = pt_opc_mode; 400 *pos++ = mode; 401 402 encoder->pos = pos; 403 return (int) (pos - begin); 404 } 405 406 case ppt_pip: { 407 uint64_t cr3; 408 409 errcode = pt_reserve(encoder, ptps_pip); 410 if (errcode < 0) 411 return errcode; 412 413 cr3 = packet->payload.pip.cr3; 414 cr3 >>= pt_pl_pip_shl; 415 cr3 <<= pt_pl_pip_shr; 416 417 if (packet->payload.pip.nr) 418 cr3 |= (uint64_t) pt_pl_pip_nr; 419 420 *pos++ = pt_opc_ext; 421 *pos++ = pt_ext_pip; 422 pos = pt_encode_int(pos, cr3, pt_pl_pip_size); 423 424 encoder->pos = pos; 425 return (int) (pos - begin); 426 } 427 428 case ppt_tsc: 429 errcode = pt_reserve(encoder, ptps_tsc); 430 if (errcode < 0) 431 return errcode; 432 433 *pos++ = pt_opc_tsc; 434 pos = pt_encode_int(pos, packet->payload.tsc.tsc, 435 pt_pl_tsc_size); 436 437 encoder->pos = pos; 438 return (int) (pos - begin); 439 440 case ppt_cbr: 441 errcode = pt_reserve(encoder, ptps_cbr); 442 if (errcode < 0) 443 return errcode; 444 445 *pos++ = pt_opc_ext; 446 *pos++ = pt_ext_cbr; 447 *pos++ = packet->payload.cbr.ratio; 448 *pos++ = 0; 449 450 encoder->pos = pos; 451 return (int) (pos - begin); 452 453 case ppt_tma: { 454 uint16_t ctc, fc; 455 456 errcode = pt_reserve(encoder, ptps_tma); 457 if (errcode < 0) 458 return errcode; 459 460 ctc = packet->payload.tma.ctc; 461 fc = packet->payload.tma.fc; 462 463 if (fc & ~pt_pl_tma_fc_mask) 464 return -pte_bad_packet; 465 466 *pos++ = pt_opc_ext; 467 *pos++ = pt_ext_tma; 468 pos = pt_encode_int(pos, ctc, pt_pl_tma_ctc_size); 469 *pos++ = 0; 470 pos = pt_encode_int(pos, fc, pt_pl_tma_fc_size); 471 472 encoder->pos = pos; 473 return (int) (pos - begin); 474 } 475 476 case ppt_mtc: 477 errcode = pt_reserve(encoder, ptps_mtc); 478 if (errcode < 0) 479 return errcode; 480 481 *pos++ = pt_opc_mtc; 482 *pos++ = packet->payload.mtc.ctc; 483 484 encoder->pos = pos; 485 return (int) (pos - begin); 486 487 case ppt_cyc: { 488 uint8_t byte[pt_pl_cyc_max_size], index, end; 489 uint64_t ctc; 490 491 ctc = (uint8_t) packet->payload.cyc.value; 492 ctc <<= pt_opm_cyc_shr; 493 494 byte[0] = pt_opc_cyc; 495 byte[0] |= (uint8_t) ctc; 496 497 ctc = packet->payload.cyc.value; 498 ctc >>= (8 - pt_opm_cyc_shr); 499 if (ctc) 500 byte[0] |= pt_opm_cyc_ext; 501 502 for (end = 1; ctc; ++end) { 503 /* Check if the CYC payload is too big. */ 504 if (pt_pl_cyc_max_size <= end) 505 return -pte_bad_packet; 506 507 ctc <<= pt_opm_cycx_shr; 508 509 byte[end] = (uint8_t) ctc; 510 511 ctc >>= 8; 512 if (ctc) 513 byte[end] |= pt_opm_cycx_ext; 514 } 515 516 errcode = pt_reserve(encoder, end); 517 if (errcode < 0) 518 return errcode; 519 520 for (index = 0; index < end; ++index) 521 *pos++ = byte[index]; 522 523 encoder->pos = pos; 524 return (int) (pos - begin); 525 } 526 527 case ppt_stop: 528 errcode = pt_reserve(encoder, ptps_stop); 529 if (errcode < 0) 530 return errcode; 531 532 *pos++ = pt_opc_ext; 533 *pos++ = pt_ext_stop; 534 535 encoder->pos = pos; 536 return (int) (pos - begin); 537 538 case ppt_vmcs: 539 errcode = pt_reserve(encoder, ptps_vmcs); 540 if (errcode < 0) 541 return errcode; 542 543 *pos++ = pt_opc_ext; 544 *pos++ = pt_ext_vmcs; 545 pos = pt_encode_int(pos, 546 packet->payload.vmcs.base >> pt_pl_vmcs_shl, 547 pt_pl_vmcs_size); 548 549 encoder->pos = pos; 550 return (int) (pos - begin); 551 552 case ppt_mnt: 553 errcode = pt_reserve(encoder, ptps_mnt); 554 if (errcode < 0) 555 return errcode; 556 557 *pos++ = pt_opc_ext; 558 *pos++ = pt_ext_ext2; 559 *pos++ = pt_ext2_mnt; 560 pos = pt_encode_int(pos, packet->payload.mnt.payload, 561 pt_pl_mnt_size); 562 563 encoder->pos = pos; 564 return (int) (pos - begin); 565 566 case ppt_exstop: { 567 uint8_t ext; 568 569 errcode = pt_reserve(encoder, ptps_exstop); 570 if (errcode < 0) 571 return errcode; 572 573 ext = packet->payload.exstop.ip ? 574 pt_ext_exstop_ip : pt_ext_exstop; 575 576 *pos++ = pt_opc_ext; 577 *pos++ = ext; 578 579 encoder->pos = pos; 580 return (int) (pos - begin); 581 } 582 583 case ppt_mwait: 584 errcode = pt_reserve(encoder, ptps_mwait); 585 if (errcode < 0) 586 return errcode; 587 588 *pos++ = pt_opc_ext; 589 *pos++ = pt_ext_mwait; 590 pos = pt_encode_int(pos, packet->payload.mwait.hints, 591 pt_pl_mwait_hints_size); 592 pos = pt_encode_int(pos, packet->payload.mwait.ext, 593 pt_pl_mwait_ext_size); 594 595 encoder->pos = pos; 596 return (int) (pos - begin); 597 598 case ppt_pwre: { 599 uint64_t payload; 600 601 errcode = pt_reserve(encoder, ptps_pwre); 602 if (errcode < 0) 603 return errcode; 604 605 payload = 0ull; 606 payload |= ((uint64_t) packet->payload.pwre.state << 607 pt_pl_pwre_state_shr) & 608 (uint64_t) pt_pl_pwre_state_mask; 609 payload |= ((uint64_t) packet->payload.pwre.sub_state << 610 pt_pl_pwre_sub_state_shr) & 611 (uint64_t) pt_pl_pwre_sub_state_mask; 612 613 if (packet->payload.pwre.hw) 614 payload |= (uint64_t) pt_pl_pwre_hw_mask; 615 616 *pos++ = pt_opc_ext; 617 *pos++ = pt_ext_pwre; 618 pos = pt_encode_int(pos, payload, pt_pl_pwre_size); 619 620 encoder->pos = pos; 621 return (int) (pos - begin); 622 } 623 624 case ppt_pwrx: { 625 uint64_t payload; 626 627 errcode = pt_reserve(encoder, ptps_pwrx); 628 if (errcode < 0) 629 return errcode; 630 631 payload = 0ull; 632 payload |= ((uint64_t) packet->payload.pwrx.last << 633 pt_pl_pwrx_last_shr) & 634 (uint64_t) pt_pl_pwrx_last_mask; 635 payload |= ((uint64_t) packet->payload.pwrx.deepest << 636 pt_pl_pwrx_deepest_shr) & 637 (uint64_t) pt_pl_pwrx_deepest_mask; 638 639 if (packet->payload.pwrx.interrupt) 640 payload |= (uint64_t) pt_pl_pwrx_wr_int; 641 if (packet->payload.pwrx.store) 642 payload |= (uint64_t) pt_pl_pwrx_wr_store; 643 if (packet->payload.pwrx.autonomous) 644 payload |= (uint64_t) pt_pl_pwrx_wr_hw; 645 646 *pos++ = pt_opc_ext; 647 *pos++ = pt_ext_pwrx; 648 pos = pt_encode_int(pos, payload, pt_pl_pwrx_size); 649 650 encoder->pos = pos; 651 return (int) (pos - begin); 652 } 653 654 case ppt_ptw: { 655 uint8_t plc, ext; 656 int size; 657 658 plc = packet->payload.ptw.plc; 659 660 size = pt_ptw_size(plc); 661 if (size < 0) 662 return size; 663 664 errcode = pt_reserve(encoder, pt_opcs_ptw + size); 665 if (errcode < 0) 666 return errcode; 667 668 ext = pt_ext_ptw; 669 ext |= plc << pt_opm_ptw_pb_shr; 670 671 if (packet->payload.ptw.ip) 672 ext |= (uint8_t) pt_opm_ptw_ip; 673 674 *pos++ = pt_opc_ext; 675 *pos++ = ext; 676 pos = pt_encode_int(pos, packet->payload.ptw.payload, size); 677 678 encoder->pos = pos; 679 return (int) (pos - begin); 680 } 681 682 case ppt_unknown: 683 case ppt_invalid: 684 return -pte_bad_opc; 685 } 686 687 return -pte_bad_opc; 688 } 689 690 int pt_encode_pad(struct pt_encoder *encoder) 691 { 692 struct pt_packet packet; 693 694 packet.type = ppt_pad; 695 696 return pt_enc_next(encoder, &packet); 697 } 698 699 int pt_encode_psb(struct pt_encoder *encoder) 700 { 701 struct pt_packet packet; 702 703 packet.type = ppt_psb; 704 705 return pt_enc_next(encoder, &packet); 706 } 707 708 int pt_encode_psbend(struct pt_encoder *encoder) 709 { 710 struct pt_packet packet; 711 712 packet.type = ppt_psbend; 713 714 return pt_enc_next(encoder, &packet); 715 } 716 717 int pt_encode_tip(struct pt_encoder *encoder, uint64_t ip, 718 enum pt_ip_compression ipc) 719 { 720 struct pt_packet packet; 721 722 packet.type = ppt_tip; 723 packet.payload.ip.ip = ip; 724 packet.payload.ip.ipc = ipc; 725 726 return pt_enc_next(encoder, &packet); 727 } 728 729 int pt_encode_tnt_8(struct pt_encoder *encoder, uint8_t tnt, int size) 730 { 731 struct pt_packet packet; 732 733 packet.type = ppt_tnt_8; 734 packet.payload.tnt.bit_size = (uint8_t) size; 735 packet.payload.tnt.payload = tnt; 736 737 return pt_enc_next(encoder, &packet); 738 } 739 740 int pt_encode_tnt_64(struct pt_encoder *encoder, uint64_t tnt, int size) 741 { 742 struct pt_packet packet; 743 744 packet.type = ppt_tnt_64; 745 packet.payload.tnt.bit_size = (uint8_t) size; 746 packet.payload.tnt.payload = tnt; 747 748 return pt_enc_next(encoder, &packet); 749 } 750 751 int pt_encode_tip_pge(struct pt_encoder *encoder, uint64_t ip, 752 enum pt_ip_compression ipc) 753 { 754 struct pt_packet packet; 755 756 packet.type = ppt_tip_pge; 757 packet.payload.ip.ip = ip; 758 packet.payload.ip.ipc = ipc; 759 760 return pt_enc_next(encoder, &packet); 761 } 762 763 int pt_encode_tip_pgd(struct pt_encoder *encoder, uint64_t ip, 764 enum pt_ip_compression ipc) 765 { 766 struct pt_packet packet; 767 768 packet.type = ppt_tip_pgd; 769 packet.payload.ip.ip = ip; 770 packet.payload.ip.ipc = ipc; 771 772 return pt_enc_next(encoder, &packet); 773 } 774 775 int pt_encode_fup(struct pt_encoder *encoder, uint64_t ip, 776 enum pt_ip_compression ipc) 777 { 778 struct pt_packet packet; 779 780 packet.type = ppt_fup; 781 packet.payload.ip.ip = ip; 782 packet.payload.ip.ipc = ipc; 783 784 return pt_enc_next(encoder, &packet); 785 } 786 787 int pt_encode_pip(struct pt_encoder *encoder, uint64_t cr3, uint8_t flags) 788 { 789 struct pt_packet packet; 790 791 packet.type = ppt_pip; 792 packet.payload.pip.cr3 = cr3; 793 packet.payload.pip.nr = (flags & pt_pl_pip_nr) != 0; 794 795 return pt_enc_next(encoder, &packet); 796 } 797 798 int pt_encode_ovf(struct pt_encoder *encoder) 799 { 800 struct pt_packet packet; 801 802 packet.type = ppt_ovf; 803 804 return pt_enc_next(encoder, &packet); 805 } 806 807 int pt_encode_mode_exec(struct pt_encoder *encoder, enum pt_exec_mode mode) 808 { 809 struct pt_packet packet; 810 811 packet.type = ppt_mode; 812 packet.payload.mode.leaf = pt_mol_exec; 813 packet.payload.mode.bits.exec = pt_set_exec_mode(mode); 814 815 return pt_enc_next(encoder, &packet); 816 } 817 818 819 int pt_encode_mode_tsx(struct pt_encoder *encoder, uint8_t bits) 820 { 821 struct pt_packet packet; 822 823 packet.type = ppt_mode; 824 packet.payload.mode.leaf = pt_mol_tsx; 825 826 if (bits & pt_mob_tsx_intx) 827 packet.payload.mode.bits.tsx.intx = 1; 828 else 829 packet.payload.mode.bits.tsx.intx = 0; 830 831 if (bits & pt_mob_tsx_abrt) 832 packet.payload.mode.bits.tsx.abrt = 1; 833 else 834 packet.payload.mode.bits.tsx.abrt = 0; 835 836 return pt_enc_next(encoder, &packet); 837 } 838 839 int pt_encode_tsc(struct pt_encoder *encoder, uint64_t tsc) 840 { 841 struct pt_packet packet; 842 843 packet.type = ppt_tsc; 844 packet.payload.tsc.tsc = tsc; 845 846 return pt_enc_next(encoder, &packet); 847 } 848 849 int pt_encode_cbr(struct pt_encoder *encoder, uint8_t cbr) 850 { 851 struct pt_packet packet; 852 853 packet.type = ppt_cbr; 854 packet.payload.cbr.ratio = cbr; 855 856 return pt_enc_next(encoder, &packet); 857 } 858 859 int pt_encode_tma(struct pt_encoder *encoder, uint16_t ctc, uint16_t fc) 860 { 861 struct pt_packet packet; 862 863 packet.type = ppt_tma; 864 packet.payload.tma.ctc = ctc; 865 packet.payload.tma.fc = fc; 866 867 return pt_enc_next(encoder, &packet); 868 } 869 870 int pt_encode_mtc(struct pt_encoder *encoder, uint8_t ctc) 871 { 872 struct pt_packet packet; 873 874 packet.type = ppt_mtc; 875 packet.payload.mtc.ctc = ctc; 876 877 return pt_enc_next(encoder, &packet); 878 } 879 880 int pt_encode_cyc(struct pt_encoder *encoder, uint32_t ctc) 881 { 882 struct pt_packet packet; 883 884 packet.type = ppt_cyc; 885 packet.payload.cyc.value = ctc; 886 887 return pt_enc_next(encoder, &packet); 888 } 889 890 int pt_encode_stop(struct pt_encoder *encoder) 891 { 892 struct pt_packet packet; 893 894 packet.type = ppt_stop; 895 896 return pt_enc_next(encoder, &packet); 897 } 898 899 int pt_encode_vmcs(struct pt_encoder *encoder, uint64_t payload) 900 { 901 struct pt_packet packet; 902 903 packet.type = ppt_vmcs; 904 packet.payload.vmcs.base = payload; 905 906 return pt_enc_next(encoder, &packet); 907 } 908 909 int pt_encode_mnt(struct pt_encoder *encoder, uint64_t payload) 910 { 911 struct pt_packet packet; 912 913 packet.type = ppt_mnt; 914 packet.payload.mnt.payload = payload; 915 916 return pt_enc_next(encoder, &packet); 917 } 918