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