xref: /freebsd/contrib/processor-trace/libipt/src/pt_encoder.c (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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