linux/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
<<
>>
Prefs
   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#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: /* MNT */
 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: /* Long TNT */
 303                return intel_pt_get_long_tnt(buf, len, packet);
 304        case 0x43: /* PIP */
 305                return intel_pt_get_pip(buf, len, packet);
 306        case 0x83: /* TraceStop */
 307                return intel_pt_get_tracestop(packet);
 308        case 0x03: /* CBR */
 309                return intel_pt_get_cbr(buf, len, packet);
 310        case 0xc8: /* VMCS */
 311                return intel_pt_get_vmcs(buf, len, packet);
 312        case 0xf3: /* OVF */
 313                return intel_pt_get_ovf(packet);
 314        case 0x82: /* PSB */
 315                return intel_pt_get_psb(buf, len, packet);
 316        case 0x23: /* PSBEND */
 317                return intel_pt_get_psbend(packet);
 318        case 0x73: /* TMA */
 319                return intel_pt_get_tma(buf, len, packet);
 320        case 0xC3: /* 3-byte header */
 321                return intel_pt_get_3byte(buf, len, packet);
 322        case 0x62: /* EXSTOP no IP */
 323                return intel_pt_get_exstop(packet);
 324        case 0xE2: /* EXSTOP with IP */
 325                return intel_pt_get_exstop_ip(packet);
 326        case 0xC2: /* MWAIT */
 327                return intel_pt_get_mwait(buf, len, packet);
 328        case 0x22: /* PWRE */
 329                return intel_pt_get_pwre(buf, len, packet);
 330        case 0xA2: /* PWRX */
 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