2 * intel_pt_pkt_decoder.c: Intel Processor Trace support
3 * Copyright (c) 2013-2014, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 #include "intel-pt-pkt-decoder.h"
23 #define BIT(n) (1 << (n))
25 #define BIT63 ((uint64_t)1 << 63)
29 #if __BYTE_ORDER == __BIG_ENDIAN
30 #define le16_to_cpu bswap_16
31 #define le32_to_cpu bswap_32
32 #define le64_to_cpu bswap_64
33 #define memcpy_le64(d, s, n) do { \
34 memcpy((d), (s), (n)); \
35 *(d) = le64_to_cpu(*(d)); \
41 #define memcpy_le64 memcpy
44 static const char * const packet_name
[] = {
45 [INTEL_PT_BAD
] = "Bad Packet!",
46 [INTEL_PT_PAD
] = "PAD",
47 [INTEL_PT_TNT
] = "TNT",
48 [INTEL_PT_TIP_PGD
] = "TIP.PGD",
49 [INTEL_PT_TIP_PGE
] = "TIP.PGE",
50 [INTEL_PT_TSC
] = "TSC",
51 [INTEL_PT_TMA
] = "TMA",
52 [INTEL_PT_MODE_EXEC
] = "MODE.Exec",
53 [INTEL_PT_MODE_TSX
] = "MODE.TSX",
54 [INTEL_PT_MTC
] = "MTC",
55 [INTEL_PT_TIP
] = "TIP",
56 [INTEL_PT_FUP
] = "FUP",
57 [INTEL_PT_CYC
] = "CYC",
58 [INTEL_PT_VMCS
] = "VMCS",
59 [INTEL_PT_PSB
] = "PSB",
60 [INTEL_PT_PSBEND
] = "PSBEND",
61 [INTEL_PT_CBR
] = "CBR",
62 [INTEL_PT_TRACESTOP
] = "TraceSTOP",
63 [INTEL_PT_PIP
] = "PIP",
64 [INTEL_PT_OVF
] = "OVF",
65 [INTEL_PT_MNT
] = "MNT",
68 const char *intel_pt_pkt_name(enum intel_pt_pkt_type type
)
70 return packet_name
[type
];
73 static int intel_pt_get_long_tnt(const unsigned char *buf
, size_t len
,
74 struct intel_pt_pkt
*packet
)
80 return INTEL_PT_NEED_MORE_BYTES
;
82 payload
= le64_to_cpu(*(uint64_t *)buf
);
84 for (count
= 47; count
; count
--) {
90 packet
->type
= INTEL_PT_TNT
;
91 packet
->count
= count
;
92 packet
->payload
= payload
<< 1;
96 static int intel_pt_get_pip(const unsigned char *buf
, size_t len
,
97 struct intel_pt_pkt
*packet
)
102 return INTEL_PT_NEED_MORE_BYTES
;
104 packet
->type
= INTEL_PT_PIP
;
105 memcpy_le64(&payload
, buf
+ 2, 6);
106 packet
->payload
= payload
>> 1;
108 packet
->payload
|= NR_FLAG
;
113 static int intel_pt_get_tracestop(struct intel_pt_pkt
*packet
)
115 packet
->type
= INTEL_PT_TRACESTOP
;
119 static int intel_pt_get_cbr(const unsigned char *buf
, size_t len
,
120 struct intel_pt_pkt
*packet
)
123 return INTEL_PT_NEED_MORE_BYTES
;
124 packet
->type
= INTEL_PT_CBR
;
125 packet
->payload
= buf
[2];
129 static int intel_pt_get_vmcs(const unsigned char *buf
, size_t len
,
130 struct intel_pt_pkt
*packet
)
132 unsigned int count
= (52 - 5) >> 3;
134 if (count
< 1 || count
> 7)
135 return INTEL_PT_BAD_PACKET
;
138 return INTEL_PT_NEED_MORE_BYTES
;
140 packet
->type
= INTEL_PT_VMCS
;
141 packet
->count
= count
;
142 memcpy_le64(&packet
->payload
, buf
+ 2, count
);
147 static int intel_pt_get_ovf(struct intel_pt_pkt
*packet
)
149 packet
->type
= INTEL_PT_OVF
;
153 static int intel_pt_get_psb(const unsigned char *buf
, size_t len
,
154 struct intel_pt_pkt
*packet
)
159 return INTEL_PT_NEED_MORE_BYTES
;
161 for (i
= 2; i
< 16; i
+= 2) {
162 if (buf
[i
] != 2 || buf
[i
+ 1] != 0x82)
163 return INTEL_PT_BAD_PACKET
;
166 packet
->type
= INTEL_PT_PSB
;
170 static int intel_pt_get_psbend(struct intel_pt_pkt
*packet
)
172 packet
->type
= INTEL_PT_PSBEND
;
176 static int intel_pt_get_tma(const unsigned char *buf
, size_t len
,
177 struct intel_pt_pkt
*packet
)
180 return INTEL_PT_NEED_MORE_BYTES
;
182 packet
->type
= INTEL_PT_TMA
;
183 packet
->payload
= buf
[2] | (buf
[3] << 8);
184 packet
->count
= buf
[5] | ((buf
[6] & BIT(0)) << 8);
188 static int intel_pt_get_pad(struct intel_pt_pkt
*packet
)
190 packet
->type
= INTEL_PT_PAD
;
194 static int intel_pt_get_mnt(const unsigned char *buf
, size_t len
,
195 struct intel_pt_pkt
*packet
)
198 return INTEL_PT_NEED_MORE_BYTES
;
199 packet
->type
= INTEL_PT_MNT
;
200 memcpy_le64(&packet
->payload
, buf
+ 3, 8);
205 static int intel_pt_get_3byte(const unsigned char *buf
, size_t len
,
206 struct intel_pt_pkt
*packet
)
209 return INTEL_PT_NEED_MORE_BYTES
;
213 return intel_pt_get_mnt(buf
, len
, packet
);
215 return INTEL_PT_BAD_PACKET
;
219 static int intel_pt_get_ext(const unsigned char *buf
, size_t len
,
220 struct intel_pt_pkt
*packet
)
223 return INTEL_PT_NEED_MORE_BYTES
;
226 case 0xa3: /* Long TNT */
227 return intel_pt_get_long_tnt(buf
, len
, packet
);
229 return intel_pt_get_pip(buf
, len
, packet
);
230 case 0x83: /* TraceStop */
231 return intel_pt_get_tracestop(packet
);
233 return intel_pt_get_cbr(buf
, len
, packet
);
234 case 0xc8: /* VMCS */
235 return intel_pt_get_vmcs(buf
, len
, packet
);
237 return intel_pt_get_ovf(packet
);
239 return intel_pt_get_psb(buf
, len
, packet
);
240 case 0x23: /* PSBEND */
241 return intel_pt_get_psbend(packet
);
243 return intel_pt_get_tma(buf
, len
, packet
);
244 case 0xC3: /* 3-byte header */
245 return intel_pt_get_3byte(buf
, len
, packet
);
247 return INTEL_PT_BAD_PACKET
;
251 static int intel_pt_get_short_tnt(unsigned int byte
,
252 struct intel_pt_pkt
*packet
)
256 for (count
= 6; count
; count
--) {
262 packet
->type
= INTEL_PT_TNT
;
263 packet
->count
= count
;
264 packet
->payload
= (uint64_t)byte
<< 57;
269 static int intel_pt_get_cyc(unsigned int byte
, const unsigned char *buf
,
270 size_t len
, struct intel_pt_pkt
*packet
)
272 unsigned int offs
= 1, shift
;
273 uint64_t payload
= byte
>> 3;
277 for (shift
= 5; byte
& 1; shift
+= 7) {
279 return INTEL_PT_BAD_PACKET
;
281 return INTEL_PT_NEED_MORE_BYTES
;
283 payload
|= (byte
>> 1) << shift
;
286 packet
->type
= INTEL_PT_CYC
;
287 packet
->payload
= payload
;
291 static int intel_pt_get_ip(enum intel_pt_pkt_type type
, unsigned int byte
,
292 const unsigned char *buf
, size_t len
,
293 struct intel_pt_pkt
*packet
)
301 return INTEL_PT_NEED_MORE_BYTES
;
303 packet
->payload
= le16_to_cpu(*(uint16_t *)(buf
+ 1));
307 return INTEL_PT_NEED_MORE_BYTES
;
309 packet
->payload
= le32_to_cpu(*(uint32_t *)(buf
+ 1));
314 return INTEL_PT_NEED_MORE_BYTES
;
316 memcpy_le64(&packet
->payload
, buf
+ 1, 6);
319 return INTEL_PT_BAD_PACKET
;
324 return packet
->count
+ 1;
327 static int intel_pt_get_mode(const unsigned char *buf
, size_t len
,
328 struct intel_pt_pkt
*packet
)
331 return INTEL_PT_NEED_MORE_BYTES
;
333 switch (buf
[1] >> 5) {
335 packet
->type
= INTEL_PT_MODE_EXEC
;
336 switch (buf
[1] & 3) {
338 packet
->payload
= 16;
341 packet
->payload
= 64;
344 packet
->payload
= 32;
347 return INTEL_PT_BAD_PACKET
;
351 packet
->type
= INTEL_PT_MODE_TSX
;
352 if ((buf
[1] & 3) == 3)
353 return INTEL_PT_BAD_PACKET
;
354 packet
->payload
= buf
[1] & 3;
357 return INTEL_PT_BAD_PACKET
;
363 static int intel_pt_get_tsc(const unsigned char *buf
, size_t len
,
364 struct intel_pt_pkt
*packet
)
367 return INTEL_PT_NEED_MORE_BYTES
;
368 packet
->type
= INTEL_PT_TSC
;
369 memcpy_le64(&packet
->payload
, buf
+ 1, 7);
373 static int intel_pt_get_mtc(const unsigned char *buf
, size_t len
,
374 struct intel_pt_pkt
*packet
)
377 return INTEL_PT_NEED_MORE_BYTES
;
378 packet
->type
= INTEL_PT_MTC
;
379 packet
->payload
= buf
[1];
383 static int intel_pt_do_get_packet(const unsigned char *buf
, size_t len
,
384 struct intel_pt_pkt
*packet
)
388 memset(packet
, 0, sizeof(struct intel_pt_pkt
));
391 return INTEL_PT_NEED_MORE_BYTES
;
394 if (!(byte
& BIT(0))) {
396 return intel_pt_get_pad(packet
);
398 return intel_pt_get_ext(buf
, len
, packet
);
399 return intel_pt_get_short_tnt(byte
, packet
);
403 return intel_pt_get_cyc(byte
, buf
, len
, packet
);
405 switch (byte
& 0x1f) {
407 return intel_pt_get_ip(INTEL_PT_TIP
, byte
, buf
, len
, packet
);
409 return intel_pt_get_ip(INTEL_PT_TIP_PGE
, byte
, buf
, len
,
412 return intel_pt_get_ip(INTEL_PT_TIP_PGD
, byte
, buf
, len
,
415 return intel_pt_get_ip(INTEL_PT_FUP
, byte
, buf
, len
, packet
);
419 return intel_pt_get_mode(buf
, len
, packet
);
421 return intel_pt_get_tsc(buf
, len
, packet
);
423 return intel_pt_get_mtc(buf
, len
, packet
);
425 return INTEL_PT_BAD_PACKET
;
428 return INTEL_PT_BAD_PACKET
;
432 int intel_pt_get_packet(const unsigned char *buf
, size_t len
,
433 struct intel_pt_pkt
*packet
)
437 ret
= intel_pt_do_get_packet(buf
, len
, packet
);
439 while (ret
< 8 && len
> (size_t)ret
&& !buf
[ret
])
445 int intel_pt_pkt_desc(const struct intel_pt_pkt
*packet
, char *buf
,
449 unsigned long long payload
= packet
->payload
;
450 const char *name
= intel_pt_pkt_name(packet
->type
);
452 switch (packet
->type
) {
456 case INTEL_PT_PSBEND
:
457 case INTEL_PT_TRACESTOP
:
459 return snprintf(buf
, buf_len
, "%s", name
);
461 size_t blen
= buf_len
;
463 ret
= snprintf(buf
, blen
, "%s ", name
);
468 for (i
= 0; i
< packet
->count
; i
++) {
470 ret
= snprintf(buf
, blen
, "T");
472 ret
= snprintf(buf
, blen
, "N");
479 ret
= snprintf(buf
, blen
, " (%d)", packet
->count
);
483 return buf_len
- blen
;
485 case INTEL_PT_TIP_PGD
:
486 case INTEL_PT_TIP_PGE
:
489 if (!(packet
->count
))
490 return snprintf(buf
, buf_len
, "%s no ip", name
);
497 return snprintf(buf
, buf_len
, "%s 0x%llx", name
, payload
);
499 return snprintf(buf
, buf_len
, "%s CTC 0x%x FC 0x%x", name
,
500 (unsigned)payload
, packet
->count
);
501 case INTEL_PT_MODE_EXEC
:
502 return snprintf(buf
, buf_len
, "%s %lld", name
, payload
);
503 case INTEL_PT_MODE_TSX
:
504 return snprintf(buf
, buf_len
, "%s TXAbort:%u InTX:%u",
505 name
, (unsigned)(payload
>> 1) & 1,
506 (unsigned)payload
& 1);
508 nr
= packet
->payload
& NR_FLAG
? 1 : 0;
510 ret
= snprintf(buf
, buf_len
, "%s 0x%llx (NR=%d)",
516 return snprintf(buf
, buf_len
, "%s 0x%llx (%d)",
517 name
, payload
, packet
->count
);