2 * Copyright (c) 2014-2019, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
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.
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.
29 #include "pt_packet_decoder.h"
30 #include "pt_decoder_function.h"
31 #include "pt_packet.h"
33 #include "pt_config.h"
34 #include "pt_opcodes.h"
41 int pt_pkt_decoder_init(struct pt_packet_decoder *decoder,
42 const struct pt_config *config)
46 if (!decoder || !config)
49 memset(decoder, 0, sizeof(*decoder));
51 errcode = pt_config_from_user(&decoder->config, config);
58 struct pt_packet_decoder *pt_pkt_alloc_decoder(const struct pt_config *config)
60 struct pt_packet_decoder *decoder;
63 decoder = malloc(sizeof(*decoder));
67 errcode = pt_pkt_decoder_init(decoder, config);
76 void pt_pkt_decoder_fini(struct pt_packet_decoder *decoder)
83 void pt_pkt_free_decoder(struct pt_packet_decoder *decoder)
85 pt_pkt_decoder_fini(decoder);
89 int pt_pkt_sync_forward(struct pt_packet_decoder *decoder)
91 const uint8_t *pos, *sync, *begin;
98 begin = decoder->config.begin;
108 return -pte_internal;
110 /* Start a bit earlier so we find PSB that have been partially consumed
111 * by a preceding packet.
114 if (ptps_psb <= space)
115 space = ptps_psb - 1;
119 errcode = pt_sync_forward(&sync, pos, &decoder->config);
123 decoder->sync = sync;
129 int pt_pkt_sync_backward(struct pt_packet_decoder *decoder)
131 const uint8_t *pos, *sync;
139 pos = decoder->config.end;
141 errcode = pt_sync_backward(&sync, pos, &decoder->config);
145 decoder->sync = sync;
151 int pt_pkt_sync_set(struct pt_packet_decoder *decoder, uint64_t offset)
153 const uint8_t *begin, *end, *pos;
158 begin = decoder->config.begin;
159 end = decoder->config.end;
160 pos = begin + offset;
162 if (end < pos || pos < begin)
171 int pt_pkt_get_offset(const struct pt_packet_decoder *decoder, uint64_t *offset)
173 const uint8_t *begin, *pos;
175 if (!decoder || !offset)
178 begin = decoder->config.begin;
184 *offset = (uint64_t) (int64_t) (pos - begin);
188 int pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder,
191 const uint8_t *begin, *sync;
193 if (!decoder || !offset)
196 begin = decoder->config.begin;
197 sync = decoder->sync;
202 *offset = (uint64_t) (int64_t) (sync - begin);
206 const struct pt_config *
207 pt_pkt_get_config(const struct pt_packet_decoder *decoder)
212 return &decoder->config;
215 static inline int pkt_to_user(struct pt_packet *upkt, size_t size,
216 const struct pt_packet *pkt)
219 return -pte_internal;
224 /* Zero out any unknown bytes. */
225 if (sizeof(*pkt) < size) {
226 memset(upkt + sizeof(*pkt), 0, size - sizeof(*pkt));
231 memcpy(upkt, pkt, size);
236 int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet,
239 const struct pt_decoder_function *dfun;
240 struct pt_packet pkt, *ppkt;
243 if (!packet || !decoder)
246 ppkt = psize == sizeof(pkt) ? packet : &pkt;
248 errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config);
253 return -pte_internal;
256 return -pte_internal;
258 size = dfun->packet(decoder, ppkt);
262 errcode = pkt_to_user(packet, psize, ppkt);
266 decoder->pos += size;
271 int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder,
272 struct pt_packet *packet)
277 return -pte_internal;
279 size = pt_pkt_read_unknown(packet, decoder->pos, &decoder->config);
286 int pt_pkt_decode_pad(struct pt_packet_decoder *decoder,
287 struct pt_packet *packet)
292 return -pte_internal;
294 packet->type = ppt_pad;
295 packet->size = ptps_pad;
300 int pt_pkt_decode_psb(struct pt_packet_decoder *decoder,
301 struct pt_packet *packet)
306 return -pte_internal;
308 size = pt_pkt_read_psb(decoder->pos, &decoder->config);
312 packet->type = ppt_psb;
313 packet->size = (uint8_t) size;
318 int pt_pkt_decode_tip(struct pt_packet_decoder *decoder,
319 struct pt_packet *packet)
323 if (!decoder || !packet)
324 return -pte_internal;
326 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
331 packet->type = ppt_tip;
332 packet->size = (uint8_t) size;
337 int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder,
338 struct pt_packet *packet)
342 if (!decoder || !packet)
343 return -pte_internal;
345 size = pt_pkt_read_tnt_8(&packet->payload.tnt, decoder->pos,
350 packet->type = ppt_tnt_8;
351 packet->size = (uint8_t) size;
356 int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder,
357 struct pt_packet *packet)
361 if (!decoder || !packet)
362 return -pte_internal;
364 size = pt_pkt_read_tnt_64(&packet->payload.tnt, decoder->pos,
369 packet->type = ppt_tnt_64;
370 packet->size = (uint8_t) size;
375 int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder,
376 struct pt_packet *packet)
380 if (!decoder || !packet)
381 return -pte_internal;
383 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
388 packet->type = ppt_tip_pge;
389 packet->size = (uint8_t) size;
394 int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder,
395 struct pt_packet *packet)
399 if (!decoder || !packet)
400 return -pte_internal;
402 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
407 packet->type = ppt_tip_pgd;
408 packet->size = (uint8_t) size;
413 int pt_pkt_decode_fup(struct pt_packet_decoder *decoder,
414 struct pt_packet *packet)
418 if (!decoder || !packet)
419 return -pte_internal;
421 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
426 packet->type = ppt_fup;
427 packet->size = (uint8_t) size;
432 int pt_pkt_decode_pip(struct pt_packet_decoder *decoder,
433 struct pt_packet *packet)
437 if (!decoder || !packet)
438 return -pte_internal;
440 size = pt_pkt_read_pip(&packet->payload.pip, decoder->pos,
445 packet->type = ppt_pip;
446 packet->size = (uint8_t) size;
451 int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder,
452 struct pt_packet *packet)
457 return -pte_internal;
459 packet->type = ppt_ovf;
460 packet->size = ptps_ovf;
465 int pt_pkt_decode_mode(struct pt_packet_decoder *decoder,
466 struct pt_packet *packet)
470 if (!decoder || !packet)
471 return -pte_internal;
473 size = pt_pkt_read_mode(&packet->payload.mode, decoder->pos,
478 packet->type = ppt_mode;
479 packet->size = (uint8_t) size;
484 int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder,
485 struct pt_packet *packet)
490 return -pte_internal;
492 packet->type = ppt_psbend;
493 packet->size = ptps_psbend;
498 int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder,
499 struct pt_packet *packet)
503 if (!decoder || !packet)
504 return -pte_internal;
506 size = pt_pkt_read_tsc(&packet->payload.tsc, decoder->pos,
511 packet->type = ppt_tsc;
512 packet->size = (uint8_t) size;
517 int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder,
518 struct pt_packet *packet)
522 if (!decoder || !packet)
523 return -pte_internal;
525 size = pt_pkt_read_cbr(&packet->payload.cbr, decoder->pos,
530 packet->type = ppt_cbr;
531 packet->size = (uint8_t) size;
536 int pt_pkt_decode_tma(struct pt_packet_decoder *decoder,
537 struct pt_packet *packet)
541 if (!decoder || !packet)
542 return -pte_internal;
544 size = pt_pkt_read_tma(&packet->payload.tma, decoder->pos,
549 packet->type = ppt_tma;
550 packet->size = (uint8_t) size;
555 int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder,
556 struct pt_packet *packet)
560 if (!decoder || !packet)
561 return -pte_internal;
563 size = pt_pkt_read_mtc(&packet->payload.mtc, decoder->pos,
568 packet->type = ppt_mtc;
569 packet->size = (uint8_t) size;
574 int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder,
575 struct pt_packet *packet)
579 if (!decoder || !packet)
580 return -pte_internal;
582 size = pt_pkt_read_cyc(&packet->payload.cyc, decoder->pos,
587 packet->type = ppt_cyc;
588 packet->size = (uint8_t) size;
593 int pt_pkt_decode_stop(struct pt_packet_decoder *decoder,
594 struct pt_packet *packet)
599 return -pte_internal;
601 packet->type = ppt_stop;
602 packet->size = ptps_stop;
607 int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder,
608 struct pt_packet *packet)
612 if (!decoder || !packet)
613 return -pte_internal;
615 size = pt_pkt_read_vmcs(&packet->payload.vmcs, decoder->pos,
620 packet->type = ppt_vmcs;
621 packet->size = (uint8_t) size;
626 int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder,
627 struct pt_packet *packet)
631 if (!decoder || !packet)
632 return -pte_internal;
634 size = pt_pkt_read_mnt(&packet->payload.mnt, decoder->pos,
639 packet->type = ppt_mnt;
640 packet->size = (uint8_t) size;
645 int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder,
646 struct pt_packet *packet)
650 if (!decoder || !packet)
651 return -pte_internal;
653 size = pt_pkt_read_exstop(&packet->payload.exstop, decoder->pos,
658 packet->type = ppt_exstop;
659 packet->size = (uint8_t) size;
664 int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder,
665 struct pt_packet *packet)
669 if (!decoder || !packet)
670 return -pte_internal;
672 size = pt_pkt_read_mwait(&packet->payload.mwait, decoder->pos,
677 packet->type = ppt_mwait;
678 packet->size = (uint8_t) size;
683 int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder,
684 struct pt_packet *packet)
688 if (!decoder || !packet)
689 return -pte_internal;
691 size = pt_pkt_read_pwre(&packet->payload.pwre, decoder->pos,
696 packet->type = ppt_pwre;
697 packet->size = (uint8_t) size;
702 int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder,
703 struct pt_packet *packet)
707 if (!decoder || !packet)
708 return -pte_internal;
710 size = pt_pkt_read_pwrx(&packet->payload.pwrx, decoder->pos,
715 packet->type = ppt_pwrx;
716 packet->size = (uint8_t) size;
721 int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder,
722 struct pt_packet *packet)
726 if (!decoder || !packet)
727 return -pte_internal;
729 size = pt_pkt_read_ptw(&packet->payload.ptw, decoder->pos,
734 packet->type = ppt_ptw;
735 packet->size = (uint8_t) size;