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
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 = (uint64_t) (int64_t) (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,
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
pt_enc_next(struct pt_encoder * encoder,const struct pt_packet * packet)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
pt_encode_pad(struct pt_encoder * encoder)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
pt_encode_psb(struct pt_encoder * encoder)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
pt_encode_psbend(struct pt_encoder * encoder)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
pt_encode_tip(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_tnt_8(struct pt_encoder * encoder,uint8_t tnt,int size)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
pt_encode_tnt_64(struct pt_encoder * encoder,uint64_t tnt,int size)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
pt_encode_tip_pge(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_tip_pgd(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_fup(struct pt_encoder * encoder,uint64_t ip,enum pt_ip_compression ipc)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
pt_encode_pip(struct pt_encoder * encoder,uint64_t cr3,uint8_t flags)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
pt_encode_ovf(struct pt_encoder * encoder)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
pt_encode_mode_exec(struct pt_encoder * encoder,enum pt_exec_mode mode)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
pt_encode_mode_tsx(struct pt_encoder * encoder,uint8_t bits)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
pt_encode_tsc(struct pt_encoder * encoder,uint64_t tsc)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
pt_encode_cbr(struct pt_encoder * encoder,uint8_t cbr)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
pt_encode_tma(struct pt_encoder * encoder,uint16_t ctc,uint16_t fc)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
pt_encode_mtc(struct pt_encoder * encoder,uint8_t ctc)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
pt_encode_cyc(struct pt_encoder * encoder,uint32_t ctc)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
pt_encode_stop(struct pt_encoder * encoder)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
pt_encode_vmcs(struct pt_encoder * encoder,uint64_t payload)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
pt_encode_mnt(struct pt_encoder * encoder,uint64_t payload)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