12025cf9eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2a4e92590SAdrian Hunter /* 3a4e92590SAdrian Hunter * intel_pt_pkt_decoder.c: Intel Processor Trace support 4a4e92590SAdrian Hunter * Copyright (c) 2013-2014, Intel Corporation. 5a4e92590SAdrian Hunter */ 6a4e92590SAdrian Hunter 7a4e92590SAdrian Hunter #include <stdio.h> 8a4e92590SAdrian Hunter #include <string.h> 9a4e92590SAdrian Hunter #include <endian.h> 10a4e92590SAdrian Hunter #include <byteswap.h> 117ea6856dSArnaldo Carvalho de Melo #include <linux/compiler.h> 12a4e92590SAdrian Hunter 13a4e92590SAdrian Hunter #include "intel-pt-pkt-decoder.h" 14a4e92590SAdrian Hunter 15a4e92590SAdrian Hunter #define BIT(n) (1 << (n)) 16a4e92590SAdrian Hunter 17a4e92590SAdrian Hunter #define BIT63 ((uint64_t)1 << 63) 18a4e92590SAdrian Hunter 194e88118cSIlya Leoshkevich #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 20a4e92590SAdrian Hunter #define le16_to_cpu bswap_16 21a4e92590SAdrian Hunter #define le32_to_cpu bswap_32 22a4e92590SAdrian Hunter #define le64_to_cpu bswap_64 23a4e92590SAdrian Hunter #define memcpy_le64(d, s, n) do { \ 24a4e92590SAdrian Hunter memcpy((d), (s), (n)); \ 25a4e92590SAdrian Hunter *(d) = le64_to_cpu(*(d)); \ 26a4e92590SAdrian Hunter } while (0) 27a4e92590SAdrian Hunter #else 28a4e92590SAdrian Hunter #define le16_to_cpu 29a4e92590SAdrian Hunter #define le32_to_cpu 30a4e92590SAdrian Hunter #define le64_to_cpu 31a4e92590SAdrian Hunter #define memcpy_le64 memcpy 32a4e92590SAdrian Hunter #endif 33a4e92590SAdrian Hunter 34a4e92590SAdrian Hunter static const char * const packet_name[] = { 35a4e92590SAdrian Hunter [INTEL_PT_BAD] = "Bad Packet!", 36a4e92590SAdrian Hunter [INTEL_PT_PAD] = "PAD", 37a4e92590SAdrian Hunter [INTEL_PT_TNT] = "TNT", 38a4e92590SAdrian Hunter [INTEL_PT_TIP_PGD] = "TIP.PGD", 39a4e92590SAdrian Hunter [INTEL_PT_TIP_PGE] = "TIP.PGE", 40a4e92590SAdrian Hunter [INTEL_PT_TSC] = "TSC", 413d498078SAdrian Hunter [INTEL_PT_TMA] = "TMA", 42a4e92590SAdrian Hunter [INTEL_PT_MODE_EXEC] = "MODE.Exec", 43a4e92590SAdrian Hunter [INTEL_PT_MODE_TSX] = "MODE.TSX", 443d498078SAdrian Hunter [INTEL_PT_MTC] = "MTC", 45a4e92590SAdrian Hunter [INTEL_PT_TIP] = "TIP", 46a4e92590SAdrian Hunter [INTEL_PT_FUP] = "FUP", 473d498078SAdrian Hunter [INTEL_PT_CYC] = "CYC", 483d498078SAdrian Hunter [INTEL_PT_VMCS] = "VMCS", 49a4e92590SAdrian Hunter [INTEL_PT_PSB] = "PSB", 50a4e92590SAdrian Hunter [INTEL_PT_PSBEND] = "PSBEND", 51a4e92590SAdrian Hunter [INTEL_PT_CBR] = "CBR", 523d498078SAdrian Hunter [INTEL_PT_TRACESTOP] = "TraceSTOP", 53a4e92590SAdrian Hunter [INTEL_PT_PIP] = "PIP", 54a4e92590SAdrian Hunter [INTEL_PT_OVF] = "OVF", 553d498078SAdrian Hunter [INTEL_PT_MNT] = "MNT", 56a472e65fSAdrian Hunter [INTEL_PT_PTWRITE] = "PTWRITE", 57a472e65fSAdrian Hunter [INTEL_PT_PTWRITE_IP] = "PTWRITE", 58a472e65fSAdrian Hunter [INTEL_PT_EXSTOP] = "EXSTOP", 59a472e65fSAdrian Hunter [INTEL_PT_EXSTOP_IP] = "EXSTOP", 60a472e65fSAdrian Hunter [INTEL_PT_MWAIT] = "MWAIT", 61a472e65fSAdrian Hunter [INTEL_PT_PWRE] = "PWRE", 62a472e65fSAdrian Hunter [INTEL_PT_PWRX] = "PWRX", 63edff7809SAdrian Hunter [INTEL_PT_BBP] = "BBP", 64edff7809SAdrian Hunter [INTEL_PT_BIP] = "BIP", 65edff7809SAdrian Hunter [INTEL_PT_BEP] = "BEP", 66edff7809SAdrian Hunter [INTEL_PT_BEP_IP] = "BEP", 672750af50SAdrian Hunter [INTEL_PT_CFE] = "CFE", 682750af50SAdrian Hunter [INTEL_PT_CFE_IP] = "CFE", 692750af50SAdrian Hunter [INTEL_PT_EVD] = "EVD", 70a4e92590SAdrian Hunter }; 71a4e92590SAdrian Hunter 72a4e92590SAdrian Hunter const char *intel_pt_pkt_name(enum intel_pt_pkt_type type) 73a4e92590SAdrian Hunter { 74a4e92590SAdrian Hunter return packet_name[type]; 75a4e92590SAdrian Hunter } 76a4e92590SAdrian Hunter 77a4e92590SAdrian Hunter static int intel_pt_get_long_tnt(const unsigned char *buf, size_t len, 78a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 79a4e92590SAdrian Hunter { 80a4e92590SAdrian Hunter uint64_t payload; 81a4e92590SAdrian Hunter int count; 82a4e92590SAdrian Hunter 83a4e92590SAdrian Hunter if (len < 8) 84a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 85a4e92590SAdrian Hunter 86a4e92590SAdrian Hunter payload = le64_to_cpu(*(uint64_t *)buf); 87a4e92590SAdrian Hunter 88a4e92590SAdrian Hunter for (count = 47; count; count--) { 89a4e92590SAdrian Hunter if (payload & BIT63) 90a4e92590SAdrian Hunter break; 91a4e92590SAdrian Hunter payload <<= 1; 92a4e92590SAdrian Hunter } 93a4e92590SAdrian Hunter 94a4e92590SAdrian Hunter packet->type = INTEL_PT_TNT; 95a4e92590SAdrian Hunter packet->count = count; 96a4e92590SAdrian Hunter packet->payload = payload << 1; 97a4e92590SAdrian Hunter return 8; 98a4e92590SAdrian Hunter } 99a4e92590SAdrian Hunter 100a4e92590SAdrian Hunter static int intel_pt_get_pip(const unsigned char *buf, size_t len, 101a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 102a4e92590SAdrian Hunter { 103a4e92590SAdrian Hunter uint64_t payload = 0; 104a4e92590SAdrian Hunter 105a4e92590SAdrian Hunter if (len < 8) 106a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 107a4e92590SAdrian Hunter 108a4e92590SAdrian Hunter packet->type = INTEL_PT_PIP; 109a4e92590SAdrian Hunter memcpy_le64(&payload, buf + 2, 6); 11090af7555SAdrian Hunter packet->payload = payload; 111a4e92590SAdrian Hunter 112a4e92590SAdrian Hunter return 8; 113a4e92590SAdrian Hunter } 114a4e92590SAdrian Hunter 1153d498078SAdrian Hunter static int intel_pt_get_tracestop(struct intel_pt_pkt *packet) 1163d498078SAdrian Hunter { 1173d498078SAdrian Hunter packet->type = INTEL_PT_TRACESTOP; 1183d498078SAdrian Hunter return 2; 1193d498078SAdrian Hunter } 1203d498078SAdrian Hunter 121a4e92590SAdrian Hunter static int intel_pt_get_cbr(const unsigned char *buf, size_t len, 122a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 123a4e92590SAdrian Hunter { 124a4e92590SAdrian Hunter if (len < 4) 125a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 126a4e92590SAdrian Hunter packet->type = INTEL_PT_CBR; 12726fb2fb1SAdrian Hunter packet->payload = le16_to_cpu(*(uint16_t *)(buf + 2)); 128a4e92590SAdrian Hunter return 4; 129a4e92590SAdrian Hunter } 130a4e92590SAdrian Hunter 1313d498078SAdrian Hunter static int intel_pt_get_vmcs(const unsigned char *buf, size_t len, 1323d498078SAdrian Hunter struct intel_pt_pkt *packet) 1333d498078SAdrian Hunter { 1343d498078SAdrian Hunter unsigned int count = (52 - 5) >> 3; 1353d498078SAdrian Hunter 1363d498078SAdrian Hunter if (count < 1 || count > 7) 1373d498078SAdrian Hunter return INTEL_PT_BAD_PACKET; 1383d498078SAdrian Hunter 1393d498078SAdrian Hunter if (len < count + 2) 1403d498078SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 1413d498078SAdrian Hunter 1423d498078SAdrian Hunter packet->type = INTEL_PT_VMCS; 1433d498078SAdrian Hunter packet->count = count; 1443d498078SAdrian Hunter memcpy_le64(&packet->payload, buf + 2, count); 1453d498078SAdrian Hunter 1463d498078SAdrian Hunter return count + 2; 1473d498078SAdrian Hunter } 1483d498078SAdrian Hunter 149a4e92590SAdrian Hunter static int intel_pt_get_ovf(struct intel_pt_pkt *packet) 150a4e92590SAdrian Hunter { 151a4e92590SAdrian Hunter packet->type = INTEL_PT_OVF; 152a4e92590SAdrian Hunter return 2; 153a4e92590SAdrian Hunter } 154a4e92590SAdrian Hunter 155a4e92590SAdrian Hunter static int intel_pt_get_psb(const unsigned char *buf, size_t len, 156a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 157a4e92590SAdrian Hunter { 158a4e92590SAdrian Hunter int i; 159a4e92590SAdrian Hunter 160a4e92590SAdrian Hunter if (len < 16) 161a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 162a4e92590SAdrian Hunter 163a4e92590SAdrian Hunter for (i = 2; i < 16; i += 2) { 164a4e92590SAdrian Hunter if (buf[i] != 2 || buf[i + 1] != 0x82) 165a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 166a4e92590SAdrian Hunter } 167a4e92590SAdrian Hunter 168a4e92590SAdrian Hunter packet->type = INTEL_PT_PSB; 169a4e92590SAdrian Hunter return 16; 170a4e92590SAdrian Hunter } 171a4e92590SAdrian Hunter 172a4e92590SAdrian Hunter static int intel_pt_get_psbend(struct intel_pt_pkt *packet) 173a4e92590SAdrian Hunter { 174a4e92590SAdrian Hunter packet->type = INTEL_PT_PSBEND; 175a4e92590SAdrian Hunter return 2; 176a4e92590SAdrian Hunter } 177a4e92590SAdrian Hunter 1783d498078SAdrian Hunter static int intel_pt_get_tma(const unsigned char *buf, size_t len, 1793d498078SAdrian Hunter struct intel_pt_pkt *packet) 1803d498078SAdrian Hunter { 1813d498078SAdrian Hunter if (len < 7) 1823d498078SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 1833d498078SAdrian Hunter 1843d498078SAdrian Hunter packet->type = INTEL_PT_TMA; 1853d498078SAdrian Hunter packet->payload = buf[2] | (buf[3] << 8); 1863d498078SAdrian Hunter packet->count = buf[5] | ((buf[6] & BIT(0)) << 8); 1873d498078SAdrian Hunter return 7; 1883d498078SAdrian Hunter } 1893d498078SAdrian Hunter 190a4e92590SAdrian Hunter static int intel_pt_get_pad(struct intel_pt_pkt *packet) 191a4e92590SAdrian Hunter { 192a4e92590SAdrian Hunter packet->type = INTEL_PT_PAD; 193a4e92590SAdrian Hunter return 1; 194a4e92590SAdrian Hunter } 195a4e92590SAdrian Hunter 1963d498078SAdrian Hunter static int intel_pt_get_mnt(const unsigned char *buf, size_t len, 1973d498078SAdrian Hunter struct intel_pt_pkt *packet) 1983d498078SAdrian Hunter { 1993d498078SAdrian Hunter if (len < 11) 2003d498078SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 2013d498078SAdrian Hunter packet->type = INTEL_PT_MNT; 2023d498078SAdrian Hunter memcpy_le64(&packet->payload, buf + 3, 8); 2036816c254SAdrian Hunter return 11; 2043d498078SAdrian Hunter } 2053d498078SAdrian Hunter 2063d498078SAdrian Hunter static int intel_pt_get_3byte(const unsigned char *buf, size_t len, 2073d498078SAdrian Hunter struct intel_pt_pkt *packet) 2083d498078SAdrian Hunter { 2093d498078SAdrian Hunter if (len < 3) 2103d498078SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 2113d498078SAdrian Hunter 2123d498078SAdrian Hunter switch (buf[2]) { 2133d498078SAdrian Hunter case 0x88: /* MNT */ 2143d498078SAdrian Hunter return intel_pt_get_mnt(buf, len, packet); 2153d498078SAdrian Hunter default: 2163d498078SAdrian Hunter return INTEL_PT_BAD_PACKET; 2173d498078SAdrian Hunter } 2183d498078SAdrian Hunter } 2193d498078SAdrian Hunter 220a472e65fSAdrian Hunter static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len, 221a472e65fSAdrian Hunter struct intel_pt_pkt *packet) 222a472e65fSAdrian Hunter { 223a472e65fSAdrian Hunter packet->count = (buf[1] >> 5) & 0x3; 224a472e65fSAdrian Hunter packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP : 225a472e65fSAdrian Hunter INTEL_PT_PTWRITE; 226a472e65fSAdrian Hunter 227a472e65fSAdrian Hunter switch (packet->count) { 228a472e65fSAdrian Hunter case 0: 229a472e65fSAdrian Hunter if (len < 6) 230a472e65fSAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 231a472e65fSAdrian Hunter packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2)); 232a472e65fSAdrian Hunter return 6; 233a472e65fSAdrian Hunter case 1: 234a472e65fSAdrian Hunter if (len < 10) 235a472e65fSAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 236a472e65fSAdrian Hunter packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2)); 237a472e65fSAdrian Hunter return 10; 238a472e65fSAdrian Hunter default: 239a472e65fSAdrian Hunter return INTEL_PT_BAD_PACKET; 240a472e65fSAdrian Hunter } 241a472e65fSAdrian Hunter } 242a472e65fSAdrian Hunter 243a472e65fSAdrian Hunter static int intel_pt_get_exstop(struct intel_pt_pkt *packet) 244a472e65fSAdrian Hunter { 245a472e65fSAdrian Hunter packet->type = INTEL_PT_EXSTOP; 246a472e65fSAdrian Hunter return 2; 247a472e65fSAdrian Hunter } 248a472e65fSAdrian Hunter 249a472e65fSAdrian Hunter static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet) 250a472e65fSAdrian Hunter { 251a472e65fSAdrian Hunter packet->type = INTEL_PT_EXSTOP_IP; 252a472e65fSAdrian Hunter return 2; 253a472e65fSAdrian Hunter } 254a472e65fSAdrian Hunter 255a472e65fSAdrian Hunter static int intel_pt_get_mwait(const unsigned char *buf, size_t len, 256a472e65fSAdrian Hunter struct intel_pt_pkt *packet) 257a472e65fSAdrian Hunter { 258a472e65fSAdrian Hunter if (len < 10) 259a472e65fSAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 260a472e65fSAdrian Hunter packet->type = INTEL_PT_MWAIT; 261a472e65fSAdrian Hunter packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2)); 262a472e65fSAdrian Hunter return 10; 263a472e65fSAdrian Hunter } 264a472e65fSAdrian Hunter 265a472e65fSAdrian Hunter static int intel_pt_get_pwre(const unsigned char *buf, size_t len, 266a472e65fSAdrian Hunter struct intel_pt_pkt *packet) 267a472e65fSAdrian Hunter { 268a472e65fSAdrian Hunter if (len < 4) 269a472e65fSAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 270a472e65fSAdrian Hunter packet->type = INTEL_PT_PWRE; 271a472e65fSAdrian Hunter memcpy_le64(&packet->payload, buf + 2, 2); 272a472e65fSAdrian Hunter return 4; 273a472e65fSAdrian Hunter } 274a472e65fSAdrian Hunter 275a472e65fSAdrian Hunter static int intel_pt_get_pwrx(const unsigned char *buf, size_t len, 276a472e65fSAdrian Hunter struct intel_pt_pkt *packet) 277a472e65fSAdrian Hunter { 278a472e65fSAdrian Hunter if (len < 7) 279a472e65fSAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 280a472e65fSAdrian Hunter packet->type = INTEL_PT_PWRX; 281a472e65fSAdrian Hunter memcpy_le64(&packet->payload, buf + 2, 5); 282a472e65fSAdrian Hunter return 7; 283a472e65fSAdrian Hunter } 284a472e65fSAdrian Hunter 285edff7809SAdrian Hunter static int intel_pt_get_bbp(const unsigned char *buf, size_t len, 286edff7809SAdrian Hunter struct intel_pt_pkt *packet) 287edff7809SAdrian Hunter { 288edff7809SAdrian Hunter if (len < 3) 289edff7809SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 290edff7809SAdrian Hunter packet->type = INTEL_PT_BBP; 291edff7809SAdrian Hunter packet->count = buf[2] >> 7; 292edff7809SAdrian Hunter packet->payload = buf[2] & 0x1f; 293edff7809SAdrian Hunter return 3; 294edff7809SAdrian Hunter } 295edff7809SAdrian Hunter 296edff7809SAdrian Hunter static int intel_pt_get_bip_4(const unsigned char *buf, size_t len, 297edff7809SAdrian Hunter struct intel_pt_pkt *packet) 298edff7809SAdrian Hunter { 299edff7809SAdrian Hunter if (len < 5) 300edff7809SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 301edff7809SAdrian Hunter packet->type = INTEL_PT_BIP; 302edff7809SAdrian Hunter packet->count = buf[0] >> 3; 303edff7809SAdrian Hunter memcpy_le64(&packet->payload, buf + 1, 4); 304edff7809SAdrian Hunter return 5; 305edff7809SAdrian Hunter } 306edff7809SAdrian Hunter 307edff7809SAdrian Hunter static int intel_pt_get_bip_8(const unsigned char *buf, size_t len, 308edff7809SAdrian Hunter struct intel_pt_pkt *packet) 309edff7809SAdrian Hunter { 310edff7809SAdrian Hunter if (len < 9) 311edff7809SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 312edff7809SAdrian Hunter packet->type = INTEL_PT_BIP; 313edff7809SAdrian Hunter packet->count = buf[0] >> 3; 314edff7809SAdrian Hunter memcpy_le64(&packet->payload, buf + 1, 8); 315edff7809SAdrian Hunter return 9; 316edff7809SAdrian Hunter } 317edff7809SAdrian Hunter 318edff7809SAdrian Hunter static int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet) 319edff7809SAdrian Hunter { 320edff7809SAdrian Hunter if (len < 2) 321edff7809SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 322edff7809SAdrian Hunter packet->type = INTEL_PT_BEP; 323edff7809SAdrian Hunter return 2; 324edff7809SAdrian Hunter } 325edff7809SAdrian Hunter 326edff7809SAdrian Hunter static int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet) 327edff7809SAdrian Hunter { 328edff7809SAdrian Hunter if (len < 2) 329edff7809SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 330edff7809SAdrian Hunter packet->type = INTEL_PT_BEP_IP; 331edff7809SAdrian Hunter return 2; 332edff7809SAdrian Hunter } 333edff7809SAdrian Hunter 3342750af50SAdrian Hunter static int intel_pt_get_cfe(const unsigned char *buf, size_t len, 3352750af50SAdrian Hunter struct intel_pt_pkt *packet) 3362750af50SAdrian Hunter { 3372750af50SAdrian Hunter if (len < 4) 3382750af50SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 3392750af50SAdrian Hunter packet->type = buf[2] & 0x80 ? INTEL_PT_CFE_IP : INTEL_PT_CFE; 3402750af50SAdrian Hunter packet->count = buf[2] & 0x1f; 3412750af50SAdrian Hunter packet->payload = buf[3]; 3422750af50SAdrian Hunter return 4; 3432750af50SAdrian Hunter } 3442750af50SAdrian Hunter 3452750af50SAdrian Hunter static int intel_pt_get_evd(const unsigned char *buf, size_t len, 3462750af50SAdrian Hunter struct intel_pt_pkt *packet) 3472750af50SAdrian Hunter { 3482750af50SAdrian Hunter if (len < 11) 3492750af50SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 3502750af50SAdrian Hunter packet->type = INTEL_PT_EVD; 3512750af50SAdrian Hunter packet->count = buf[2] & 0x3f; 3522750af50SAdrian Hunter packet->payload = buf[3]; 3532750af50SAdrian Hunter memcpy_le64(&packet->payload, buf + 3, 8); 3542750af50SAdrian Hunter return 11; 3552750af50SAdrian Hunter } 3562750af50SAdrian Hunter 357a4e92590SAdrian Hunter static int intel_pt_get_ext(const unsigned char *buf, size_t len, 358a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 359a4e92590SAdrian Hunter { 360a4e92590SAdrian Hunter if (len < 2) 361a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 362a4e92590SAdrian Hunter 363a472e65fSAdrian Hunter if ((buf[1] & 0x1f) == 0x12) 364a472e65fSAdrian Hunter return intel_pt_get_ptwrite(buf, len, packet); 365a472e65fSAdrian Hunter 366a4e92590SAdrian Hunter switch (buf[1]) { 367a4e92590SAdrian Hunter case 0xa3: /* Long TNT */ 368a4e92590SAdrian Hunter return intel_pt_get_long_tnt(buf, len, packet); 369a4e92590SAdrian Hunter case 0x43: /* PIP */ 370a4e92590SAdrian Hunter return intel_pt_get_pip(buf, len, packet); 3713d498078SAdrian Hunter case 0x83: /* TraceStop */ 3723d498078SAdrian Hunter return intel_pt_get_tracestop(packet); 373a4e92590SAdrian Hunter case 0x03: /* CBR */ 374a4e92590SAdrian Hunter return intel_pt_get_cbr(buf, len, packet); 3753d498078SAdrian Hunter case 0xc8: /* VMCS */ 3763d498078SAdrian Hunter return intel_pt_get_vmcs(buf, len, packet); 377a4e92590SAdrian Hunter case 0xf3: /* OVF */ 378a4e92590SAdrian Hunter return intel_pt_get_ovf(packet); 379a4e92590SAdrian Hunter case 0x82: /* PSB */ 380a4e92590SAdrian Hunter return intel_pt_get_psb(buf, len, packet); 381a4e92590SAdrian Hunter case 0x23: /* PSBEND */ 382a4e92590SAdrian Hunter return intel_pt_get_psbend(packet); 3833d498078SAdrian Hunter case 0x73: /* TMA */ 3843d498078SAdrian Hunter return intel_pt_get_tma(buf, len, packet); 3853d498078SAdrian Hunter case 0xC3: /* 3-byte header */ 3863d498078SAdrian Hunter return intel_pt_get_3byte(buf, len, packet); 387a472e65fSAdrian Hunter case 0x62: /* EXSTOP no IP */ 388a472e65fSAdrian Hunter return intel_pt_get_exstop(packet); 389a472e65fSAdrian Hunter case 0xE2: /* EXSTOP with IP */ 390a472e65fSAdrian Hunter return intel_pt_get_exstop_ip(packet); 391a472e65fSAdrian Hunter case 0xC2: /* MWAIT */ 392a472e65fSAdrian Hunter return intel_pt_get_mwait(buf, len, packet); 393a472e65fSAdrian Hunter case 0x22: /* PWRE */ 394a472e65fSAdrian Hunter return intel_pt_get_pwre(buf, len, packet); 395a472e65fSAdrian Hunter case 0xA2: /* PWRX */ 396a472e65fSAdrian Hunter return intel_pt_get_pwrx(buf, len, packet); 397edff7809SAdrian Hunter case 0x63: /* BBP */ 398edff7809SAdrian Hunter return intel_pt_get_bbp(buf, len, packet); 399edff7809SAdrian Hunter case 0x33: /* BEP no IP */ 400edff7809SAdrian Hunter return intel_pt_get_bep(len, packet); 401edff7809SAdrian Hunter case 0xb3: /* BEP with IP */ 402edff7809SAdrian Hunter return intel_pt_get_bep_ip(len, packet); 4032750af50SAdrian Hunter case 0x13: /* CFE */ 4042750af50SAdrian Hunter return intel_pt_get_cfe(buf, len, packet); 4052750af50SAdrian Hunter case 0x53: /* EVD */ 4062750af50SAdrian Hunter return intel_pt_get_evd(buf, len, packet); 407a4e92590SAdrian Hunter default: 408a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 409a4e92590SAdrian Hunter } 410a4e92590SAdrian Hunter } 411a4e92590SAdrian Hunter 412a4e92590SAdrian Hunter static int intel_pt_get_short_tnt(unsigned int byte, 413a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 414a4e92590SAdrian Hunter { 415a4e92590SAdrian Hunter int count; 416a4e92590SAdrian Hunter 417a4e92590SAdrian Hunter for (count = 6; count; count--) { 418a4e92590SAdrian Hunter if (byte & BIT(7)) 419a4e92590SAdrian Hunter break; 420a4e92590SAdrian Hunter byte <<= 1; 421a4e92590SAdrian Hunter } 422a4e92590SAdrian Hunter 423a4e92590SAdrian Hunter packet->type = INTEL_PT_TNT; 424a4e92590SAdrian Hunter packet->count = count; 425a4e92590SAdrian Hunter packet->payload = (uint64_t)byte << 57; 426a4e92590SAdrian Hunter 427a4e92590SAdrian Hunter return 1; 428a4e92590SAdrian Hunter } 429a4e92590SAdrian Hunter 4303d498078SAdrian Hunter static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf, 4313d498078SAdrian Hunter size_t len, struct intel_pt_pkt *packet) 4323d498078SAdrian Hunter { 4333d498078SAdrian Hunter unsigned int offs = 1, shift; 4343d498078SAdrian Hunter uint64_t payload = byte >> 3; 4353d498078SAdrian Hunter 4363d498078SAdrian Hunter byte >>= 2; 4373d498078SAdrian Hunter len -= 1; 4383d498078SAdrian Hunter for (shift = 5; byte & 1; shift += 7) { 4393d498078SAdrian Hunter if (offs > 9) 4403d498078SAdrian Hunter return INTEL_PT_BAD_PACKET; 4413d498078SAdrian Hunter if (len < offs) 4423d498078SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 4433d498078SAdrian Hunter byte = buf[offs++]; 444621a5a32SAdrian Hunter payload |= ((uint64_t)byte >> 1) << shift; 4453d498078SAdrian Hunter } 4463d498078SAdrian Hunter 4473d498078SAdrian Hunter packet->type = INTEL_PT_CYC; 4483d498078SAdrian Hunter packet->payload = payload; 4493d498078SAdrian Hunter return offs; 4503d498078SAdrian Hunter } 4513d498078SAdrian Hunter 452a4e92590SAdrian Hunter static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte, 453a4e92590SAdrian Hunter const unsigned char *buf, size_t len, 454a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 455a4e92590SAdrian Hunter { 456e1717e04SAdrian Hunter int ip_len; 457e1717e04SAdrian Hunter 458e1717e04SAdrian Hunter packet->count = byte >> 5; 459e1717e04SAdrian Hunter 460e1717e04SAdrian Hunter switch (packet->count) { 461a4e92590SAdrian Hunter case 0: 462e1717e04SAdrian Hunter ip_len = 0; 463a4e92590SAdrian Hunter break; 464a4e92590SAdrian Hunter case 1: 465a4e92590SAdrian Hunter if (len < 3) 466a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 467e1717e04SAdrian Hunter ip_len = 2; 468a4e92590SAdrian Hunter packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1)); 469a4e92590SAdrian Hunter break; 470a4e92590SAdrian Hunter case 2: 471a4e92590SAdrian Hunter if (len < 5) 472a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 473e1717e04SAdrian Hunter ip_len = 4; 474a4e92590SAdrian Hunter packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1)); 475a4e92590SAdrian Hunter break; 476a4e92590SAdrian Hunter case 3: 477e1717e04SAdrian Hunter case 4: 478a4e92590SAdrian Hunter if (len < 7) 479a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 480e1717e04SAdrian Hunter ip_len = 6; 481a4e92590SAdrian Hunter memcpy_le64(&packet->payload, buf + 1, 6); 482a4e92590SAdrian Hunter break; 483e1717e04SAdrian Hunter case 6: 484e1717e04SAdrian Hunter if (len < 9) 485e1717e04SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 486e1717e04SAdrian Hunter ip_len = 8; 487e1717e04SAdrian Hunter packet->payload = le64_to_cpu(*(uint64_t *)(buf + 1)); 488e1717e04SAdrian Hunter break; 489a4e92590SAdrian Hunter default: 490a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 491a4e92590SAdrian Hunter } 492a4e92590SAdrian Hunter 493a4e92590SAdrian Hunter packet->type = type; 494a4e92590SAdrian Hunter 495e1717e04SAdrian Hunter return ip_len + 1; 496a4e92590SAdrian Hunter } 497a4e92590SAdrian Hunter 498a4e92590SAdrian Hunter static int intel_pt_get_mode(const unsigned char *buf, size_t len, 499a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 500a4e92590SAdrian Hunter { 501a4e92590SAdrian Hunter if (len < 2) 502a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 503a4e92590SAdrian Hunter 504a4e92590SAdrian Hunter switch (buf[1] >> 5) { 505a4e92590SAdrian Hunter case 0: 506a4e92590SAdrian Hunter packet->type = INTEL_PT_MODE_EXEC; 507*f7934477SAdrian Hunter packet->count = buf[1]; 508a4e92590SAdrian Hunter switch (buf[1] & 3) { 509a4e92590SAdrian Hunter case 0: 510a4e92590SAdrian Hunter packet->payload = 16; 511a4e92590SAdrian Hunter break; 512a4e92590SAdrian Hunter case 1: 513a4e92590SAdrian Hunter packet->payload = 64; 514a4e92590SAdrian Hunter break; 515a4e92590SAdrian Hunter case 2: 516a4e92590SAdrian Hunter packet->payload = 32; 517a4e92590SAdrian Hunter break; 518a4e92590SAdrian Hunter default: 519a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 520a4e92590SAdrian Hunter } 521a4e92590SAdrian Hunter break; 522a4e92590SAdrian Hunter case 1: 523a4e92590SAdrian Hunter packet->type = INTEL_PT_MODE_TSX; 524a4e92590SAdrian Hunter if ((buf[1] & 3) == 3) 525a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 526a4e92590SAdrian Hunter packet->payload = buf[1] & 3; 527a4e92590SAdrian Hunter break; 528a4e92590SAdrian Hunter default: 529a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 530a4e92590SAdrian Hunter } 531a4e92590SAdrian Hunter 532a4e92590SAdrian Hunter return 2; 533a4e92590SAdrian Hunter } 534a4e92590SAdrian Hunter 535a4e92590SAdrian Hunter static int intel_pt_get_tsc(const unsigned char *buf, size_t len, 536a4e92590SAdrian Hunter struct intel_pt_pkt *packet) 537a4e92590SAdrian Hunter { 538a4e92590SAdrian Hunter if (len < 8) 539a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 540a4e92590SAdrian Hunter packet->type = INTEL_PT_TSC; 541a4e92590SAdrian Hunter memcpy_le64(&packet->payload, buf + 1, 7); 542a4e92590SAdrian Hunter return 8; 543a4e92590SAdrian Hunter } 544a4e92590SAdrian Hunter 5453d498078SAdrian Hunter static int intel_pt_get_mtc(const unsigned char *buf, size_t len, 5463d498078SAdrian Hunter struct intel_pt_pkt *packet) 5473d498078SAdrian Hunter { 5483d498078SAdrian Hunter if (len < 2) 5493d498078SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 5503d498078SAdrian Hunter packet->type = INTEL_PT_MTC; 5513d498078SAdrian Hunter packet->payload = buf[1]; 5523d498078SAdrian Hunter return 2; 5533d498078SAdrian Hunter } 5543d498078SAdrian Hunter 555a4e92590SAdrian Hunter static int intel_pt_do_get_packet(const unsigned char *buf, size_t len, 556edff7809SAdrian Hunter struct intel_pt_pkt *packet, 557edff7809SAdrian Hunter enum intel_pt_pkt_ctx ctx) 558a4e92590SAdrian Hunter { 559a4e92590SAdrian Hunter unsigned int byte; 560a4e92590SAdrian Hunter 561a4e92590SAdrian Hunter memset(packet, 0, sizeof(struct intel_pt_pkt)); 562a4e92590SAdrian Hunter 563a4e92590SAdrian Hunter if (!len) 564a4e92590SAdrian Hunter return INTEL_PT_NEED_MORE_BYTES; 565a4e92590SAdrian Hunter 566a4e92590SAdrian Hunter byte = buf[0]; 567edff7809SAdrian Hunter 568edff7809SAdrian Hunter switch (ctx) { 569edff7809SAdrian Hunter case INTEL_PT_NO_CTX: 570edff7809SAdrian Hunter break; 571edff7809SAdrian Hunter case INTEL_PT_BLK_4_CTX: 572edff7809SAdrian Hunter if ((byte & 0x7) == 4) 573edff7809SAdrian Hunter return intel_pt_get_bip_4(buf, len, packet); 574edff7809SAdrian Hunter break; 575edff7809SAdrian Hunter case INTEL_PT_BLK_8_CTX: 576edff7809SAdrian Hunter if ((byte & 0x7) == 4) 577edff7809SAdrian Hunter return intel_pt_get_bip_8(buf, len, packet); 578edff7809SAdrian Hunter break; 579edff7809SAdrian Hunter default: 580edff7809SAdrian Hunter break; 5818284bbeaSZou Wei } 582edff7809SAdrian Hunter 583a4e92590SAdrian Hunter if (!(byte & BIT(0))) { 584a4e92590SAdrian Hunter if (byte == 0) 585a4e92590SAdrian Hunter return intel_pt_get_pad(packet); 586a4e92590SAdrian Hunter if (byte == 2) 587a4e92590SAdrian Hunter return intel_pt_get_ext(buf, len, packet); 588a4e92590SAdrian Hunter return intel_pt_get_short_tnt(byte, packet); 589a4e92590SAdrian Hunter } 590a4e92590SAdrian Hunter 5913d498078SAdrian Hunter if ((byte & 2)) 5923d498078SAdrian Hunter return intel_pt_get_cyc(byte, buf, len, packet); 5933d498078SAdrian Hunter 594a4e92590SAdrian Hunter switch (byte & 0x1f) { 595a4e92590SAdrian Hunter case 0x0D: 596a4e92590SAdrian Hunter return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet); 597a4e92590SAdrian Hunter case 0x11: 598a4e92590SAdrian Hunter return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len, 599a4e92590SAdrian Hunter packet); 600a4e92590SAdrian Hunter case 0x01: 601a4e92590SAdrian Hunter return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len, 602a4e92590SAdrian Hunter packet); 603a4e92590SAdrian Hunter case 0x1D: 604a4e92590SAdrian Hunter return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet); 605a4e92590SAdrian Hunter case 0x19: 606a4e92590SAdrian Hunter switch (byte) { 607a4e92590SAdrian Hunter case 0x99: 608a4e92590SAdrian Hunter return intel_pt_get_mode(buf, len, packet); 609a4e92590SAdrian Hunter case 0x19: 610a4e92590SAdrian Hunter return intel_pt_get_tsc(buf, len, packet); 6113d498078SAdrian Hunter case 0x59: 6123d498078SAdrian Hunter return intel_pt_get_mtc(buf, len, packet); 613a4e92590SAdrian Hunter default: 614a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 615a4e92590SAdrian Hunter } 616a4e92590SAdrian Hunter default: 617a4e92590SAdrian Hunter return INTEL_PT_BAD_PACKET; 618a4e92590SAdrian Hunter } 619a4e92590SAdrian Hunter } 620a4e92590SAdrian Hunter 621edff7809SAdrian Hunter void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet, 622edff7809SAdrian Hunter enum intel_pt_pkt_ctx *ctx) 623edff7809SAdrian Hunter { 624edff7809SAdrian Hunter switch (packet->type) { 625edff7809SAdrian Hunter case INTEL_PT_BAD: 626edff7809SAdrian Hunter case INTEL_PT_PAD: 627edff7809SAdrian Hunter case INTEL_PT_TSC: 628edff7809SAdrian Hunter case INTEL_PT_TMA: 629edff7809SAdrian Hunter case INTEL_PT_MTC: 630edff7809SAdrian Hunter case INTEL_PT_FUP: 631edff7809SAdrian Hunter case INTEL_PT_CYC: 632edff7809SAdrian Hunter case INTEL_PT_CBR: 633edff7809SAdrian Hunter case INTEL_PT_MNT: 634edff7809SAdrian Hunter case INTEL_PT_EXSTOP: 635edff7809SAdrian Hunter case INTEL_PT_EXSTOP_IP: 636edff7809SAdrian Hunter case INTEL_PT_PWRE: 637edff7809SAdrian Hunter case INTEL_PT_PWRX: 638edff7809SAdrian Hunter case INTEL_PT_BIP: 639edff7809SAdrian Hunter break; 640edff7809SAdrian Hunter case INTEL_PT_TNT: 641edff7809SAdrian Hunter case INTEL_PT_TIP: 642edff7809SAdrian Hunter case INTEL_PT_TIP_PGD: 643edff7809SAdrian Hunter case INTEL_PT_TIP_PGE: 644edff7809SAdrian Hunter case INTEL_PT_MODE_EXEC: 645edff7809SAdrian Hunter case INTEL_PT_MODE_TSX: 646edff7809SAdrian Hunter case INTEL_PT_PIP: 647edff7809SAdrian Hunter case INTEL_PT_OVF: 648edff7809SAdrian Hunter case INTEL_PT_VMCS: 649edff7809SAdrian Hunter case INTEL_PT_TRACESTOP: 650edff7809SAdrian Hunter case INTEL_PT_PSB: 651edff7809SAdrian Hunter case INTEL_PT_PSBEND: 652edff7809SAdrian Hunter case INTEL_PT_PTWRITE: 653edff7809SAdrian Hunter case INTEL_PT_PTWRITE_IP: 654edff7809SAdrian Hunter case INTEL_PT_MWAIT: 655edff7809SAdrian Hunter case INTEL_PT_BEP: 656edff7809SAdrian Hunter case INTEL_PT_BEP_IP: 6572750af50SAdrian Hunter case INTEL_PT_CFE: 6582750af50SAdrian Hunter case INTEL_PT_CFE_IP: 6592750af50SAdrian Hunter case INTEL_PT_EVD: 660edff7809SAdrian Hunter *ctx = INTEL_PT_NO_CTX; 661edff7809SAdrian Hunter break; 662edff7809SAdrian Hunter case INTEL_PT_BBP: 663edff7809SAdrian Hunter if (packet->count) 664edff7809SAdrian Hunter *ctx = INTEL_PT_BLK_4_CTX; 665edff7809SAdrian Hunter else 666edff7809SAdrian Hunter *ctx = INTEL_PT_BLK_8_CTX; 667edff7809SAdrian Hunter break; 668edff7809SAdrian Hunter default: 669edff7809SAdrian Hunter break; 670edff7809SAdrian Hunter } 671edff7809SAdrian Hunter } 672edff7809SAdrian Hunter 673a4e92590SAdrian Hunter int intel_pt_get_packet(const unsigned char *buf, size_t len, 674edff7809SAdrian Hunter struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx) 675a4e92590SAdrian Hunter { 676a4e92590SAdrian Hunter int ret; 677a4e92590SAdrian Hunter 678edff7809SAdrian Hunter ret = intel_pt_do_get_packet(buf, len, packet, *ctx); 679a4e92590SAdrian Hunter if (ret > 0) { 680a4e92590SAdrian Hunter while (ret < 8 && len > (size_t)ret && !buf[ret]) 681a4e92590SAdrian Hunter ret += 1; 682edff7809SAdrian Hunter intel_pt_upd_pkt_ctx(packet, ctx); 683a4e92590SAdrian Hunter } 684a4e92590SAdrian Hunter return ret; 685a4e92590SAdrian Hunter } 686a4e92590SAdrian Hunter 687a4e92590SAdrian Hunter int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf, 688a4e92590SAdrian Hunter size_t buf_len) 689a4e92590SAdrian Hunter { 6903d498078SAdrian Hunter int ret, i, nr; 691a4e92590SAdrian Hunter unsigned long long payload = packet->payload; 692a4e92590SAdrian Hunter const char *name = intel_pt_pkt_name(packet->type); 693a4e92590SAdrian Hunter 694a4e92590SAdrian Hunter switch (packet->type) { 695a4e92590SAdrian Hunter case INTEL_PT_BAD: 696a4e92590SAdrian Hunter case INTEL_PT_PAD: 697a4e92590SAdrian Hunter case INTEL_PT_PSB: 698a4e92590SAdrian Hunter case INTEL_PT_PSBEND: 6993d498078SAdrian Hunter case INTEL_PT_TRACESTOP: 700a4e92590SAdrian Hunter case INTEL_PT_OVF: 701a4e92590SAdrian Hunter return snprintf(buf, buf_len, "%s", name); 702a4e92590SAdrian Hunter case INTEL_PT_TNT: { 703a4e92590SAdrian Hunter size_t blen = buf_len; 704a4e92590SAdrian Hunter 705a4e92590SAdrian Hunter ret = snprintf(buf, blen, "%s ", name); 706a4e92590SAdrian Hunter if (ret < 0) 707a4e92590SAdrian Hunter return ret; 708a4e92590SAdrian Hunter buf += ret; 709a4e92590SAdrian Hunter blen -= ret; 710a4e92590SAdrian Hunter for (i = 0; i < packet->count; i++) { 711a4e92590SAdrian Hunter if (payload & BIT63) 712a4e92590SAdrian Hunter ret = snprintf(buf, blen, "T"); 713a4e92590SAdrian Hunter else 714a4e92590SAdrian Hunter ret = snprintf(buf, blen, "N"); 715a4e92590SAdrian Hunter if (ret < 0) 716a4e92590SAdrian Hunter return ret; 717a4e92590SAdrian Hunter buf += ret; 718a4e92590SAdrian Hunter blen -= ret; 719a4e92590SAdrian Hunter payload <<= 1; 720a4e92590SAdrian Hunter } 721a4e92590SAdrian Hunter ret = snprintf(buf, blen, " (%d)", packet->count); 722a4e92590SAdrian Hunter if (ret < 0) 723a4e92590SAdrian Hunter return ret; 724a4e92590SAdrian Hunter blen -= ret; 725a4e92590SAdrian Hunter return buf_len - blen; 726a4e92590SAdrian Hunter } 727a4e92590SAdrian Hunter case INTEL_PT_TIP_PGD: 728a4e92590SAdrian Hunter case INTEL_PT_TIP_PGE: 729a4e92590SAdrian Hunter case INTEL_PT_TIP: 730a4e92590SAdrian Hunter case INTEL_PT_FUP: 731a4e92590SAdrian Hunter if (!(packet->count)) 732a4e92590SAdrian Hunter return snprintf(buf, buf_len, "%s no ip", name); 7337ea6856dSArnaldo Carvalho de Melo __fallthrough; 7343d498078SAdrian Hunter case INTEL_PT_CYC: 7353d498078SAdrian Hunter case INTEL_PT_VMCS: 7363d498078SAdrian Hunter case INTEL_PT_MTC: 7373d498078SAdrian Hunter case INTEL_PT_MNT: 738a4e92590SAdrian Hunter case INTEL_PT_CBR: 739a4e92590SAdrian Hunter case INTEL_PT_TSC: 7403d498078SAdrian Hunter return snprintf(buf, buf_len, "%s 0x%llx", name, payload); 7413d498078SAdrian Hunter case INTEL_PT_TMA: 7423d498078SAdrian Hunter return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name, 7433d498078SAdrian Hunter (unsigned)payload, packet->count); 744a4e92590SAdrian Hunter case INTEL_PT_MODE_EXEC: 745*f7934477SAdrian Hunter return snprintf(buf, buf_len, "%s IF:%d %lld", 746*f7934477SAdrian Hunter name, !!(packet->count & 4), payload); 747a4e92590SAdrian Hunter case INTEL_PT_MODE_TSX: 748a4e92590SAdrian Hunter return snprintf(buf, buf_len, "%s TXAbort:%u InTX:%u", 749a4e92590SAdrian Hunter name, (unsigned)(payload >> 1) & 1, 750a4e92590SAdrian Hunter (unsigned)payload & 1); 751a4e92590SAdrian Hunter case INTEL_PT_PIP: 75290af7555SAdrian Hunter nr = packet->payload & INTEL_PT_VMX_NR_FLAG ? 1 : 0; 75390af7555SAdrian Hunter payload &= ~INTEL_PT_VMX_NR_FLAG; 7543d498078SAdrian Hunter ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)", 75590af7555SAdrian Hunter name, payload >> 1, nr); 756a4e92590SAdrian Hunter return ret; 757a472e65fSAdrian Hunter case INTEL_PT_PTWRITE: 758a472e65fSAdrian Hunter return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload); 759a472e65fSAdrian Hunter case INTEL_PT_PTWRITE_IP: 760a472e65fSAdrian Hunter return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload); 761edff7809SAdrian Hunter case INTEL_PT_BEP: 762a472e65fSAdrian Hunter case INTEL_PT_EXSTOP: 763a472e65fSAdrian Hunter return snprintf(buf, buf_len, "%s IP:0", name); 764edff7809SAdrian Hunter case INTEL_PT_BEP_IP: 765a472e65fSAdrian Hunter case INTEL_PT_EXSTOP_IP: 766a472e65fSAdrian Hunter return snprintf(buf, buf_len, "%s IP:1", name); 767a472e65fSAdrian Hunter case INTEL_PT_MWAIT: 768a472e65fSAdrian Hunter return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x", 769a472e65fSAdrian Hunter name, payload, (unsigned int)(payload & 0xff), 770a472e65fSAdrian Hunter (unsigned int)((payload >> 32) & 0x3)); 771a472e65fSAdrian Hunter case INTEL_PT_PWRE: 772a472e65fSAdrian Hunter return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u", 773a472e65fSAdrian Hunter name, payload, !!(payload & 0x80), 774a472e65fSAdrian Hunter (unsigned int)((payload >> 12) & 0xf), 775a472e65fSAdrian Hunter (unsigned int)((payload >> 8) & 0xf)); 776a472e65fSAdrian Hunter case INTEL_PT_PWRX: 777a472e65fSAdrian Hunter return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x", 778a472e65fSAdrian Hunter name, payload, 779a472e65fSAdrian Hunter (unsigned int)((payload >> 4) & 0xf), 780a472e65fSAdrian Hunter (unsigned int)(payload & 0xf), 781a472e65fSAdrian Hunter (unsigned int)((payload >> 8) & 0xf)); 782edff7809SAdrian Hunter case INTEL_PT_BBP: 783edff7809SAdrian Hunter return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx", 784edff7809SAdrian Hunter name, packet->count ? "4" : "8", payload); 785edff7809SAdrian Hunter case INTEL_PT_BIP: 786edff7809SAdrian Hunter return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx", 787edff7809SAdrian Hunter name, packet->count, payload); 7882750af50SAdrian Hunter case INTEL_PT_CFE: 7892750af50SAdrian Hunter case INTEL_PT_CFE_IP: 7902750af50SAdrian Hunter return snprintf(buf, buf_len, "%s IP:%d Type 0x%02x Vector 0x%llx", 7912750af50SAdrian Hunter name, packet->type == INTEL_PT_CFE_IP, packet->count, payload); 7922750af50SAdrian Hunter case INTEL_PT_EVD: 7932750af50SAdrian Hunter return snprintf(buf, buf_len, "%s Type 0x%02x Payload 0x%llx", 7942750af50SAdrian Hunter name, packet->count, payload); 795a4e92590SAdrian Hunter default: 796a4e92590SAdrian Hunter break; 797a4e92590SAdrian Hunter } 798a4e92590SAdrian Hunter return snprintf(buf, buf_len, "%s 0x%llx (%d)", 799a4e92590SAdrian Hunter name, payload, packet->count); 800a4e92590SAdrian Hunter } 801