1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <stdio.h>
17#include <string.h>
18#include <endian.h>
19#include <byteswap.h>
20#include <linux/compiler.h>
21
22#include "intel-pt-pkt-decoder.h"
23
24#define BIT(n) (1 << (n))
25
26#define BIT63 ((uint64_t)1 << 63)
27
28#define NR_FLAG BIT63
29
30#if __BYTE_ORDER == __BIG_ENDIAN
31#define le16_to_cpu bswap_16
32#define le32_to_cpu bswap_32
33#define le64_to_cpu bswap_64
34#define memcpy_le64(d, s, n) do { \
35 memcpy((d), (s), (n)); \
36 *(d) = le64_to_cpu(*(d)); \
37} while (0)
38#else
39#define le16_to_cpu
40#define le32_to_cpu
41#define le64_to_cpu
42#define memcpy_le64 memcpy
43#endif
44
45static const char * const packet_name[] = {
46 [INTEL_PT_BAD] = "Bad Packet!",
47 [INTEL_PT_PAD] = "PAD",
48 [INTEL_PT_TNT] = "TNT",
49 [INTEL_PT_TIP_PGD] = "TIP.PGD",
50 [INTEL_PT_TIP_PGE] = "TIP.PGE",
51 [INTEL_PT_TSC] = "TSC",
52 [INTEL_PT_TMA] = "TMA",
53 [INTEL_PT_MODE_EXEC] = "MODE.Exec",
54 [INTEL_PT_MODE_TSX] = "MODE.TSX",
55 [INTEL_PT_MTC] = "MTC",
56 [INTEL_PT_TIP] = "TIP",
57 [INTEL_PT_FUP] = "FUP",
58 [INTEL_PT_CYC] = "CYC",
59 [INTEL_PT_VMCS] = "VMCS",
60 [INTEL_PT_PSB] = "PSB",
61 [INTEL_PT_PSBEND] = "PSBEND",
62 [INTEL_PT_CBR] = "CBR",
63 [INTEL_PT_TRACESTOP] = "TraceSTOP",
64 [INTEL_PT_PIP] = "PIP",
65 [INTEL_PT_OVF] = "OVF",
66 [INTEL_PT_MNT] = "MNT",
67 [INTEL_PT_PTWRITE] = "PTWRITE",
68 [INTEL_PT_PTWRITE_IP] = "PTWRITE",
69 [INTEL_PT_EXSTOP] = "EXSTOP",
70 [INTEL_PT_EXSTOP_IP] = "EXSTOP",
71 [INTEL_PT_MWAIT] = "MWAIT",
72 [INTEL_PT_PWRE] = "PWRE",
73 [INTEL_PT_PWRX] = "PWRX",
74};
75
76const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
77{
78 return packet_name[type];
79}
80
81static int intel_pt_get_long_tnt(const unsigned char *buf, size_t len,
82 struct intel_pt_pkt *packet)
83{
84 uint64_t payload;
85 int count;
86
87 if (len < 8)
88 return INTEL_PT_NEED_MORE_BYTES;
89
90 payload = le64_to_cpu(*(uint64_t *)buf);
91
92 for (count = 47; count; count--) {
93 if (payload & BIT63)
94 break;
95 payload <<= 1;
96 }
97
98 packet->type = INTEL_PT_TNT;
99 packet->count = count;
100 packet->payload = payload << 1;
101 return 8;
102}
103
104static int intel_pt_get_pip(const unsigned char *buf, size_t len,
105 struct intel_pt_pkt *packet)
106{
107 uint64_t payload = 0;
108
109 if (len < 8)
110 return INTEL_PT_NEED_MORE_BYTES;
111
112 packet->type = INTEL_PT_PIP;
113 memcpy_le64(&payload, buf + 2, 6);
114 packet->payload = payload >> 1;
115 if (payload & 1)
116 packet->payload |= NR_FLAG;
117
118 return 8;
119}
120
121static int intel_pt_get_tracestop(struct intel_pt_pkt *packet)
122{
123 packet->type = INTEL_PT_TRACESTOP;
124 return 2;
125}
126
127static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
128 struct intel_pt_pkt *packet)
129{
130 if (len < 4)
131 return INTEL_PT_NEED_MORE_BYTES;
132 packet->type = INTEL_PT_CBR;
133 packet->payload = le16_to_cpu(*(uint16_t *)(buf + 2));
134 return 4;
135}
136
137static int intel_pt_get_vmcs(const unsigned char *buf, size_t len,
138 struct intel_pt_pkt *packet)
139{
140 unsigned int count = (52 - 5) >> 3;
141
142 if (count < 1 || count > 7)
143 return INTEL_PT_BAD_PACKET;
144
145 if (len < count + 2)
146 return INTEL_PT_NEED_MORE_BYTES;
147
148 packet->type = INTEL_PT_VMCS;
149 packet->count = count;
150 memcpy_le64(&packet->payload, buf + 2, count);
151
152 return count + 2;
153}
154
155static int intel_pt_get_ovf(struct intel_pt_pkt *packet)
156{
157 packet->type = INTEL_PT_OVF;
158 return 2;
159}
160
161static int intel_pt_get_psb(const unsigned char *buf, size_t len,
162 struct intel_pt_pkt *packet)
163{
164 int i;
165
166 if (len < 16)
167 return INTEL_PT_NEED_MORE_BYTES;
168
169 for (i = 2; i < 16; i += 2) {
170 if (buf[i] != 2 || buf[i + 1] != 0x82)
171 return INTEL_PT_BAD_PACKET;
172 }
173
174 packet->type = INTEL_PT_PSB;
175 return 16;
176}
177
178static int intel_pt_get_psbend(struct intel_pt_pkt *packet)
179{
180 packet->type = INTEL_PT_PSBEND;
181 return 2;
182}
183
184static int intel_pt_get_tma(const unsigned char *buf, size_t len,
185 struct intel_pt_pkt *packet)
186{
187 if (len < 7)
188 return INTEL_PT_NEED_MORE_BYTES;
189
190 packet->type = INTEL_PT_TMA;
191 packet->payload = buf[2] | (buf[3] << 8);
192 packet->count = buf[5] | ((buf[6] & BIT(0)) << 8);
193 return 7;
194}
195
196static int intel_pt_get_pad(struct intel_pt_pkt *packet)
197{
198 packet->type = INTEL_PT_PAD;
199 return 1;
200}
201
202static int intel_pt_get_mnt(const unsigned char *buf, size_t len,
203 struct intel_pt_pkt *packet)
204{
205 if (len < 11)
206 return INTEL_PT_NEED_MORE_BYTES;
207 packet->type = INTEL_PT_MNT;
208 memcpy_le64(&packet->payload, buf + 3, 8);
209 return 11
210;
211}
212
213static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
214 struct intel_pt_pkt *packet)
215{
216 if (len < 3)
217 return INTEL_PT_NEED_MORE_BYTES;
218
219 switch (buf[2]) {
220 case 0x88:
221 return intel_pt_get_mnt(buf, len, packet);
222 default:
223 return INTEL_PT_BAD_PACKET;
224 }
225}
226
227static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len,
228 struct intel_pt_pkt *packet)
229{
230 packet->count = (buf[1] >> 5) & 0x3;
231 packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP :
232 INTEL_PT_PTWRITE;
233
234 switch (packet->count) {
235 case 0:
236 if (len < 6)
237 return INTEL_PT_NEED_MORE_BYTES;
238 packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2));
239 return 6;
240 case 1:
241 if (len < 10)
242 return INTEL_PT_NEED_MORE_BYTES;
243 packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
244 return 10;
245 default:
246 return INTEL_PT_BAD_PACKET;
247 }
248}
249
250static int intel_pt_get_exstop(struct intel_pt_pkt *packet)
251{
252 packet->type = INTEL_PT_EXSTOP;
253 return 2;
254}
255
256static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet)
257{
258 packet->type = INTEL_PT_EXSTOP_IP;
259 return 2;
260}
261
262static int intel_pt_get_mwait(const unsigned char *buf, size_t len,
263 struct intel_pt_pkt *packet)
264{
265 if (len < 10)
266 return INTEL_PT_NEED_MORE_BYTES;
267 packet->type = INTEL_PT_MWAIT;
268 packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
269 return 10;
270}
271
272static int intel_pt_get_pwre(const unsigned char *buf, size_t len,
273 struct intel_pt_pkt *packet)
274{
275 if (len < 4)
276 return INTEL_PT_NEED_MORE_BYTES;
277 packet->type = INTEL_PT_PWRE;
278 memcpy_le64(&packet->payload, buf + 2, 2);
279 return 4;
280}
281
282static int intel_pt_get_pwrx(const unsigned char *buf, size_t len,
283 struct intel_pt_pkt *packet)
284{
285 if (len < 7)
286 return INTEL_PT_NEED_MORE_BYTES;
287 packet->type = INTEL_PT_PWRX;
288 memcpy_le64(&packet->payload, buf + 2, 5);
289 return 7;
290}
291
292static int intel_pt_get_ext(const unsigned char *buf, size_t len,
293 struct intel_pt_pkt *packet)
294{
295 if (len < 2)
296 return INTEL_PT_NEED_MORE_BYTES;
297
298 if ((buf[1] & 0x1f) == 0x12)
299 return intel_pt_get_ptwrite(buf, len, packet);
300
301 switch (buf[1]) {
302 case 0xa3:
303 return intel_pt_get_long_tnt(buf, len, packet);
304 case 0x43:
305 return intel_pt_get_pip(buf, len, packet);
306 case 0x83:
307 return intel_pt_get_tracestop(packet);
308 case 0x03:
309 return intel_pt_get_cbr(buf, len, packet);
310 case 0xc8:
311 return intel_pt_get_vmcs(buf, len, packet);
312 case 0xf3:
313 return intel_pt_get_ovf(packet);
314 case 0x82:
315 return intel_pt_get_psb(buf, len, packet);
316 case 0x23:
317 return intel_pt_get_psbend(packet);
318 case 0x73:
319 return intel_pt_get_tma(buf, len, packet);
320 case 0xC3:
321 return intel_pt_get_3byte(buf, len, packet);
322 case 0x62:
323 return intel_pt_get_exstop(packet);
324 case 0xE2:
325 return intel_pt_get_exstop_ip(packet);
326 case 0xC2:
327 return intel_pt_get_mwait(buf, len, packet);
328 case 0x22:
329 return intel_pt_get_pwre(buf, len, packet);
330 case 0xA2:
331 return intel_pt_get_pwrx(buf, len, packet);
332 default:
333 return INTEL_PT_BAD_PACKET;
334 }
335}
336
337static int intel_pt_get_short_tnt(unsigned int byte,
338 struct intel_pt_pkt *packet)
339{
340 int count;
341
342 for (count = 6; count; count--) {
343 if (byte & BIT(7))
344 break;
345 byte <<= 1;
346 }
347
348 packet->type = INTEL_PT_TNT;
349 packet->count = count;
350 packet->payload = (uint64_t)byte << 57;
351
352 return 1;
353}
354
355static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf,
356 size_t len, struct intel_pt_pkt *packet)
357{
358 unsigned int offs = 1, shift;
359 uint64_t payload = byte >> 3;
360
361 byte >>= 2;
362 len -= 1;
363 for (shift = 5; byte & 1; shift += 7) {
364 if (offs > 9)
365 return INTEL_PT_BAD_PACKET;
366 if (len < offs)
367 return INTEL_PT_NEED_MORE_BYTES;
368 byte = buf[offs++];
369 payload |= (byte >> 1) << shift;
370 }
371
372 packet->type = INTEL_PT_CYC;
373 packet->payload = payload;
374 return offs;
375}
376
377static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
378 const unsigned char *buf, size_t len,
379 struct intel_pt_pkt *packet)
380{
381 int ip_len;
382
383 packet->count = byte >> 5;
384
385 switch (packet->count) {
386 case 0:
387 ip_len = 0;
388 break;
389 case 1:
390 if (len < 3)
391 return INTEL_PT_NEED_MORE_BYTES;
392 ip_len = 2;
393 packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1));
394 break;
395 case 2:
396 if (len < 5)
397 return INTEL_PT_NEED_MORE_BYTES;
398 ip_len = 4;
399 packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1));
400 break;
401 case 3:
402 case 4:
403 if (len < 7)
404 return INTEL_PT_NEED_MORE_BYTES;
405 ip_len = 6;
406 memcpy_le64(&packet->payload, buf + 1, 6);
407 break;
408 case 6:
409 if (len < 9)
410 return INTEL_PT_NEED_MORE_BYTES;
411 ip_len = 8;
412 packet->payload = le64_to_cpu(*(uint64_t *)(buf + 1));
413 break;
414 default:
415 return INTEL_PT_BAD_PACKET;
416 }
417
418 packet->type = type;
419
420 return ip_len + 1;
421}
422
423static int intel_pt_get_mode(const unsigned char *buf, size_t len,
424 struct intel_pt_pkt *packet)
425{
426 if (len < 2)
427 return INTEL_PT_NEED_MORE_BYTES;
428
429 switch (buf[1] >> 5) {
430 case 0:
431 packet->type = INTEL_PT_MODE_EXEC;
432 switch (buf[1] & 3) {
433 case 0:
434 packet->payload = 16;
435 break;
436 case 1:
437 packet->payload = 64;
438 break;
439 case 2:
440 packet->payload = 32;
441 break;
442 default:
443 return INTEL_PT_BAD_PACKET;
444 }
445 break;
446 case 1:
447 packet->type = INTEL_PT_MODE_TSX;
448 if ((buf[1] & 3) == 3)
449 return INTEL_PT_BAD_PACKET;
450 packet->payload = buf[1] & 3;
451 break;
452 default:
453 return INTEL_PT_BAD_PACKET;
454 }
455
456 return 2;
457}
458
459static int intel_pt_get_tsc(const unsigned char *buf, size_t len,
460 struct intel_pt_pkt *packet)
461{
462 if (len < 8)
463 return INTEL_PT_NEED_MORE_BYTES;
464 packet->type = INTEL_PT_TSC;
465 memcpy_le64(&packet->payload, buf + 1, 7);
466 return 8;
467}
468
469static int intel_pt_get_mtc(const unsigned char *buf, size_t len,
470 struct intel_pt_pkt *packet)
471{
472 if (len < 2)
473 return INTEL_PT_NEED_MORE_BYTES;
474 packet->type = INTEL_PT_MTC;
475 packet->payload = buf[1];
476 return 2;
477}
478
479static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
480 struct intel_pt_pkt *packet)
481{
482 unsigned int byte;
483
484 memset(packet, 0, sizeof(struct intel_pt_pkt));
485
486 if (!len)
487 return INTEL_PT_NEED_MORE_BYTES;
488
489 byte = buf[0];
490 if (!(byte & BIT(0))) {
491 if (byte == 0)
492 return intel_pt_get_pad(packet);
493 if (byte == 2)
494 return intel_pt_get_ext(buf, len, packet);
495 return intel_pt_get_short_tnt(byte, packet);
496 }
497
498 if ((byte & 2))
499 return intel_pt_get_cyc(byte, buf, len, packet);
500
501 switch (byte & 0x1f) {
502 case 0x0D:
503 return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet);
504 case 0x11:
505 return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len,
506 packet);
507 case 0x01:
508 return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len,
509 packet);
510 case 0x1D:
511 return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet);
512 case 0x19:
513 switch (byte) {
514 case 0x99:
515 return intel_pt_get_mode(buf, len, packet);
516 case 0x19:
517 return intel_pt_get_tsc(buf, len, packet);
518 case 0x59:
519 return intel_pt_get_mtc(buf, len, packet);
520 default:
521 return INTEL_PT_BAD_PACKET;
522 }
523 default:
524 return INTEL_PT_BAD_PACKET;
525 }
526}
527
528int intel_pt_get_packet(const unsigned char *buf, size_t len,
529 struct intel_pt_pkt *packet)
530{
531 int ret;
532
533 ret = intel_pt_do_get_packet(buf, len, packet);
534 if (ret > 0) {
535 while (ret < 8 && len > (size_t)ret && !buf[ret])
536 ret += 1;
537 }
538 return ret;
539}
540
541int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
542 size_t buf_len)
543{
544 int ret, i, nr;
545 unsigned long long payload = packet->payload;
546 const char *name = intel_pt_pkt_name(packet->type);
547
548 switch (packet->type) {
549 case INTEL_PT_BAD:
550 case INTEL_PT_PAD:
551 case INTEL_PT_PSB:
552 case INTEL_PT_PSBEND:
553 case INTEL_PT_TRACESTOP:
554 case INTEL_PT_OVF:
555 return snprintf(buf, buf_len, "%s", name);
556 case INTEL_PT_TNT: {
557 size_t blen = buf_len;
558
559 ret = snprintf(buf, blen, "%s ", name);
560 if (ret < 0)
561 return ret;
562 buf += ret;
563 blen -= ret;
564 for (i = 0; i < packet->count; i++) {
565 if (payload & BIT63)
566 ret = snprintf(buf, blen, "T");
567 else
568 ret = snprintf(buf, blen, "N");
569 if (ret < 0)
570 return ret;
571 buf += ret;
572 blen -= ret;
573 payload <<= 1;
574 }
575 ret = snprintf(buf, blen, " (%d)", packet->count);
576 if (ret < 0)
577 return ret;
578 blen -= ret;
579 return buf_len - blen;
580 }
581 case INTEL_PT_TIP_PGD:
582 case INTEL_PT_TIP_PGE:
583 case INTEL_PT_TIP:
584 case INTEL_PT_FUP:
585 if (!(packet->count))
586 return snprintf(buf, buf_len, "%s no ip", name);
587 __fallthrough;
588 case INTEL_PT_CYC:
589 case INTEL_PT_VMCS:
590 case INTEL_PT_MTC:
591 case INTEL_PT_MNT:
592 case INTEL_PT_CBR:
593 case INTEL_PT_TSC:
594 return snprintf(buf, buf_len, "%s 0x%llx", name, payload);
595 case INTEL_PT_TMA:
596 return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name,
597 (unsigned)payload, packet->count);
598 case INTEL_PT_MODE_EXEC:
599 return snprintf(buf, buf_len, "%s %lld", name, payload);
600 case INTEL_PT_MODE_TSX:
601 return snprintf(buf, buf_len, "%s TXAbort:%u InTX:%u",
602 name, (unsigned)(payload >> 1) & 1,
603 (unsigned)payload & 1);
604 case INTEL_PT_PIP:
605 nr = packet->payload & NR_FLAG ? 1 : 0;
606 payload &= ~NR_FLAG;
607 ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
608 name, payload, nr);
609 return ret;
610 case INTEL_PT_PTWRITE:
611 return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
612 case INTEL_PT_PTWRITE_IP:
613 return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
614 case INTEL_PT_EXSTOP:
615 return snprintf(buf, buf_len, "%s IP:0", name);
616 case INTEL_PT_EXSTOP_IP:
617 return snprintf(buf, buf_len, "%s IP:1", name);
618 case INTEL_PT_MWAIT:
619 return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x",
620 name, payload, (unsigned int)(payload & 0xff),
621 (unsigned int)((payload >> 32) & 0x3));
622 case INTEL_PT_PWRE:
623 return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u",
624 name, payload, !!(payload & 0x80),
625 (unsigned int)((payload >> 12) & 0xf),
626 (unsigned int)((payload >> 8) & 0xf));
627 case INTEL_PT_PWRX:
628 return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x",
629 name, payload,
630 (unsigned int)((payload >> 4) & 0xf),
631 (unsigned int)(payload & 0xf),
632 (unsigned int)((payload >> 8) & 0xf));
633 default:
634 break;
635 }
636 return snprintf(buf, buf_len, "%s 0x%llx (%d)",
637 name, payload, packet->count);
638}
639