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
pt_encoder_init(struct pt_encoder * encoder,const struct pt_config * config)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
pt_encoder_fini(struct pt_encoder * encoder)55 void pt_encoder_fini(struct pt_encoder *encoder)
56 {
57 (void) encoder;
58
59 /* Nothing to do. */
60 }
61
pt_alloc_encoder(const struct pt_config * config)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
pt_free_encoder(struct pt_encoder * encoder)80 void pt_free_encoder(struct pt_encoder *encoder)
81 {
82 pt_encoder_fini(encoder);
83 free(encoder);
84 }
85
pt_enc_sync_set(struct pt_encoder * encoder,uint64_t offset)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
pt_enc_get_offset(const struct pt_encoder * encoder,uint64_t * offset)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
pt_enc_get_config(const struct pt_encoder * encoder)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 */
pt_reserve(const struct pt_encoder * encoder,unsigned int size)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 */
pt_ipc_size(enum pt_ip_compression ipc)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 */
pt_encode_int(uint8_t * pos,uint64_t val,int size)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 */
pt_encode_ip(struct pt_encoder * encoder,enum pt_opcode op,const struct pt_packet_ip * packet)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
pt_enc_next(struct pt_encoder * encoder,const struct pt_packet * packet)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
pt_encode_pad(struct pt_encoder * encoder)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
pt_encode_psb(struct pt_encoder * encoder)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
pt_encode_psbend(struct pt_encoder * encoder)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
pt_encode_tip(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_tnt_8(struct pt_encoder * encoder,uint8_t tnt,int size)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
pt_encode_tnt_64(struct pt_encoder * encoder,uint64_t tnt,int size)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
pt_encode_tip_pge(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_tip_pgd(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_fup(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_pip(struct pt_encoder * encoder,uint64_t cr3,uint8_t flags)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
pt_encode_ovf(struct pt_encoder * encoder)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
pt_encode_mode_exec(struct pt_encoder * encoder,enum pt_exec_mode mode)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
pt_encode_mode_tsx(struct pt_encoder * encoder,uint8_t bits)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
pt_encode_tsc(struct pt_encoder * encoder,uint64_t tsc)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
pt_encode_cbr(struct pt_encoder * encoder,uint8_t cbr)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
pt_encode_tma(struct pt_encoder * encoder,uint16_t ctc,uint16_t fc)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
pt_encode_mtc(struct pt_encoder * encoder,uint8_t ctc)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
pt_encode_cyc(struct pt_encoder * encoder,uint32_t ctc)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
pt_encode_stop(struct pt_encoder * encoder)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
pt_encode_vmcs(struct pt_encoder * encoder,uint64_t payload)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
pt_encode_mnt(struct pt_encoder * encoder,uint64_t payload)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