]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/processor-trace/libipt/src/pt_encoder.c
Import Intel Processor Trace decoder library from
[FreeBSD/FreeBSD.git] / contrib / processor-trace / libipt / src / pt_encoder.c
1 /*
2  * Copyright (c) 2014-2018, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *  * Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *  * Neither the name of Intel Corporation nor the names of its contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "pt_encoder.h"
30 #include "pt_config.h"
31 #include "pt_opcodes.h"
32
33 #include <string.h>
34 #include <stdlib.h>
35
36
37 int pt_encoder_init(struct pt_encoder *encoder, const struct pt_config *config)
38 {
39         int errcode;
40
41         if (!encoder)
42                 return -pte_invalid;
43
44         memset(encoder, 0, sizeof(*encoder));
45
46         errcode = pt_config_from_user(&encoder->config, config);
47         if (errcode < 0)
48                 return errcode;
49
50         encoder->pos = encoder->config.begin;
51
52         return 0;
53 }
54
55 void pt_encoder_fini(struct pt_encoder *encoder)
56 {
57         (void) encoder;
58
59         /* Nothing to do. */
60 }
61
62 struct pt_encoder *pt_alloc_encoder(const struct pt_config *config)
63 {
64         struct pt_encoder *encoder;
65         int errcode;
66
67         encoder = malloc(sizeof(*encoder));
68         if (!encoder)
69                 return NULL;
70
71         errcode = pt_encoder_init(encoder, config);
72         if (errcode < 0) {
73                 free(encoder);
74                 return NULL;
75         }
76
77         return encoder;
78 }
79
80 void pt_free_encoder(struct pt_encoder *encoder)
81 {
82         pt_encoder_fini(encoder);
83         free(encoder);
84 }
85
86 int pt_enc_sync_set(struct pt_encoder *encoder, uint64_t offset)
87 {
88         uint8_t *begin, *end, *pos;
89
90         if (!encoder)
91                 return -pte_invalid;
92
93         begin = encoder->config.begin;
94         end = encoder->config.end;
95         pos = begin + offset;
96
97         if (end < pos || pos < begin)
98                 return -pte_eos;
99
100         encoder->pos = pos;
101         return 0;
102 }
103
104 int pt_enc_get_offset(const struct pt_encoder *encoder, uint64_t *offset)
105 {
106         const uint8_t *raw, *begin;
107
108         if (!encoder || !offset)
109                 return -pte_invalid;
110
111         /* The encoder is synchronized at all times. */
112         raw = encoder->pos;
113         if (!raw)
114                 return -pte_internal;
115
116         begin = encoder->config.begin;
117         if (!begin)
118                 return -pte_internal;
119
120         *offset = raw - begin;
121         return 0;
122 }
123
124 const struct pt_config *pt_enc_get_config(const struct pt_encoder *encoder)
125 {
126         if (!encoder)
127                 return NULL;
128
129         return &encoder->config;
130 }
131
132 /* Check the remaining space.
133  *
134  * Returns zero if there are at least \@size bytes of free space available in
135  * \@encoder's Intel PT buffer.
136  *
137  * Returns -pte_eos if not enough space is available.
138  * Returns -pte_internal if \@encoder is NULL.
139  * Returns -pte_internal if \@encoder is not synchronized.
140  */
141 static int pt_reserve(const struct pt_encoder *encoder, unsigned int size)
142 {
143         const uint8_t *begin, *end, *pos;
144
145         if (!encoder)
146                 return -pte_internal;
147
148         /* The encoder is synchronized at all times. */
149         pos = encoder->pos;
150         if (!pos)
151                 return -pte_internal;
152
153         begin = encoder->config.begin;
154         end = encoder->config.end;
155
156         pos += size;
157         if (pos < begin || end < pos)
158                 return -pte_eos;
159
160         return 0;
161 }
162
163 /* Return the size of an IP payload based on its IP compression.
164  *
165  * Returns -pte_bad_packet if \@ipc is not a valid IP compression.
166  */
167 static int pt_ipc_size(enum pt_ip_compression ipc)
168 {
169         switch (ipc) {
170         case pt_ipc_suppressed:
171                 return 0;
172
173         case pt_ipc_update_16:
174                 return pt_pl_ip_upd16_size;
175
176         case pt_ipc_update_32:
177                 return pt_pl_ip_upd32_size;
178
179         case pt_ipc_update_48:
180                 return pt_pl_ip_upd48_size;
181
182         case pt_ipc_sext_48:
183                 return pt_pl_ip_sext48_size;
184
185         case pt_ipc_full:
186                 return pt_pl_ip_full_size;
187         }
188
189         return -pte_invalid;
190 }
191
192 /* Encode an integer value.
193  *
194  * Writes the \@size least signifficant bytes of \@value starting from \@pos.
195  *
196  * The caller needs to ensure that there is enough space available.
197  *
198  * Returns the updated position.
199  */
200 static uint8_t *pt_encode_int(uint8_t *pos, uint64_t val, int size)
201 {
202         for (; size; --size, val >>= 8)
203                 *pos++ = (uint8_t) val;
204
205         return pos;
206 }
207
208 /* Encode an IP packet.
209  *
210  * Write an IP packet with opcode \@opc and payload from \@packet if there is
211  * enough space in \@encoder's Intel PT buffer.
212  *
213  * Returns the number of bytes written on success.
214  *
215  * Returns -pte_eos if there is not enough space.
216  * Returns -pte_internal if \@encoder or \@packet is NULL.
217  * Returns -pte_invalid if \@packet.ipc is not valid.
218  */
219 static int pt_encode_ip(struct pt_encoder *encoder, enum pt_opcode op,
220                         const struct pt_packet_ip *packet)
221 {
222         uint8_t *pos;
223         uint8_t opc, ipc;
224         int size, errcode;
225
226         if (!encoder || !packet)
227                 return pte_internal;
228
229         size = pt_ipc_size(packet->ipc);
230         if (size < 0)
231                 return size;
232
233         errcode = pt_reserve(encoder, /* opc size = */ 1 + size);
234         if (errcode < 0)
235                 return errcode;
236
237         /* We already checked the ipc in pt_ipc_size(). */
238         ipc = (uint8_t) (packet->ipc << pt_opm_ipc_shr);
239         opc = (uint8_t) op;
240
241         pos = encoder->pos;
242         *pos++ = opc | ipc;
243
244         encoder->pos = pt_encode_int(pos, packet->ip, size);
245         return /* opc size = */ 1 + size;
246 }
247
248 int pt_enc_next(struct pt_encoder *encoder, const struct pt_packet *packet)
249 {
250         uint8_t *pos, *begin;
251         int errcode;
252
253         if (!encoder || !packet)
254                 return -pte_invalid;
255
256         pos = begin = encoder->pos;
257         switch (packet->type) {
258         case ppt_pad:
259                 errcode = pt_reserve(encoder, ptps_pad);
260                 if (errcode < 0)
261                         return errcode;
262
263                 *pos++ = pt_opc_pad;
264
265                 encoder->pos = pos;
266                 return (int) (pos - begin);
267
268         case ppt_psb: {
269                 uint64_t psb;
270
271                 errcode = pt_reserve(encoder, ptps_psb);
272                 if (errcode < 0)
273                         return errcode;
274
275                 psb = ((uint64_t) pt_psb_hilo << 48 |
276                        (uint64_t) pt_psb_hilo << 32 |
277                        (uint64_t) pt_psb_hilo << 16 |
278                        (uint64_t) pt_psb_hilo);
279
280                 pos = pt_encode_int(pos, psb, 8);
281                 pos = pt_encode_int(pos, psb, 8);
282
283                 encoder->pos = pos;
284                 return (int) (pos - begin);
285         }
286
287         case ppt_psbend:
288                 errcode = pt_reserve(encoder, ptps_psbend);
289                 if (errcode < 0)
290                         return errcode;
291
292                 *pos++ = pt_opc_ext;
293                 *pos++ = pt_ext_psbend;
294
295                 encoder->pos = pos;
296                 return (int) (pos - begin);
297
298         case ppt_ovf:
299                 errcode = pt_reserve(encoder, ptps_ovf);
300                 if (errcode < 0)
301                         return errcode;
302
303                 *pos++ = pt_opc_ext;
304                 *pos++ = pt_ext_ovf;
305
306                 encoder->pos = pos;
307                 return (int) (pos - begin);
308
309         case ppt_fup:
310                 return pt_encode_ip(encoder, pt_opc_fup, &packet->payload.ip);
311
312         case ppt_tip:
313                 return pt_encode_ip(encoder, pt_opc_tip, &packet->payload.ip);
314
315         case ppt_tip_pge:
316                 return pt_encode_ip(encoder, pt_opc_tip_pge,
317                                     &packet->payload.ip);
318
319         case ppt_tip_pgd:
320                 return pt_encode_ip(encoder, pt_opc_tip_pgd,
321                                     &packet->payload.ip);
322
323         case ppt_tnt_8: {
324                 uint8_t opc, stop;
325
326                 if (packet->payload.tnt.bit_size >= 7)
327                         return -pte_bad_packet;
328
329                 errcode = pt_reserve(encoder, ptps_tnt_8);
330                 if (errcode < 0)
331                         return errcode;
332
333                 stop = packet->payload.tnt.bit_size + pt_opm_tnt_8_shr;
334                 opc = (uint8_t)
335                         (packet->payload.tnt.payload << pt_opm_tnt_8_shr);
336
337                 *pos++ = (uint8_t) (opc | (1u << stop));
338
339                 encoder->pos = pos;
340                 return (int) (pos - begin);
341         }
342
343         case ppt_tnt_64: {
344                 uint64_t tnt, stop;
345
346                 errcode = pt_reserve(encoder, ptps_tnt_64);
347                 if (errcode < 0)
348                         return errcode;
349
350                 if (packet->payload.tnt.bit_size >= pt_pl_tnt_64_bits)
351                         return -pte_invalid;
352
353                 stop = 1ull << packet->payload.tnt.bit_size;
354                 tnt = packet->payload.tnt.payload;
355
356                 if (tnt & ~(stop - 1))
357                         return -pte_invalid;
358
359                 *pos++ = pt_opc_ext;
360                 *pos++ = pt_ext_tnt_64;
361                 pos = pt_encode_int(pos, tnt | stop, pt_pl_tnt_64_size);
362
363                 encoder->pos = pos;
364                 return (int) (pos - begin);
365         }
366
367         case ppt_mode: {
368                 uint8_t mode;
369
370                 errcode = pt_reserve(encoder, ptps_mode);
371                 if (errcode < 0)
372                         return errcode;
373
374                 switch (packet->payload.mode.leaf) {
375                 default:
376                         return -pte_bad_packet;
377
378                 case pt_mol_exec:
379                         mode = pt_mol_exec;
380
381                         if (packet->payload.mode.bits.exec.csl)
382                                 mode |= pt_mob_exec_csl;
383
384                         if (packet->payload.mode.bits.exec.csd)
385                                 mode |= pt_mob_exec_csd;
386                         break;
387
388                 case pt_mol_tsx:
389                         mode = pt_mol_tsx;
390
391                         if (packet->payload.mode.bits.tsx.intx)
392                                 mode |= pt_mob_tsx_intx;
393
394                         if (packet->payload.mode.bits.tsx.abrt)
395                                 mode |= pt_mob_tsx_abrt;
396                         break;
397                 }
398
399                 *pos++ = pt_opc_mode;
400                 *pos++ = mode;
401
402                 encoder->pos = pos;
403                 return (int) (pos - begin);
404         }
405
406         case ppt_pip: {
407                 uint64_t cr3;
408
409                 errcode = pt_reserve(encoder, ptps_pip);
410                 if (errcode < 0)
411                         return errcode;
412
413                 cr3 = packet->payload.pip.cr3;
414                 cr3 >>= pt_pl_pip_shl;
415                 cr3 <<= pt_pl_pip_shr;
416
417                 if (packet->payload.pip.nr)
418                         cr3 |= (uint64_t) pt_pl_pip_nr;
419
420                 *pos++ = pt_opc_ext;
421                 *pos++ = pt_ext_pip;
422                 pos = pt_encode_int(pos, cr3, pt_pl_pip_size);
423
424                 encoder->pos = pos;
425                 return (int) (pos - begin);
426         }
427
428         case ppt_tsc:
429                 errcode = pt_reserve(encoder, ptps_tsc);
430                 if (errcode < 0)
431                         return errcode;
432
433                 *pos++ = pt_opc_tsc;
434                 pos = pt_encode_int(pos, packet->payload.tsc.tsc,
435                                     pt_pl_tsc_size);
436
437                 encoder->pos = pos;
438                 return (int) (pos - begin);
439
440         case ppt_cbr:
441                 errcode = pt_reserve(encoder, ptps_cbr);
442                 if (errcode < 0)
443                         return errcode;
444
445                 *pos++ = pt_opc_ext;
446                 *pos++ = pt_ext_cbr;
447                 *pos++ = packet->payload.cbr.ratio;
448                 *pos++ = 0;
449
450                 encoder->pos = pos;
451                 return (int) (pos - begin);
452
453         case ppt_tma: {
454                 uint16_t ctc, fc;
455
456                 errcode = pt_reserve(encoder, ptps_tma);
457                 if (errcode < 0)
458                         return errcode;
459
460                 ctc = packet->payload.tma.ctc;
461                 fc = packet->payload.tma.fc;
462
463                 if (fc & ~pt_pl_tma_fc_mask)
464                         return -pte_bad_packet;
465
466                 *pos++ = pt_opc_ext;
467                 *pos++ = pt_ext_tma;
468                 pos = pt_encode_int(pos, ctc, pt_pl_tma_ctc_size);
469                 *pos++ = 0;
470                 pos = pt_encode_int(pos, fc, pt_pl_tma_fc_size);
471
472                 encoder->pos = pos;
473                 return (int) (pos - begin);
474         }
475
476         case ppt_mtc:
477                 errcode = pt_reserve(encoder, ptps_mtc);
478                 if (errcode < 0)
479                         return errcode;
480
481                 *pos++ = pt_opc_mtc;
482                 *pos++ = packet->payload.mtc.ctc;
483
484                 encoder->pos = pos;
485                 return (int) (pos - begin);
486
487         case ppt_cyc: {
488                 uint8_t byte[pt_pl_cyc_max_size], index, end;
489                 uint64_t ctc;
490
491                 ctc = (uint8_t) packet->payload.cyc.value;
492                 ctc <<= pt_opm_cyc_shr;
493
494                 byte[0] = pt_opc_cyc;
495                 byte[0] |= (uint8_t) ctc;
496
497                 ctc = packet->payload.cyc.value;
498                 ctc >>= (8 - pt_opm_cyc_shr);
499                 if (ctc)
500                         byte[0] |= pt_opm_cyc_ext;
501
502                 for (end = 1; ctc; ++end) {
503                         /* Check if the CYC payload is too big. */
504                         if (pt_pl_cyc_max_size <= end)
505                                 return -pte_bad_packet;
506
507                         ctc <<= pt_opm_cycx_shr;
508
509                         byte[end] = (uint8_t) ctc;
510
511                         ctc >>= 8;
512                         if (ctc)
513                                 byte[end] |= pt_opm_cycx_ext;
514                 }
515
516                 errcode = pt_reserve(encoder, end);
517                 if (errcode < 0)
518                         return errcode;
519
520                 for (index = 0; index < end; ++index)
521                         *pos++ = byte[index];
522
523                 encoder->pos = pos;
524                 return (int) (pos - begin);
525         }
526
527         case ppt_stop:
528                 errcode = pt_reserve(encoder, ptps_stop);
529                 if (errcode < 0)
530                         return errcode;
531
532                 *pos++ = pt_opc_ext;
533                 *pos++ = pt_ext_stop;
534
535                 encoder->pos = pos;
536                 return (int) (pos - begin);
537
538         case ppt_vmcs:
539                 errcode = pt_reserve(encoder, ptps_vmcs);
540                 if (errcode < 0)
541                         return errcode;
542
543                 *pos++ = pt_opc_ext;
544                 *pos++ = pt_ext_vmcs;
545                 pos = pt_encode_int(pos,
546                                     packet->payload.vmcs.base >> pt_pl_vmcs_shl,
547                                     pt_pl_vmcs_size);
548
549                 encoder->pos = pos;
550                 return (int) (pos - begin);
551
552         case ppt_mnt:
553                 errcode = pt_reserve(encoder, ptps_mnt);
554                 if (errcode < 0)
555                         return errcode;
556
557                 *pos++ = pt_opc_ext;
558                 *pos++ = pt_ext_ext2;
559                 *pos++ = pt_ext2_mnt;
560                 pos = pt_encode_int(pos, packet->payload.mnt.payload,
561                                     pt_pl_mnt_size);
562
563                 encoder->pos = pos;
564                 return (int) (pos - begin);
565
566         case ppt_exstop: {
567                 uint8_t ext;
568
569                 errcode = pt_reserve(encoder, ptps_exstop);
570                 if (errcode < 0)
571                         return errcode;
572
573                 ext = packet->payload.exstop.ip ?
574                         pt_ext_exstop_ip : pt_ext_exstop;
575
576                 *pos++ = pt_opc_ext;
577                 *pos++ = ext;
578
579                 encoder->pos = pos;
580                 return (int) (pos - begin);
581         }
582
583         case ppt_mwait:
584                 errcode = pt_reserve(encoder, ptps_mwait);
585                 if (errcode < 0)
586                         return errcode;
587
588                 *pos++ = pt_opc_ext;
589                 *pos++ = pt_ext_mwait;
590                 pos = pt_encode_int(pos, packet->payload.mwait.hints,
591                                     pt_pl_mwait_hints_size);
592                 pos = pt_encode_int(pos, packet->payload.mwait.ext,
593                                     pt_pl_mwait_ext_size);
594
595                 encoder->pos = pos;
596                 return (int) (pos - begin);
597
598         case ppt_pwre: {
599                 uint64_t payload;
600
601                 errcode = pt_reserve(encoder, ptps_pwre);
602                 if (errcode < 0)
603                         return errcode;
604
605                 payload = 0ull;
606                 payload |= ((uint64_t) packet->payload.pwre.state <<
607                             pt_pl_pwre_state_shr) &
608                         (uint64_t) pt_pl_pwre_state_mask;
609                 payload |= ((uint64_t) packet->payload.pwre.sub_state <<
610                             pt_pl_pwre_sub_state_shr) &
611                         (uint64_t) pt_pl_pwre_sub_state_mask;
612
613                 if (packet->payload.pwre.hw)
614                         payload |= (uint64_t) pt_pl_pwre_hw_mask;
615
616                 *pos++ = pt_opc_ext;
617                 *pos++ = pt_ext_pwre;
618                 pos = pt_encode_int(pos, payload, pt_pl_pwre_size);
619
620                 encoder->pos = pos;
621                 return (int) (pos - begin);
622         }
623
624         case ppt_pwrx: {
625                 uint64_t payload;
626
627                 errcode = pt_reserve(encoder, ptps_pwrx);
628                 if (errcode < 0)
629                         return errcode;
630
631                 payload = 0ull;
632                 payload |= ((uint64_t) packet->payload.pwrx.last <<
633                             pt_pl_pwrx_last_shr) &
634                         (uint64_t) pt_pl_pwrx_last_mask;
635                 payload |= ((uint64_t) packet->payload.pwrx.deepest <<
636                             pt_pl_pwrx_deepest_shr) &
637                         (uint64_t) pt_pl_pwrx_deepest_mask;
638
639                 if (packet->payload.pwrx.interrupt)
640                         payload |= (uint64_t) pt_pl_pwrx_wr_int;
641                 if (packet->payload.pwrx.store)
642                         payload |= (uint64_t) pt_pl_pwrx_wr_store;
643                 if (packet->payload.pwrx.autonomous)
644                         payload |= (uint64_t) pt_pl_pwrx_wr_hw;
645
646                 *pos++ = pt_opc_ext;
647                 *pos++ = pt_ext_pwrx;
648                 pos = pt_encode_int(pos, payload, pt_pl_pwrx_size);
649
650                 encoder->pos = pos;
651                 return (int) (pos - begin);
652         }
653
654         case ppt_ptw: {
655                 uint8_t plc, ext;
656                 int size;
657
658                 plc = packet->payload.ptw.plc;
659
660                 size = pt_ptw_size(plc);
661                 if (size < 0)
662                         return size;
663
664                 errcode = pt_reserve(encoder, pt_opcs_ptw + size);
665                 if (errcode < 0)
666                         return errcode;
667
668                 ext = pt_ext_ptw;
669                 ext |= plc << pt_opm_ptw_pb_shr;
670
671                 if (packet->payload.ptw.ip)
672                         ext |= (uint8_t) pt_opm_ptw_ip;
673
674                 *pos++ = pt_opc_ext;
675                 *pos++ = ext;
676                 pos = pt_encode_int(pos, packet->payload.ptw.payload, size);
677
678                 encoder->pos = pos;
679                 return (int) (pos - begin);
680         }
681
682         case ppt_unknown:
683         case ppt_invalid:
684                 return -pte_bad_opc;
685         }
686
687         return -pte_bad_opc;
688 }
689
690 int pt_encode_pad(struct pt_encoder *encoder)
691 {
692         struct pt_packet packet;
693
694         packet.type = ppt_pad;
695
696         return pt_enc_next(encoder, &packet);
697 }
698
699 int pt_encode_psb(struct pt_encoder *encoder)
700 {
701         struct pt_packet packet;
702
703         packet.type = ppt_psb;
704
705         return pt_enc_next(encoder, &packet);
706 }
707
708 int pt_encode_psbend(struct pt_encoder *encoder)
709 {
710         struct pt_packet packet;
711
712         packet.type = ppt_psbend;
713
714         return pt_enc_next(encoder, &packet);
715 }
716
717 int pt_encode_tip(struct pt_encoder *encoder, uint64_t ip,
718                   enum pt_ip_compression ipc)
719 {
720         struct pt_packet packet;
721
722         packet.type = ppt_tip;
723         packet.payload.ip.ip = ip;
724         packet.payload.ip.ipc = ipc;
725
726         return pt_enc_next(encoder, &packet);
727 }
728
729 int pt_encode_tnt_8(struct pt_encoder *encoder, uint8_t tnt, int size)
730 {
731         struct pt_packet packet;
732
733         packet.type = ppt_tnt_8;
734         packet.payload.tnt.bit_size = (uint8_t) size;
735         packet.payload.tnt.payload = tnt;
736
737         return pt_enc_next(encoder, &packet);
738 }
739
740 int pt_encode_tnt_64(struct pt_encoder *encoder, uint64_t tnt, int size)
741 {
742         struct pt_packet packet;
743
744         packet.type = ppt_tnt_64;
745         packet.payload.tnt.bit_size = (uint8_t) size;
746         packet.payload.tnt.payload = tnt;
747
748         return pt_enc_next(encoder, &packet);
749 }
750
751 int pt_encode_tip_pge(struct pt_encoder *encoder, uint64_t ip,
752                       enum pt_ip_compression ipc)
753 {
754         struct pt_packet packet;
755
756         packet.type = ppt_tip_pge;
757         packet.payload.ip.ip = ip;
758         packet.payload.ip.ipc = ipc;
759
760         return pt_enc_next(encoder, &packet);
761 }
762
763 int pt_encode_tip_pgd(struct pt_encoder *encoder, uint64_t ip,
764                       enum pt_ip_compression ipc)
765 {
766         struct pt_packet packet;
767
768         packet.type = ppt_tip_pgd;
769         packet.payload.ip.ip = ip;
770         packet.payload.ip.ipc = ipc;
771
772         return pt_enc_next(encoder, &packet);
773 }
774
775 int pt_encode_fup(struct pt_encoder *encoder, uint64_t ip,
776                   enum pt_ip_compression ipc)
777 {
778         struct pt_packet packet;
779
780         packet.type = ppt_fup;
781         packet.payload.ip.ip = ip;
782         packet.payload.ip.ipc = ipc;
783
784         return pt_enc_next(encoder, &packet);
785 }
786
787 int pt_encode_pip(struct pt_encoder *encoder, uint64_t cr3, uint8_t flags)
788 {
789         struct pt_packet packet;
790
791         packet.type = ppt_pip;
792         packet.payload.pip.cr3 = cr3;
793         packet.payload.pip.nr = (flags & pt_pl_pip_nr) != 0;
794
795         return pt_enc_next(encoder, &packet);
796 }
797
798 int pt_encode_ovf(struct pt_encoder *encoder)
799 {
800         struct pt_packet packet;
801
802         packet.type = ppt_ovf;
803
804         return pt_enc_next(encoder, &packet);
805 }
806
807 int pt_encode_mode_exec(struct pt_encoder *encoder, enum pt_exec_mode mode)
808 {
809         struct pt_packet packet;
810
811         packet.type = ppt_mode;
812         packet.payload.mode.leaf = pt_mol_exec;
813         packet.payload.mode.bits.exec = pt_set_exec_mode(mode);
814
815         return pt_enc_next(encoder, &packet);
816 }
817
818
819 int pt_encode_mode_tsx(struct pt_encoder *encoder, uint8_t bits)
820 {
821         struct pt_packet packet;
822
823         packet.type = ppt_mode;
824         packet.payload.mode.leaf = pt_mol_tsx;
825
826         if (bits & pt_mob_tsx_intx)
827                 packet.payload.mode.bits.tsx.intx = 1;
828         else
829                 packet.payload.mode.bits.tsx.intx = 0;
830
831         if (bits & pt_mob_tsx_abrt)
832                 packet.payload.mode.bits.tsx.abrt = 1;
833         else
834                 packet.payload.mode.bits.tsx.abrt = 0;
835
836         return pt_enc_next(encoder, &packet);
837 }
838
839 int pt_encode_tsc(struct pt_encoder *encoder, uint64_t tsc)
840 {
841         struct pt_packet packet;
842
843         packet.type = ppt_tsc;
844         packet.payload.tsc.tsc = tsc;
845
846         return pt_enc_next(encoder, &packet);
847 }
848
849 int pt_encode_cbr(struct pt_encoder *encoder, uint8_t cbr)
850 {
851         struct pt_packet packet;
852
853         packet.type = ppt_cbr;
854         packet.payload.cbr.ratio = cbr;
855
856         return pt_enc_next(encoder, &packet);
857 }
858
859 int pt_encode_tma(struct pt_encoder *encoder, uint16_t ctc, uint16_t fc)
860 {
861         struct pt_packet packet;
862
863         packet.type = ppt_tma;
864         packet.payload.tma.ctc = ctc;
865         packet.payload.tma.fc = fc;
866
867         return pt_enc_next(encoder, &packet);
868 }
869
870 int pt_encode_mtc(struct pt_encoder *encoder, uint8_t ctc)
871 {
872         struct pt_packet packet;
873
874         packet.type = ppt_mtc;
875         packet.payload.mtc.ctc = ctc;
876
877         return pt_enc_next(encoder, &packet);
878 }
879
880 int pt_encode_cyc(struct pt_encoder *encoder, uint32_t ctc)
881 {
882         struct pt_packet packet;
883
884         packet.type = ppt_cyc;
885         packet.payload.cyc.value = ctc;
886
887         return pt_enc_next(encoder, &packet);
888 }
889
890 int pt_encode_stop(struct pt_encoder *encoder)
891 {
892         struct pt_packet packet;
893
894         packet.type = ppt_stop;
895
896         return pt_enc_next(encoder, &packet);
897 }
898
899 int pt_encode_vmcs(struct pt_encoder *encoder, uint64_t payload)
900 {
901         struct pt_packet packet;
902
903         packet.type = ppt_vmcs;
904         packet.payload.vmcs.base = payload;
905
906         return pt_enc_next(encoder, &packet);
907 }
908
909 int pt_encode_mnt(struct pt_encoder *encoder, uint64_t payload)
910 {
911         struct pt_packet packet;
912
913         packet.type = ppt_mnt;
914         packet.payload.mnt.payload = payload;
915
916         return pt_enc_next(encoder, &packet);
917 }