1/* 2 * intel_pt_pkt_decoder.c: Intel Processor Trace support 3 * Copyright (c) 2013-2014, Intel Corporation. 4 * 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. 8 * 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 12 * more details. 13 * 14 */ 15 16#include <stdio.h> 17#include <string.h> 18#include <endian.h> 19#include <byteswap.h> 20 21#include "intel-pt-pkt-decoder.h" 22 23#define BIT(n) (1 << (n)) 24 25#define BIT63 ((uint64_t)1 << 63) 26 27#define NR_FLAG BIT63 28 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)); \ 36} while (0) 37#else 38#define le16_to_cpu 39#define le32_to_cpu 40#define le64_to_cpu 41#define memcpy_le64 memcpy 42#endif 43 44static 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", 66}; 67 68const char *intel_pt_pkt_name(enum intel_pt_pkt_type type) 69{ 70 return packet_name[type]; 71} 72 73static int intel_pt_get_long_tnt(const unsigned char *buf, size_t len, 74 struct intel_pt_pkt *packet) 75{ 76 uint64_t payload; 77 int count; 78 79 if (len < 8) 80 return INTEL_PT_NEED_MORE_BYTES; 81 82 payload = le64_to_cpu(*(uint64_t *)buf); 83 84 for (count = 47; count; count--) { 85 if (payload & BIT63) 86 break; 87 payload <<= 1; 88 } 89 90 packet->type = INTEL_PT_TNT; 91 packet->count = count; 92 packet->payload = payload << 1; 93 return 8; 94} 95 96static int intel_pt_get_pip(const unsigned char *buf, size_t len, 97 struct intel_pt_pkt *packet) 98{ 99 uint64_t payload = 0; 100 101 if (len < 8) 102 return INTEL_PT_NEED_MORE_BYTES; 103 104 packet->type = INTEL_PT_PIP; 105 memcpy_le64(&payload, buf + 2, 6); 106 packet->payload = payload >> 1; 107 if (payload & 1) 108 packet->payload |= NR_FLAG; 109 110 return 8; 111} 112 113static int intel_pt_get_tracestop(struct intel_pt_pkt *packet) 114{ 115 packet->type = INTEL_PT_TRACESTOP; 116 return 2; 117} 118 119static int intel_pt_get_cbr(const unsigned char *buf, size_t len, 120 struct intel_pt_pkt *packet) 121{ 122 if (len < 4) 123 return INTEL_PT_NEED_MORE_BYTES; 124 packet->type = INTEL_PT_CBR; 125 packet->payload = buf[2]; 126 return 4; 127} 128 129static int intel_pt_get_vmcs(const unsigned char *buf, size_t len, 130 struct intel_pt_pkt *packet) 131{ 132 unsigned int count = (52 - 5) >> 3; 133 134 if (count < 1 || count > 7) 135 return INTEL_PT_BAD_PACKET; 136 137 if (len < count + 2) 138 return INTEL_PT_NEED_MORE_BYTES; 139 140 packet->type = INTEL_PT_VMCS; 141 packet->count = count; 142 memcpy_le64(&packet->payload, buf + 2, count); 143 144 return count + 2; 145} 146 147static int intel_pt_get_ovf(struct intel_pt_pkt *packet) 148{ 149 packet->type = INTEL_PT_OVF; 150 return 2; 151} 152 153static int intel_pt_get_psb(const unsigned char *buf, size_t len, 154 struct intel_pt_pkt *packet) 155{ 156 int i; 157 158 if (len < 16) 159 return INTEL_PT_NEED_MORE_BYTES; 160 161 for (i = 2; i < 16; i += 2) { 162 if (buf[i] != 2 || buf[i + 1] != 0x82) 163 return INTEL_PT_BAD_PACKET; 164 } 165 166 packet->type = INTEL_PT_PSB; 167 return 16; 168} 169 170static int intel_pt_get_psbend(struct intel_pt_pkt *packet) 171{ 172 packet->type = INTEL_PT_PSBEND; 173 return 2; 174} 175 176static int intel_pt_get_tma(const unsigned char *buf, size_t len, 177 struct intel_pt_pkt *packet) 178{ 179 if (len < 7) 180 return INTEL_PT_NEED_MORE_BYTES; 181 182 packet->type = INTEL_PT_TMA; 183 packet->payload = buf[2] | (buf[3] << 8); 184 packet->count = buf[5] | ((buf[6] & BIT(0)) << 8); 185 return 7; 186} 187 188static int intel_pt_get_pad(struct intel_pt_pkt *packet) 189{ 190 packet->type = INTEL_PT_PAD; 191 return 1; 192} 193 194static int intel_pt_get_mnt(const unsigned char *buf, size_t len, 195 struct intel_pt_pkt *packet) 196{ 197 if (len < 11) 198 return INTEL_PT_NEED_MORE_BYTES; 199 packet->type = INTEL_PT_MNT; 200 memcpy_le64(&packet->payload, buf + 3, 8); 201 return 11 202; 203} 204 205static int intel_pt_get_3byte(const unsigned char *buf, size_t len, 206 struct intel_pt_pkt *packet) 207{ 208 if (len < 3) 209 return INTEL_PT_NEED_MORE_BYTES; 210 211 switch (buf[2]) { 212 case 0x88: /* MNT */ 213 return intel_pt_get_mnt(buf, len, packet); 214 default: 215 return INTEL_PT_BAD_PACKET; 216 } 217} 218 219static int intel_pt_get_ext(const unsigned char *buf, size_t len, 220 struct intel_pt_pkt *packet) 221{ 222 if (len < 2) 223 return INTEL_PT_NEED_MORE_BYTES; 224 225 switch (buf[1]) { 226 case 0xa3: /* Long TNT */ 227 return intel_pt_get_long_tnt(buf, len, packet); 228 case 0x43: /* PIP */ 229 return intel_pt_get_pip(buf, len, packet); 230 case 0x83: /* TraceStop */ 231 return intel_pt_get_tracestop(packet); 232 case 0x03: /* CBR */ 233 return intel_pt_get_cbr(buf, len, packet); 234 case 0xc8: /* VMCS */ 235 return intel_pt_get_vmcs(buf, len, packet); 236 case 0xf3: /* OVF */ 237 return intel_pt_get_ovf(packet); 238 case 0x82: /* PSB */ 239 return intel_pt_get_psb(buf, len, packet); 240 case 0x23: /* PSBEND */ 241 return intel_pt_get_psbend(packet); 242 case 0x73: /* TMA */ 243 return intel_pt_get_tma(buf, len, packet); 244 case 0xC3: /* 3-byte header */ 245 return intel_pt_get_3byte(buf, len, packet); 246 default: 247 return INTEL_PT_BAD_PACKET; 248 } 249} 250 251static int intel_pt_get_short_tnt(unsigned int byte, 252 struct intel_pt_pkt *packet) 253{ 254 int count; 255 256 for (count = 6; count; count--) { 257 if (byte & BIT(7)) 258 break; 259 byte <<= 1; 260 } 261 262 packet->type = INTEL_PT_TNT; 263 packet->count = count; 264 packet->payload = (uint64_t)byte << 57; 265 266 return 1; 267} 268 269static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf, 270 size_t len, struct intel_pt_pkt *packet) 271{ 272 unsigned int offs = 1, shift; 273 uint64_t payload = byte >> 3; 274 275 byte >>= 2; 276 len -= 1; 277 for (shift = 5; byte & 1; shift += 7) { 278 if (offs > 9) 279 return INTEL_PT_BAD_PACKET; 280 if (len < offs) 281 return INTEL_PT_NEED_MORE_BYTES; 282 byte = buf[offs++]; 283 payload |= (byte >> 1) << shift; 284 } 285 286 packet->type = INTEL_PT_CYC; 287 packet->payload = payload; 288 return offs; 289} 290 291static 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) 294{ 295 switch (byte >> 5) { 296 case 0: 297 packet->count = 0; 298 break; 299 case 1: 300 if (len < 3) 301 return INTEL_PT_NEED_MORE_BYTES; 302 packet->count = 2; 303 packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1)); 304 break; 305 case 2: 306 if (len < 5) 307 return INTEL_PT_NEED_MORE_BYTES; 308 packet->count = 4; 309 packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1)); 310 break; 311 case 3: 312 case 6: 313 if (len < 7) 314 return INTEL_PT_NEED_MORE_BYTES; 315 packet->count = 6; 316 memcpy_le64(&packet->payload, buf + 1, 6); 317 break; 318 default: 319 return INTEL_PT_BAD_PACKET; 320 } 321 322 packet->type = type; 323 324 return packet->count + 1; 325} 326 327static int intel_pt_get_mode(const unsigned char *buf, size_t len, 328 struct intel_pt_pkt *packet) 329{ 330 if (len < 2) 331 return INTEL_PT_NEED_MORE_BYTES; 332 333 switch (buf[1] >> 5) { 334 case 0: 335 packet->type = INTEL_PT_MODE_EXEC; 336 switch (buf[1] & 3) { 337 case 0: 338 packet->payload = 16; 339 break; 340 case 1: 341 packet->payload = 64; 342 break; 343 case 2: 344 packet->payload = 32; 345 break; 346 default: 347 return INTEL_PT_BAD_PACKET; 348 } 349 break; 350 case 1: 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; 355 break; 356 default: 357 return INTEL_PT_BAD_PACKET; 358 } 359 360 return 2; 361} 362 363static int intel_pt_get_tsc(const unsigned char *buf, size_t len, 364 struct intel_pt_pkt *packet) 365{ 366 if (len < 8) 367 return INTEL_PT_NEED_MORE_BYTES; 368 packet->type = INTEL_PT_TSC; 369 memcpy_le64(&packet->payload, buf + 1, 7); 370 return 8; 371} 372 373static int intel_pt_get_mtc(const unsigned char *buf, size_t len, 374 struct intel_pt_pkt *packet) 375{ 376 if (len < 2) 377 return INTEL_PT_NEED_MORE_BYTES; 378 packet->type = INTEL_PT_MTC; 379 packet->payload = buf[1]; 380 return 2; 381} 382 383static int intel_pt_do_get_packet(const unsigned char *buf, size_t len, 384 struct intel_pt_pkt *packet) 385{ 386 unsigned int byte; 387 388 memset(packet, 0, sizeof(struct intel_pt_pkt)); 389 390 if (!len) 391 return INTEL_PT_NEED_MORE_BYTES; 392 393 byte = buf[0]; 394 if (!(byte & BIT(0))) { 395 if (byte == 0) 396 return intel_pt_get_pad(packet); 397 if (byte == 2) 398 return intel_pt_get_ext(buf, len, packet); 399 return intel_pt_get_short_tnt(byte, packet); 400 } 401 402 if ((byte & 2)) 403 return intel_pt_get_cyc(byte, buf, len, packet); 404 405 switch (byte & 0x1f) { 406 case 0x0D: 407 return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet); 408 case 0x11: 409 return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len, 410 packet); 411 case 0x01: 412 return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len, 413 packet); 414 case 0x1D: 415 return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet); 416 case 0x19: 417 switch (byte) { 418 case 0x99: 419 return intel_pt_get_mode(buf, len, packet); 420 case 0x19: 421 return intel_pt_get_tsc(buf, len, packet); 422 case 0x59: 423 return intel_pt_get_mtc(buf, len, packet); 424 default: 425 return INTEL_PT_BAD_PACKET; 426 } 427 default: 428 return INTEL_PT_BAD_PACKET; 429 } 430} 431 432int intel_pt_get_packet(const unsigned char *buf, size_t len, 433 struct intel_pt_pkt *packet) 434{ 435 int ret; 436 437 ret = intel_pt_do_get_packet(buf, len, packet); 438 if (ret > 0) { 439 while (ret < 8 && len > (size_t)ret && !buf[ret]) 440 ret += 1; 441 } 442 return ret; 443} 444 445int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf, 446 size_t buf_len) 447{ 448 int ret, i, nr; 449 unsigned long long payload = packet->payload; 450 const char *name = intel_pt_pkt_name(packet->type); 451 452 switch (packet->type) { 453 case INTEL_PT_BAD: 454 case INTEL_PT_PAD: 455 case INTEL_PT_PSB: 456 case INTEL_PT_PSBEND: 457 case INTEL_PT_TRACESTOP: 458 case INTEL_PT_OVF: 459 return snprintf(buf, buf_len, "%s", name); 460 case INTEL_PT_TNT: { 461 size_t blen = buf_len; 462 463 ret = snprintf(buf, blen, "%s ", name); 464 if (ret < 0) 465 return ret; 466 buf += ret; 467 blen -= ret; 468 for (i = 0; i < packet->count; i++) { 469 if (payload & BIT63) 470 ret = snprintf(buf, blen, "T"); 471 else 472 ret = snprintf(buf, blen, "N"); 473 if (ret < 0) 474 return ret; 475 buf += ret; 476 blen -= ret; 477 payload <<= 1; 478 } 479 ret = snprintf(buf, blen, " (%d)", packet->count); 480 if (ret < 0) 481 return ret; 482 blen -= ret; 483 return buf_len - blen; 484 } 485 case INTEL_PT_TIP_PGD: 486 case INTEL_PT_TIP_PGE: 487 case INTEL_PT_TIP: 488 case INTEL_PT_FUP: 489 if (!(packet->count)) 490 return snprintf(buf, buf_len, "%s no ip", name); 491 case INTEL_PT_CYC: 492 case INTEL_PT_VMCS: 493 case INTEL_PT_MTC: 494 case INTEL_PT_MNT: 495 case INTEL_PT_CBR: 496 case INTEL_PT_TSC: 497 return snprintf(buf, buf_len, "%s 0x%llx", name, payload); 498 case INTEL_PT_TMA: 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); 507 case INTEL_PT_PIP: 508 nr = packet->payload & NR_FLAG ? 1 : 0; 509 payload &= ~NR_FLAG; 510 ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)", 511 name, payload, nr); 512 return ret; 513 default: 514 break; 515 } 516 return snprintf(buf, buf_len, "%s 0x%llx (%d)", 517 name, payload, packet->count); 518} 519