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_packet_decoder.h"
30 #include "pt_decoder_function.h"
31 #include "pt_packet.h"
32 #include "pt_sync.h"
33 #include "pt_config.h"
34 #include "pt_opcodes.h"
35
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stddef.h>
39
40
pt_pkt_decoder_init(struct pt_packet_decoder * decoder,const struct pt_config * config)41 int pt_pkt_decoder_init(struct pt_packet_decoder *decoder,
42 const struct pt_config *config)
43 {
44 int errcode;
45
46 if (!decoder || !config)
47 return -pte_invalid;
48
49 memset(decoder, 0, sizeof(*decoder));
50
51 errcode = pt_config_from_user(&decoder->config, config);
52 if (errcode < 0)
53 return errcode;
54
55 return 0;
56 }
57
pt_pkt_alloc_decoder(const struct pt_config * config)58 struct pt_packet_decoder *pt_pkt_alloc_decoder(const struct pt_config *config)
59 {
60 struct pt_packet_decoder *decoder;
61 int errcode;
62
63 decoder = malloc(sizeof(*decoder));
64 if (!decoder)
65 return NULL;
66
67 errcode = pt_pkt_decoder_init(decoder, config);
68 if (errcode < 0) {
69 free(decoder);
70 return NULL;
71 }
72
73 return decoder;
74 }
75
pt_pkt_decoder_fini(struct pt_packet_decoder * decoder)76 void pt_pkt_decoder_fini(struct pt_packet_decoder *decoder)
77 {
78 (void) decoder;
79
80 /* Nothing to do. */
81 }
82
pt_pkt_free_decoder(struct pt_packet_decoder * decoder)83 void pt_pkt_free_decoder(struct pt_packet_decoder *decoder)
84 {
85 pt_pkt_decoder_fini(decoder);
86 free(decoder);
87 }
88
pt_pkt_sync_forward(struct pt_packet_decoder * decoder)89 int pt_pkt_sync_forward(struct pt_packet_decoder *decoder)
90 {
91 const uint8_t *pos, *sync, *begin;
92 ptrdiff_t space;
93 int errcode;
94
95 if (!decoder)
96 return -pte_invalid;
97
98 begin = decoder->config.begin;
99 sync = decoder->sync;
100 pos = decoder->pos;
101 if (!pos)
102 pos = begin;
103
104 if (pos == sync)
105 pos += ptps_psb;
106
107 if (pos < begin)
108 return -pte_internal;
109
110 /* Start a bit earlier so we find PSB that have been partially consumed
111 * by a preceding packet.
112 */
113 space = pos - begin;
114 if (ptps_psb <= space)
115 space = ptps_psb - 1;
116
117 pos -= space;
118
119 errcode = pt_sync_forward(&sync, pos, &decoder->config);
120 if (errcode < 0)
121 return errcode;
122
123 decoder->sync = sync;
124 decoder->pos = sync;
125
126 return 0;
127 }
128
pt_pkt_sync_backward(struct pt_packet_decoder * decoder)129 int pt_pkt_sync_backward(struct pt_packet_decoder *decoder)
130 {
131 const uint8_t *pos, *sync;
132 int errcode;
133
134 if (!decoder)
135 return -pte_invalid;
136
137 pos = decoder->pos;
138 if (!pos)
139 pos = decoder->config.end;
140
141 errcode = pt_sync_backward(&sync, pos, &decoder->config);
142 if (errcode < 0)
143 return errcode;
144
145 decoder->sync = sync;
146 decoder->pos = sync;
147
148 return 0;
149 }
150
pt_pkt_sync_set(struct pt_packet_decoder * decoder,uint64_t offset)151 int pt_pkt_sync_set(struct pt_packet_decoder *decoder, uint64_t offset)
152 {
153 const uint8_t *begin, *end, *pos;
154
155 if (!decoder)
156 return -pte_invalid;
157
158 begin = decoder->config.begin;
159 end = decoder->config.end;
160 pos = begin + offset;
161
162 if (end < pos || pos < begin)
163 return -pte_eos;
164
165 decoder->sync = pos;
166 decoder->pos = pos;
167
168 return 0;
169 }
170
pt_pkt_get_offset(const struct pt_packet_decoder * decoder,uint64_t * offset)171 int pt_pkt_get_offset(const struct pt_packet_decoder *decoder, uint64_t *offset)
172 {
173 const uint8_t *begin, *pos;
174
175 if (!decoder || !offset)
176 return -pte_invalid;
177
178 begin = decoder->config.begin;
179 pos = decoder->pos;
180
181 if (!pos)
182 return -pte_nosync;
183
184 *offset = (uint64_t) (int64_t) (pos - begin);
185 return 0;
186 }
187
pt_pkt_get_sync_offset(const struct pt_packet_decoder * decoder,uint64_t * offset)188 int pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder,
189 uint64_t *offset)
190 {
191 const uint8_t *begin, *sync;
192
193 if (!decoder || !offset)
194 return -pte_invalid;
195
196 begin = decoder->config.begin;
197 sync = decoder->sync;
198
199 if (!sync)
200 return -pte_nosync;
201
202 *offset = (uint64_t) (int64_t) (sync - begin);
203 return 0;
204 }
205
206 const struct pt_config *
pt_pkt_get_config(const struct pt_packet_decoder * decoder)207 pt_pkt_get_config(const struct pt_packet_decoder *decoder)
208 {
209 if (!decoder)
210 return NULL;
211
212 return &decoder->config;
213 }
214
pkt_to_user(struct pt_packet * upkt,size_t size,const struct pt_packet * pkt)215 static inline int pkt_to_user(struct pt_packet *upkt, size_t size,
216 const struct pt_packet *pkt)
217 {
218 if (!upkt || !pkt)
219 return -pte_internal;
220
221 if (upkt == pkt)
222 return 0;
223
224 /* Zero out any unknown bytes. */
225 if (sizeof(*pkt) < size) {
226 memset(upkt + sizeof(*pkt), 0, size - sizeof(*pkt));
227
228 size = sizeof(*pkt);
229 }
230
231 memcpy(upkt, pkt, size);
232
233 return 0;
234 }
235
pt_pkt_next(struct pt_packet_decoder * decoder,struct pt_packet * packet,size_t psize)236 int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet,
237 size_t psize)
238 {
239 const struct pt_decoder_function *dfun;
240 struct pt_packet pkt, *ppkt;
241 int errcode, size;
242
243 if (!packet || !decoder)
244 return -pte_invalid;
245
246 ppkt = psize == sizeof(pkt) ? packet : &pkt;
247
248 errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config);
249 if (errcode < 0)
250 return errcode;
251
252 if (!dfun)
253 return -pte_internal;
254
255 if (!dfun->packet)
256 return -pte_internal;
257
258 size = dfun->packet(decoder, ppkt);
259 if (size < 0)
260 return size;
261
262 errcode = pkt_to_user(packet, psize, ppkt);
263 if (errcode < 0)
264 return errcode;
265
266 decoder->pos += size;
267
268 return size;
269 }
270
pt_pkt_decode_unknown(struct pt_packet_decoder * decoder,struct pt_packet * packet)271 int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder,
272 struct pt_packet *packet)
273 {
274 int size;
275
276 if (!decoder)
277 return -pte_internal;
278
279 size = pt_pkt_read_unknown(packet, decoder->pos, &decoder->config);
280 if (size < 0)
281 return size;
282
283 return size;
284 }
285
pt_pkt_decode_pad(struct pt_packet_decoder * decoder,struct pt_packet * packet)286 int pt_pkt_decode_pad(struct pt_packet_decoder *decoder,
287 struct pt_packet *packet)
288 {
289 (void) decoder;
290
291 if (!packet)
292 return -pte_internal;
293
294 packet->type = ppt_pad;
295 packet->size = ptps_pad;
296
297 return ptps_pad;
298 }
299
pt_pkt_decode_psb(struct pt_packet_decoder * decoder,struct pt_packet * packet)300 int pt_pkt_decode_psb(struct pt_packet_decoder *decoder,
301 struct pt_packet *packet)
302 {
303 int size;
304
305 if (!decoder)
306 return -pte_internal;
307
308 size = pt_pkt_read_psb(decoder->pos, &decoder->config);
309 if (size < 0)
310 return size;
311
312 packet->type = ppt_psb;
313 packet->size = (uint8_t) size;
314
315 return size;
316 }
317
pt_pkt_decode_tip(struct pt_packet_decoder * decoder,struct pt_packet * packet)318 int pt_pkt_decode_tip(struct pt_packet_decoder *decoder,
319 struct pt_packet *packet)
320 {
321 int size;
322
323 if (!decoder || !packet)
324 return -pte_internal;
325
326 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
327 &decoder->config);
328 if (size < 0)
329 return size;
330
331 packet->type = ppt_tip;
332 packet->size = (uint8_t) size;
333
334 return size;
335 }
336
pt_pkt_decode_tnt_8(struct pt_packet_decoder * decoder,struct pt_packet * packet)337 int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder,
338 struct pt_packet *packet)
339 {
340 int size;
341
342 if (!decoder || !packet)
343 return -pte_internal;
344
345 size = pt_pkt_read_tnt_8(&packet->payload.tnt, decoder->pos,
346 &decoder->config);
347 if (size < 0)
348 return size;
349
350 packet->type = ppt_tnt_8;
351 packet->size = (uint8_t) size;
352
353 return size;
354 }
355
pt_pkt_decode_tnt_64(struct pt_packet_decoder * decoder,struct pt_packet * packet)356 int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder,
357 struct pt_packet *packet)
358 {
359 int size;
360
361 if (!decoder || !packet)
362 return -pte_internal;
363
364 size = pt_pkt_read_tnt_64(&packet->payload.tnt, decoder->pos,
365 &decoder->config);
366 if (size < 0)
367 return size;
368
369 packet->type = ppt_tnt_64;
370 packet->size = (uint8_t) size;
371
372 return size;
373 }
374
pt_pkt_decode_tip_pge(struct pt_packet_decoder * decoder,struct pt_packet * packet)375 int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder,
376 struct pt_packet *packet)
377 {
378 int size;
379
380 if (!decoder || !packet)
381 return -pte_internal;
382
383 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
384 &decoder->config);
385 if (size < 0)
386 return size;
387
388 packet->type = ppt_tip_pge;
389 packet->size = (uint8_t) size;
390
391 return size;
392 }
393
pt_pkt_decode_tip_pgd(struct pt_packet_decoder * decoder,struct pt_packet * packet)394 int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder,
395 struct pt_packet *packet)
396 {
397 int size;
398
399 if (!decoder || !packet)
400 return -pte_internal;
401
402 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
403 &decoder->config);
404 if (size < 0)
405 return size;
406
407 packet->type = ppt_tip_pgd;
408 packet->size = (uint8_t) size;
409
410 return size;
411 }
412
pt_pkt_decode_fup(struct pt_packet_decoder * decoder,struct pt_packet * packet)413 int pt_pkt_decode_fup(struct pt_packet_decoder *decoder,
414 struct pt_packet *packet)
415 {
416 int size;
417
418 if (!decoder || !packet)
419 return -pte_internal;
420
421 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
422 &decoder->config);
423 if (size < 0)
424 return size;
425
426 packet->type = ppt_fup;
427 packet->size = (uint8_t) size;
428
429 return size;
430 }
431
pt_pkt_decode_pip(struct pt_packet_decoder * decoder,struct pt_packet * packet)432 int pt_pkt_decode_pip(struct pt_packet_decoder *decoder,
433 struct pt_packet *packet)
434 {
435 int size;
436
437 if (!decoder || !packet)
438 return -pte_internal;
439
440 size = pt_pkt_read_pip(&packet->payload.pip, decoder->pos,
441 &decoder->config);
442 if (size < 0)
443 return size;
444
445 packet->type = ppt_pip;
446 packet->size = (uint8_t) size;
447
448 return size;
449 }
450
pt_pkt_decode_ovf(struct pt_packet_decoder * decoder,struct pt_packet * packet)451 int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder,
452 struct pt_packet *packet)
453 {
454 (void) decoder;
455
456 if (!packet)
457 return -pte_internal;
458
459 packet->type = ppt_ovf;
460 packet->size = ptps_ovf;
461
462 return ptps_ovf;
463 }
464
pt_pkt_decode_mode(struct pt_packet_decoder * decoder,struct pt_packet * packet)465 int pt_pkt_decode_mode(struct pt_packet_decoder *decoder,
466 struct pt_packet *packet)
467 {
468 int size;
469
470 if (!decoder || !packet)
471 return -pte_internal;
472
473 size = pt_pkt_read_mode(&packet->payload.mode, decoder->pos,
474 &decoder->config);
475 if (size < 0)
476 return size;
477
478 packet->type = ppt_mode;
479 packet->size = (uint8_t) size;
480
481 return size;
482 }
483
pt_pkt_decode_psbend(struct pt_packet_decoder * decoder,struct pt_packet * packet)484 int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder,
485 struct pt_packet *packet)
486 {
487 (void) decoder;
488
489 if (!packet)
490 return -pte_internal;
491
492 packet->type = ppt_psbend;
493 packet->size = ptps_psbend;
494
495 return ptps_psbend;
496 }
497
pt_pkt_decode_tsc(struct pt_packet_decoder * decoder,struct pt_packet * packet)498 int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder,
499 struct pt_packet *packet)
500 {
501 int size;
502
503 if (!decoder || !packet)
504 return -pte_internal;
505
506 size = pt_pkt_read_tsc(&packet->payload.tsc, decoder->pos,
507 &decoder->config);
508 if (size < 0)
509 return size;
510
511 packet->type = ppt_tsc;
512 packet->size = (uint8_t) size;
513
514 return size;
515 }
516
pt_pkt_decode_cbr(struct pt_packet_decoder * decoder,struct pt_packet * packet)517 int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder,
518 struct pt_packet *packet)
519 {
520 int size;
521
522 if (!decoder || !packet)
523 return -pte_internal;
524
525 size = pt_pkt_read_cbr(&packet->payload.cbr, decoder->pos,
526 &decoder->config);
527 if (size < 0)
528 return size;
529
530 packet->type = ppt_cbr;
531 packet->size = (uint8_t) size;
532
533 return size;
534 }
535
pt_pkt_decode_tma(struct pt_packet_decoder * decoder,struct pt_packet * packet)536 int pt_pkt_decode_tma(struct pt_packet_decoder *decoder,
537 struct pt_packet *packet)
538 {
539 int size;
540
541 if (!decoder || !packet)
542 return -pte_internal;
543
544 size = pt_pkt_read_tma(&packet->payload.tma, decoder->pos,
545 &decoder->config);
546 if (size < 0)
547 return size;
548
549 packet->type = ppt_tma;
550 packet->size = (uint8_t) size;
551
552 return size;
553 }
554
pt_pkt_decode_mtc(struct pt_packet_decoder * decoder,struct pt_packet * packet)555 int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder,
556 struct pt_packet *packet)
557 {
558 int size;
559
560 if (!decoder || !packet)
561 return -pte_internal;
562
563 size = pt_pkt_read_mtc(&packet->payload.mtc, decoder->pos,
564 &decoder->config);
565 if (size < 0)
566 return size;
567
568 packet->type = ppt_mtc;
569 packet->size = (uint8_t) size;
570
571 return size;
572 }
573
pt_pkt_decode_cyc(struct pt_packet_decoder * decoder,struct pt_packet * packet)574 int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder,
575 struct pt_packet *packet)
576 {
577 int size;
578
579 if (!decoder || !packet)
580 return -pte_internal;
581
582 size = pt_pkt_read_cyc(&packet->payload.cyc, decoder->pos,
583 &decoder->config);
584 if (size < 0)
585 return size;
586
587 packet->type = ppt_cyc;
588 packet->size = (uint8_t) size;
589
590 return size;
591 }
592
pt_pkt_decode_stop(struct pt_packet_decoder * decoder,struct pt_packet * packet)593 int pt_pkt_decode_stop(struct pt_packet_decoder *decoder,
594 struct pt_packet *packet)
595 {
596 (void) decoder;
597
598 if (!packet)
599 return -pte_internal;
600
601 packet->type = ppt_stop;
602 packet->size = ptps_stop;
603
604 return ptps_stop;
605 }
606
pt_pkt_decode_vmcs(struct pt_packet_decoder * decoder,struct pt_packet * packet)607 int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder,
608 struct pt_packet *packet)
609 {
610 int size;
611
612 if (!decoder || !packet)
613 return -pte_internal;
614
615 size = pt_pkt_read_vmcs(&packet->payload.vmcs, decoder->pos,
616 &decoder->config);
617 if (size < 0)
618 return size;
619
620 packet->type = ppt_vmcs;
621 packet->size = (uint8_t) size;
622
623 return size;
624 }
625
pt_pkt_decode_mnt(struct pt_packet_decoder * decoder,struct pt_packet * packet)626 int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder,
627 struct pt_packet *packet)
628 {
629 int size;
630
631 if (!decoder || !packet)
632 return -pte_internal;
633
634 size = pt_pkt_read_mnt(&packet->payload.mnt, decoder->pos,
635 &decoder->config);
636 if (size < 0)
637 return size;
638
639 packet->type = ppt_mnt;
640 packet->size = (uint8_t) size;
641
642 return size;
643 }
644
pt_pkt_decode_exstop(struct pt_packet_decoder * decoder,struct pt_packet * packet)645 int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder,
646 struct pt_packet *packet)
647 {
648 int size;
649
650 if (!decoder || !packet)
651 return -pte_internal;
652
653 size = pt_pkt_read_exstop(&packet->payload.exstop, decoder->pos,
654 &decoder->config);
655 if (size < 0)
656 return size;
657
658 packet->type = ppt_exstop;
659 packet->size = (uint8_t) size;
660
661 return size;
662 }
663
pt_pkt_decode_mwait(struct pt_packet_decoder * decoder,struct pt_packet * packet)664 int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder,
665 struct pt_packet *packet)
666 {
667 int size;
668
669 if (!decoder || !packet)
670 return -pte_internal;
671
672 size = pt_pkt_read_mwait(&packet->payload.mwait, decoder->pos,
673 &decoder->config);
674 if (size < 0)
675 return size;
676
677 packet->type = ppt_mwait;
678 packet->size = (uint8_t) size;
679
680 return size;
681 }
682
pt_pkt_decode_pwre(struct pt_packet_decoder * decoder,struct pt_packet * packet)683 int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder,
684 struct pt_packet *packet)
685 {
686 int size;
687
688 if (!decoder || !packet)
689 return -pte_internal;
690
691 size = pt_pkt_read_pwre(&packet->payload.pwre, decoder->pos,
692 &decoder->config);
693 if (size < 0)
694 return size;
695
696 packet->type = ppt_pwre;
697 packet->size = (uint8_t) size;
698
699 return size;
700 }
701
pt_pkt_decode_pwrx(struct pt_packet_decoder * decoder,struct pt_packet * packet)702 int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder,
703 struct pt_packet *packet)
704 {
705 int size;
706
707 if (!decoder || !packet)
708 return -pte_internal;
709
710 size = pt_pkt_read_pwrx(&packet->payload.pwrx, decoder->pos,
711 &decoder->config);
712 if (size < 0)
713 return size;
714
715 packet->type = ppt_pwrx;
716 packet->size = (uint8_t) size;
717
718 return size;
719 }
720
pt_pkt_decode_ptw(struct pt_packet_decoder * decoder,struct pt_packet * packet)721 int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder,
722 struct pt_packet *packet)
723 {
724 int size;
725
726 if (!decoder || !packet)
727 return -pte_internal;
728
729 size = pt_pkt_read_ptw(&packet->payload.ptw, decoder->pos,
730 &decoder->config);
731 if (size < 0)
732 return size;
733
734 packet->type = ppt_ptw;
735 packet->size = (uint8_t) size;
736
737 return size;
738 }
739