hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * intel_pt_pkt_decoder.c: Intel Processor Trace support
34 * 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
- *
145 */
156
167 #include <stdio.h>
....@@ -71,6 +62,10 @@
7162 [INTEL_PT_MWAIT] = "MWAIT",
7263 [INTEL_PT_PWRE] = "PWRE",
7364 [INTEL_PT_PWRX] = "PWRX",
65
+ [INTEL_PT_BBP] = "BBP",
66
+ [INTEL_PT_BIP] = "BIP",
67
+ [INTEL_PT_BEP] = "BEP",
68
+ [INTEL_PT_BEP_IP] = "BEP",
7469 };
7570
7671 const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
....@@ -289,6 +284,55 @@
289284 return 7;
290285 }
291286
287
+static int intel_pt_get_bbp(const unsigned char *buf, size_t len,
288
+ struct intel_pt_pkt *packet)
289
+{
290
+ if (len < 3)
291
+ return INTEL_PT_NEED_MORE_BYTES;
292
+ packet->type = INTEL_PT_BBP;
293
+ packet->count = buf[2] >> 7;
294
+ packet->payload = buf[2] & 0x1f;
295
+ return 3;
296
+}
297
+
298
+static int intel_pt_get_bip_4(const unsigned char *buf, size_t len,
299
+ struct intel_pt_pkt *packet)
300
+{
301
+ if (len < 5)
302
+ return INTEL_PT_NEED_MORE_BYTES;
303
+ packet->type = INTEL_PT_BIP;
304
+ packet->count = buf[0] >> 3;
305
+ memcpy_le64(&packet->payload, buf + 1, 4);
306
+ return 5;
307
+}
308
+
309
+static int intel_pt_get_bip_8(const unsigned char *buf, size_t len,
310
+ struct intel_pt_pkt *packet)
311
+{
312
+ if (len < 9)
313
+ return INTEL_PT_NEED_MORE_BYTES;
314
+ packet->type = INTEL_PT_BIP;
315
+ packet->count = buf[0] >> 3;
316
+ memcpy_le64(&packet->payload, buf + 1, 8);
317
+ return 9;
318
+}
319
+
320
+static int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet)
321
+{
322
+ if (len < 2)
323
+ return INTEL_PT_NEED_MORE_BYTES;
324
+ packet->type = INTEL_PT_BEP;
325
+ return 2;
326
+}
327
+
328
+static int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet)
329
+{
330
+ if (len < 2)
331
+ return INTEL_PT_NEED_MORE_BYTES;
332
+ packet->type = INTEL_PT_BEP_IP;
333
+ return 2;
334
+}
335
+
292336 static int intel_pt_get_ext(const unsigned char *buf, size_t len,
293337 struct intel_pt_pkt *packet)
294338 {
....@@ -329,6 +373,12 @@
329373 return intel_pt_get_pwre(buf, len, packet);
330374 case 0xA2: /* PWRX */
331375 return intel_pt_get_pwrx(buf, len, packet);
376
+ case 0x63: /* BBP */
377
+ return intel_pt_get_bbp(buf, len, packet);
378
+ case 0x33: /* BEP no IP */
379
+ return intel_pt_get_bep(len, packet);
380
+ case 0xb3: /* BEP with IP */
381
+ return intel_pt_get_bep_ip(len, packet);
332382 default:
333383 return INTEL_PT_BAD_PACKET;
334384 }
....@@ -477,7 +527,8 @@
477527 }
478528
479529 static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
480
- struct intel_pt_pkt *packet)
530
+ struct intel_pt_pkt *packet,
531
+ enum intel_pt_pkt_ctx ctx)
481532 {
482533 unsigned int byte;
483534
....@@ -487,6 +538,22 @@
487538 return INTEL_PT_NEED_MORE_BYTES;
488539
489540 byte = buf[0];
541
+
542
+ switch (ctx) {
543
+ case INTEL_PT_NO_CTX:
544
+ break;
545
+ case INTEL_PT_BLK_4_CTX:
546
+ if ((byte & 0x7) == 4)
547
+ return intel_pt_get_bip_4(buf, len, packet);
548
+ break;
549
+ case INTEL_PT_BLK_8_CTX:
550
+ if ((byte & 0x7) == 4)
551
+ return intel_pt_get_bip_8(buf, len, packet);
552
+ break;
553
+ default:
554
+ break;
555
+ }
556
+
490557 if (!(byte & BIT(0))) {
491558 if (byte == 0)
492559 return intel_pt_get_pad(packet);
....@@ -525,15 +592,65 @@
525592 }
526593 }
527594
595
+void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet,
596
+ enum intel_pt_pkt_ctx *ctx)
597
+{
598
+ switch (packet->type) {
599
+ case INTEL_PT_BAD:
600
+ case INTEL_PT_PAD:
601
+ case INTEL_PT_TSC:
602
+ case INTEL_PT_TMA:
603
+ case INTEL_PT_MTC:
604
+ case INTEL_PT_FUP:
605
+ case INTEL_PT_CYC:
606
+ case INTEL_PT_CBR:
607
+ case INTEL_PT_MNT:
608
+ case INTEL_PT_EXSTOP:
609
+ case INTEL_PT_EXSTOP_IP:
610
+ case INTEL_PT_PWRE:
611
+ case INTEL_PT_PWRX:
612
+ case INTEL_PT_BIP:
613
+ break;
614
+ case INTEL_PT_TNT:
615
+ case INTEL_PT_TIP:
616
+ case INTEL_PT_TIP_PGD:
617
+ case INTEL_PT_TIP_PGE:
618
+ case INTEL_PT_MODE_EXEC:
619
+ case INTEL_PT_MODE_TSX:
620
+ case INTEL_PT_PIP:
621
+ case INTEL_PT_OVF:
622
+ case INTEL_PT_VMCS:
623
+ case INTEL_PT_TRACESTOP:
624
+ case INTEL_PT_PSB:
625
+ case INTEL_PT_PSBEND:
626
+ case INTEL_PT_PTWRITE:
627
+ case INTEL_PT_PTWRITE_IP:
628
+ case INTEL_PT_MWAIT:
629
+ case INTEL_PT_BEP:
630
+ case INTEL_PT_BEP_IP:
631
+ *ctx = INTEL_PT_NO_CTX;
632
+ break;
633
+ case INTEL_PT_BBP:
634
+ if (packet->count)
635
+ *ctx = INTEL_PT_BLK_4_CTX;
636
+ else
637
+ *ctx = INTEL_PT_BLK_8_CTX;
638
+ break;
639
+ default:
640
+ break;
641
+ }
642
+}
643
+
528644 int intel_pt_get_packet(const unsigned char *buf, size_t len,
529
- struct intel_pt_pkt *packet)
645
+ struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx)
530646 {
531647 int ret;
532648
533
- ret = intel_pt_do_get_packet(buf, len, packet);
649
+ ret = intel_pt_do_get_packet(buf, len, packet, *ctx);
534650 if (ret > 0) {
535651 while (ret < 8 && len > (size_t)ret && !buf[ret])
536652 ret += 1;
653
+ intel_pt_upd_pkt_ctx(packet, ctx);
537654 }
538655 return ret;
539656 }
....@@ -611,8 +728,10 @@
611728 return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
612729 case INTEL_PT_PTWRITE_IP:
613730 return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
731
+ case INTEL_PT_BEP:
614732 case INTEL_PT_EXSTOP:
615733 return snprintf(buf, buf_len, "%s IP:0", name);
734
+ case INTEL_PT_BEP_IP:
616735 case INTEL_PT_EXSTOP_IP:
617736 return snprintf(buf, buf_len, "%s IP:1", name);
618737 case INTEL_PT_MWAIT:
....@@ -630,6 +749,12 @@
630749 (unsigned int)((payload >> 4) & 0xf),
631750 (unsigned int)(payload & 0xf),
632751 (unsigned int)((payload >> 8) & 0xf));
752
+ case INTEL_PT_BBP:
753
+ return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx",
754
+ name, packet->count ? "4" : "8", payload);
755
+ case INTEL_PT_BIP:
756
+ return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx",
757
+ name, packet->count, payload);
633758 default:
634759 break;
635760 }