]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/processor-trace/libipt/src/pt_encoder.c
Import riscv DTS files
[FreeBSD/FreeBSD.git] / contrib / processor-trace / libipt / src / pt_encoder.c
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 }