~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * intel_pt_pkt_decoder.c: Intel Processor Trace support
  4  * Copyright (c) 2013-2014, Intel Corporation.
  5  */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <endian.h>
 10 #include <byteswap.h>
 11 #include <linux/kernel.h>
 12 #include <linux/compiler.h>
 13 #include <asm-generic/unaligned.h>
 14 
 15 #include "intel-pt-pkt-decoder.h"
 16 
 17 #define BIT(n)          (1 << (n))
 18 
 19 #define BIT63           ((uint64_t)1 << 63)
 20 
 21 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 22 #define memcpy_le64(d, s, n) do { \
 23         memcpy((d), (s), (n));    \
 24         *(d) = le64_to_cpu(*(d)); \
 25 } while (0)
 26 #else
 27 #define memcpy_le64 memcpy
 28 #endif
 29 
 30 static const char * const packet_name[] = {
 31         [INTEL_PT_BAD]          = "Bad Packet!",
 32         [INTEL_PT_PAD]          = "PAD",
 33         [INTEL_PT_TNT]          = "TNT",
 34         [INTEL_PT_TIP_PGD]      = "TIP.PGD",
 35         [INTEL_PT_TIP_PGE]      = "TIP.PGE",
 36         [INTEL_PT_TSC]          = "TSC",
 37         [INTEL_PT_TMA]          = "TMA",
 38         [INTEL_PT_MODE_EXEC]    = "MODE.Exec",
 39         [INTEL_PT_MODE_TSX]     = "MODE.TSX",
 40         [INTEL_PT_MTC]          = "MTC",
 41         [INTEL_PT_TIP]          = "TIP",
 42         [INTEL_PT_FUP]          = "FUP",
 43         [INTEL_PT_CYC]          = "CYC",
 44         [INTEL_PT_VMCS]         = "VMCS",
 45         [INTEL_PT_PSB]          = "PSB",
 46         [INTEL_PT_PSBEND]       = "PSBEND",
 47         [INTEL_PT_CBR]          = "CBR",
 48         [INTEL_PT_TRACESTOP]    = "TraceSTOP",
 49         [INTEL_PT_PIP]          = "PIP",
 50         [INTEL_PT_OVF]          = "OVF",
 51         [INTEL_PT_MNT]          = "MNT",
 52         [INTEL_PT_PTWRITE]      = "PTWRITE",
 53         [INTEL_PT_PTWRITE_IP]   = "PTWRITE",
 54         [INTEL_PT_EXSTOP]       = "EXSTOP",
 55         [INTEL_PT_EXSTOP_IP]    = "EXSTOP",
 56         [INTEL_PT_MWAIT]        = "MWAIT",
 57         [INTEL_PT_PWRE]         = "PWRE",
 58         [INTEL_PT_PWRX]         = "PWRX",
 59         [INTEL_PT_BBP]          = "BBP",
 60         [INTEL_PT_BIP]          = "BIP",
 61         [INTEL_PT_BEP]          = "BEP",
 62         [INTEL_PT_BEP_IP]       = "BEP",
 63         [INTEL_PT_CFE]          = "CFE",
 64         [INTEL_PT_CFE_IP]       = "CFE",
 65         [INTEL_PT_EVD]          = "EVD",
 66 };
 67 
 68 const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
 69 {
 70         return packet_name[type];
 71 }
 72 
 73 static 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 = get_unaligned_le64(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 
 96 static 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;
107 
108         return 8;
109 }
110 
111 static int intel_pt_get_tracestop(struct intel_pt_pkt *packet)
112 {
113         packet->type = INTEL_PT_TRACESTOP;
114         return 2;
115 }
116 
117 static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
118                             struct intel_pt_pkt *packet)
119 {
120         if (len < 4)
121                 return INTEL_PT_NEED_MORE_BYTES;
122         packet->type = INTEL_PT_CBR;
123         packet->payload = get_unaligned_le16(buf + 2);
124         return 4;
125 }
126 
127 static int intel_pt_get_vmcs(const unsigned char *buf, size_t len,
128                              struct intel_pt_pkt *packet)
129 {
130         if (len < 7)
131                 return INTEL_PT_NEED_MORE_BYTES;
132 
133         packet->type = INTEL_PT_VMCS;
134         packet->count = 5;
135         memcpy_le64(&packet->payload, buf + 2, 5);
136 
137         return 7;
138 }
139 
140 static int intel_pt_get_ovf(struct intel_pt_pkt *packet)
141 {
142         packet->type = INTEL_PT_OVF;
143         return 2;
144 }
145 
146 static int intel_pt_get_psb(const unsigned char *buf, size_t len,
147                             struct intel_pt_pkt *packet)
148 {
149         int i;
150 
151         if (len < 16)
152                 return INTEL_PT_NEED_MORE_BYTES;
153 
154         for (i = 2; i < 16; i += 2) {
155                 if (buf[i] != 2 || buf[i + 1] != 0x82)
156                         return INTEL_PT_BAD_PACKET;
157         }
158 
159         packet->type = INTEL_PT_PSB;
160         return 16;
161 }
162 
163 static int intel_pt_get_psbend(struct intel_pt_pkt *packet)
164 {
165         packet->type = INTEL_PT_PSBEND;
166         return 2;
167 }
168 
169 static int intel_pt_get_tma(const unsigned char *buf, size_t len,
170                             struct intel_pt_pkt *packet)
171 {
172         if (len < 7)
173                 return INTEL_PT_NEED_MORE_BYTES;
174 
175         packet->type = INTEL_PT_TMA;
176         packet->payload = buf[2] | (buf[3] << 8);
177         packet->count = buf[5] | ((buf[6] & BIT(0)) << 8);
178         return 7;
179 }
180 
181 static int intel_pt_get_pad(struct intel_pt_pkt *packet)
182 {
183         packet->type = INTEL_PT_PAD;
184         return 1;
185 }
186 
187 static int intel_pt_get_mnt(const unsigned char *buf, size_t len,
188                             struct intel_pt_pkt *packet)
189 {
190         if (len < 11)
191                 return INTEL_PT_NEED_MORE_BYTES;
192         packet->type = INTEL_PT_MNT;
193         packet->payload = get_unaligned_le64(buf + 3);
194         return 11;
195 }
196 
197 static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
198                               struct intel_pt_pkt *packet)
199 {
200         if (len < 3)
201                 return INTEL_PT_NEED_MORE_BYTES;
202 
203         switch (buf[2]) {
204         case 0x88: /* MNT */
205                 return intel_pt_get_mnt(buf, len, packet);
206         default:
207                 return INTEL_PT_BAD_PACKET;
208         }
209 }
210 
211 static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len,
212                                 struct intel_pt_pkt *packet)
213 {
214         packet->count = (buf[1] >> 5) & 0x3;
215         packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP :
216                                          INTEL_PT_PTWRITE;
217 
218         switch (packet->count) {
219         case 0:
220                 if (len < 6)
221                         return INTEL_PT_NEED_MORE_BYTES;
222                 packet->payload = get_unaligned_le32(buf + 2);
223                 return 6;
224         case 1:
225                 if (len < 10)
226                         return INTEL_PT_NEED_MORE_BYTES;
227                 packet->payload = get_unaligned_le64(buf + 2);
228                 return 10;
229         default:
230                 return INTEL_PT_BAD_PACKET;
231         }
232 }
233 
234 static int intel_pt_get_exstop(struct intel_pt_pkt *packet)
235 {
236         packet->type = INTEL_PT_EXSTOP;
237         return 2;
238 }
239 
240 static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet)
241 {
242         packet->type = INTEL_PT_EXSTOP_IP;
243         return 2;
244 }
245 
246 static int intel_pt_get_mwait(const unsigned char *buf, size_t len,
247                               struct intel_pt_pkt *packet)
248 {
249         if (len < 10)
250                 return INTEL_PT_NEED_MORE_BYTES;
251         packet->type = INTEL_PT_MWAIT;
252         packet->payload = get_unaligned_le64(buf + 2);
253         return 10;
254 }
255 
256 static int intel_pt_get_pwre(const unsigned char *buf, size_t len,
257                              struct intel_pt_pkt *packet)
258 {
259         if (len < 4)
260                 return INTEL_PT_NEED_MORE_BYTES;
261         packet->type = INTEL_PT_PWRE;
262         memcpy_le64(&packet->payload, buf + 2, 2);
263         return 4;
264 }
265 
266 static int intel_pt_get_pwrx(const unsigned char *buf, size_t len,
267                              struct intel_pt_pkt *packet)
268 {
269         if (len < 7)
270                 return INTEL_PT_NEED_MORE_BYTES;
271         packet->type = INTEL_PT_PWRX;
272         memcpy_le64(&packet->payload, buf + 2, 5);
273         return 7;
274 }
275 
276 static int intel_pt_get_bbp(const unsigned char *buf, size_t len,
277                             struct intel_pt_pkt *packet)
278 {
279         if (len < 3)
280                 return INTEL_PT_NEED_MORE_BYTES;
281         packet->type = INTEL_PT_BBP;
282         packet->count = buf[2] >> 7;
283         packet->payload = buf[2] & 0x1f;
284         return 3;
285 }
286 
287 static int intel_pt_get_bip_4(const unsigned char *buf, size_t len,
288                               struct intel_pt_pkt *packet)
289 {
290         if (len < 5)
291                 return INTEL_PT_NEED_MORE_BYTES;
292         packet->type = INTEL_PT_BIP;
293         packet->count = buf[0] >> 3;
294         memcpy_le64(&packet->payload, buf + 1, 4);
295         return 5;
296 }
297 
298 static int intel_pt_get_bip_8(const unsigned char *buf, size_t len,
299                               struct intel_pt_pkt *packet)
300 {
301         if (len < 9)
302                 return INTEL_PT_NEED_MORE_BYTES;
303         packet->type = INTEL_PT_BIP;
304         packet->count = buf[0] >> 3;
305         packet->payload = get_unaligned_le64(buf + 1);
306         return 9;
307 }
308 
309 static int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet)
310 {
311         if (len < 2)
312                 return INTEL_PT_NEED_MORE_BYTES;
313         packet->type = INTEL_PT_BEP;
314         return 2;
315 }
316 
317 static int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet)
318 {
319         if (len < 2)
320                 return INTEL_PT_NEED_MORE_BYTES;
321         packet->type = INTEL_PT_BEP_IP;
322         return 2;
323 }
324 
325 static int intel_pt_get_cfe(const unsigned char *buf, size_t len,
326                             struct intel_pt_pkt *packet)
327 {
328         if (len < 4)
329                 return INTEL_PT_NEED_MORE_BYTES;
330         packet->type = buf[2] & 0x80 ? INTEL_PT_CFE_IP : INTEL_PT_CFE;
331         packet->count = buf[2] & 0x1f;
332         packet->payload = buf[3];
333         return 4;
334 }
335 
336 static int intel_pt_get_evd(const unsigned char *buf, size_t len,
337                             struct intel_pt_pkt *packet)
338 {
339         if (len < 11)
340                 return INTEL_PT_NEED_MORE_BYTES;
341         packet->type = INTEL_PT_EVD;
342         packet->count = buf[2] & 0x3f;
343         packet->payload = buf[3];
344         packet->payload = get_unaligned_le64(buf + 3);
345         return 11;
346 }
347 
348 static int intel_pt_get_ext(const unsigned char *buf, size_t len,
349                             struct intel_pt_pkt *packet)
350 {
351         if (len < 2)
352                 return INTEL_PT_NEED_MORE_BYTES;
353 
354         if ((buf[1] & 0x1f) == 0x12)
355                 return intel_pt_get_ptwrite(buf, len, packet);
356 
357         switch (buf[1]) {
358         case 0xa3: /* Long TNT */
359                 return intel_pt_get_long_tnt(buf, len, packet);
360         case 0x43: /* PIP */
361                 return intel_pt_get_pip(buf, len, packet);
362         case 0x83: /* TraceStop */
363                 return intel_pt_get_tracestop(packet);
364         case 0x03: /* CBR */
365                 return intel_pt_get_cbr(buf, len, packet);
366         case 0xc8: /* VMCS */
367                 return intel_pt_get_vmcs(buf, len, packet);
368         case 0xf3: /* OVF */
369                 return intel_pt_get_ovf(packet);
370         case 0x82: /* PSB */
371                 return intel_pt_get_psb(buf, len, packet);
372         case 0x23: /* PSBEND */
373                 return intel_pt_get_psbend(packet);
374         case 0x73: /* TMA */
375                 return intel_pt_get_tma(buf, len, packet);
376         case 0xC3: /* 3-byte header */
377                 return intel_pt_get_3byte(buf, len, packet);
378         case 0x62: /* EXSTOP no IP */
379                 return intel_pt_get_exstop(packet);
380         case 0xE2: /* EXSTOP with IP */
381                 return intel_pt_get_exstop_ip(packet);
382         case 0xC2: /* MWAIT */
383                 return intel_pt_get_mwait(buf, len, packet);
384         case 0x22: /* PWRE */
385                 return intel_pt_get_pwre(buf, len, packet);
386         case 0xA2: /* PWRX */
387                 return intel_pt_get_pwrx(buf, len, packet);
388         case 0x63: /* BBP */
389                 return intel_pt_get_bbp(buf, len, packet);
390         case 0x33: /* BEP no IP */
391                 return intel_pt_get_bep(len, packet);
392         case 0xb3: /* BEP with IP */
393                 return intel_pt_get_bep_ip(len, packet);
394         case 0x13: /* CFE */
395                 return intel_pt_get_cfe(buf, len, packet);
396         case 0x53: /* EVD */
397                 return intel_pt_get_evd(buf, len, packet);
398         default:
399                 return INTEL_PT_BAD_PACKET;
400         }
401 }
402 
403 static int intel_pt_get_short_tnt(unsigned int byte,
404                                   struct intel_pt_pkt *packet)
405 {
406         int count;
407 
408         for (count = 6; count; count--) {
409                 if (byte & BIT(7))
410                         break;
411                 byte <<= 1;
412         }
413 
414         packet->type = INTEL_PT_TNT;
415         packet->count = count;
416         packet->payload = (uint64_t)byte << 57;
417 
418         return 1;
419 }
420 
421 static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf,
422                             size_t len, struct intel_pt_pkt *packet)
423 {
424         unsigned int offs = 1, shift;
425         uint64_t payload = byte >> 3;
426 
427         byte >>= 2;
428         len -= 1;
429         for (shift = 5; byte & 1; shift += 7) {
430                 if (offs > 9)
431                         return INTEL_PT_BAD_PACKET;
432                 if (len < offs)
433                         return INTEL_PT_NEED_MORE_BYTES;
434                 byte = buf[offs++];
435                 payload |= ((uint64_t)byte >> 1) << shift;
436         }
437 
438         packet->type = INTEL_PT_CYC;
439         packet->payload = payload;
440         return offs;
441 }
442 
443 static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
444                            const unsigned char *buf, size_t len,
445                            struct intel_pt_pkt *packet)
446 {
447         int ip_len;
448 
449         packet->count = byte >> 5;
450 
451         switch (packet->count) {
452         case 0:
453                 ip_len = 0;
454                 break;
455         case 1:
456                 if (len < 3)
457                         return INTEL_PT_NEED_MORE_BYTES;
458                 ip_len = 2;
459                 packet->payload = get_unaligned_le16(buf + 1);
460                 break;
461         case 2:
462                 if (len < 5)
463                         return INTEL_PT_NEED_MORE_BYTES;
464                 ip_len = 4;
465                 packet->payload = get_unaligned_le32(buf + 1);
466                 break;
467         case 3:
468         case 4:
469                 if (len < 7)
470                         return INTEL_PT_NEED_MORE_BYTES;
471                 ip_len = 6;
472                 memcpy_le64(&packet->payload, buf + 1, 6);
473                 break;
474         case 6:
475                 if (len < 9)
476                         return INTEL_PT_NEED_MORE_BYTES;
477                 ip_len = 8;
478                 packet->payload = get_unaligned_le64(buf + 1);
479                 break;
480         default:
481                 return INTEL_PT_BAD_PACKET;
482         }
483 
484         packet->type = type;
485 
486         return ip_len + 1;
487 }
488 
489 static int intel_pt_get_mode(const unsigned char *buf, size_t len,
490                              struct intel_pt_pkt *packet)
491 {
492         if (len < 2)
493                 return INTEL_PT_NEED_MORE_BYTES;
494 
495         switch (buf[1] >> 5) {
496         case 0:
497                 packet->type = INTEL_PT_MODE_EXEC;
498                 packet->count = buf[1];
499                 switch (buf[1] & 3) {
500                 case 0:
501                         packet->payload = 16;
502                         break;
503                 case 1:
504                         packet->payload = 64;
505                         break;
506                 case 2:
507                         packet->payload = 32;
508                         break;
509                 default:
510                         return INTEL_PT_BAD_PACKET;
511                 }
512                 break;
513         case 1:
514                 packet->type = INTEL_PT_MODE_TSX;
515                 if ((buf[1] & 3) == 3)
516                         return INTEL_PT_BAD_PACKET;
517                 packet->payload = buf[1] & 3;
518                 break;
519         default:
520                 return INTEL_PT_BAD_PACKET;
521         }
522 
523         return 2;
524 }
525 
526 static int intel_pt_get_tsc(const unsigned char *buf, size_t len,
527                             struct intel_pt_pkt *packet)
528 {
529         if (len < 8)
530                 return INTEL_PT_NEED_MORE_BYTES;
531         packet->type = INTEL_PT_TSC;
532         memcpy_le64(&packet->payload, buf + 1, 7);
533         return 8;
534 }
535 
536 static int intel_pt_get_mtc(const unsigned char *buf, size_t len,
537                             struct intel_pt_pkt *packet)
538 {
539         if (len < 2)
540                 return INTEL_PT_NEED_MORE_BYTES;
541         packet->type = INTEL_PT_MTC;
542         packet->payload = buf[1];
543         return 2;
544 }
545 
546 static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
547                                   struct intel_pt_pkt *packet,
548                                   enum intel_pt_pkt_ctx ctx)
549 {
550         unsigned int byte;
551 
552         memset(packet, 0, sizeof(struct intel_pt_pkt));
553 
554         if (!len)
555                 return INTEL_PT_NEED_MORE_BYTES;
556 
557         byte = buf[0];
558 
559         switch (ctx) {
560         case INTEL_PT_NO_CTX:
561                 break;
562         case INTEL_PT_BLK_4_CTX:
563                 if ((byte & 0x7) == 4)
564                         return intel_pt_get_bip_4(buf, len, packet);
565                 break;
566         case INTEL_PT_BLK_8_CTX:
567                 if ((byte & 0x7) == 4)
568                         return intel_pt_get_bip_8(buf, len, packet);
569                 break;
570         default:
571                 break;
572         }
573 
574         if (!(byte & BIT(0))) {
575                 if (byte == 0)
576                         return intel_pt_get_pad(packet);
577                 if (byte == 2)
578                         return intel_pt_get_ext(buf, len, packet);
579                 return intel_pt_get_short_tnt(byte, packet);
580         }
581 
582         if ((byte & 2))
583                 return intel_pt_get_cyc(byte, buf, len, packet);
584 
585         switch (byte & 0x1f) {
586         case 0x0D:
587                 return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet);
588         case 0x11:
589                 return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len,
590                                        packet);
591         case 0x01:
592                 return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len,
593                                        packet);
594         case 0x1D:
595                 return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet);
596         case 0x19:
597                 switch (byte) {
598                 case 0x99:
599                         return intel_pt_get_mode(buf, len, packet);
600                 case 0x19:
601                         return intel_pt_get_tsc(buf, len, packet);
602                 case 0x59:
603                         return intel_pt_get_mtc(buf, len, packet);
604                 default:
605                         return INTEL_PT_BAD_PACKET;
606                 }
607         default:
608                 return INTEL_PT_BAD_PACKET;
609         }
610 }
611 
612 void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet,
613                           enum intel_pt_pkt_ctx *ctx)
614 {
615         switch (packet->type) {
616         case INTEL_PT_BAD:
617         case INTEL_PT_PAD:
618         case INTEL_PT_TSC:
619         case INTEL_PT_TMA:
620         case INTEL_PT_MTC:
621         case INTEL_PT_FUP:
622         case INTEL_PT_CYC:
623         case INTEL_PT_CBR:
624         case INTEL_PT_MNT:
625         case INTEL_PT_EXSTOP:
626         case INTEL_PT_EXSTOP_IP:
627         case INTEL_PT_PWRE:
628         case INTEL_PT_PWRX:
629         case INTEL_PT_BIP:
630                 break;
631         case INTEL_PT_TNT:
632         case INTEL_PT_TIP:
633         case INTEL_PT_TIP_PGD:
634         case INTEL_PT_TIP_PGE:
635         case INTEL_PT_MODE_EXEC:
636         case INTEL_PT_MODE_TSX:
637         case INTEL_PT_PIP:
638         case INTEL_PT_OVF:
639         case INTEL_PT_VMCS:
640         case INTEL_PT_TRACESTOP:
641         case INTEL_PT_PSB:
642         case INTEL_PT_PSBEND:
643         case INTEL_PT_PTWRITE:
644         case INTEL_PT_PTWRITE_IP:
645         case INTEL_PT_MWAIT:
646         case INTEL_PT_BEP:
647         case INTEL_PT_BEP_IP:
648         case INTEL_PT_CFE:
649         case INTEL_PT_CFE_IP:
650         case INTEL_PT_EVD:
651                 *ctx = INTEL_PT_NO_CTX;
652                 break;
653         case INTEL_PT_BBP:
654                 if (packet->count)
655                         *ctx = INTEL_PT_BLK_4_CTX;
656                 else
657                         *ctx = INTEL_PT_BLK_8_CTX;
658                 break;
659         default:
660                 break;
661         }
662 }
663 
664 int intel_pt_get_packet(const unsigned char *buf, size_t len,
665                         struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx)
666 {
667         int ret;
668 
669         ret = intel_pt_do_get_packet(buf, len, packet, *ctx);
670         if (ret > 0) {
671                 while (ret < 8 && len > (size_t)ret && !buf[ret])
672                         ret += 1;
673                 intel_pt_upd_pkt_ctx(packet, ctx);
674         }
675         return ret;
676 }
677 
678 int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
679                       size_t buf_len)
680 {
681         int ret, i, nr;
682         unsigned long long payload = packet->payload;
683         const char *name = intel_pt_pkt_name(packet->type);
684 
685         switch (packet->type) {
686         case INTEL_PT_BAD:
687         case INTEL_PT_PAD:
688         case INTEL_PT_PSB:
689         case INTEL_PT_PSBEND:
690         case INTEL_PT_TRACESTOP:
691         case INTEL_PT_OVF:
692                 return snprintf(buf, buf_len, "%s", name);
693         case INTEL_PT_TNT: {
694                 size_t blen = buf_len;
695 
696                 ret = snprintf(buf, blen, "%s ", name);
697                 if (ret < 0)
698                         return ret;
699                 buf += ret;
700                 blen -= ret;
701                 for (i = 0; i < packet->count; i++) {
702                         if (payload & BIT63)
703                                 ret = snprintf(buf, blen, "T");
704                         else
705                                 ret = snprintf(buf, blen, "N");
706                         if (ret < 0)
707                                 return ret;
708                         buf += ret;
709                         blen -= ret;
710                         payload <<= 1;
711                 }
712                 ret = snprintf(buf, blen, " (%d)", packet->count);
713                 if (ret < 0)
714                         return ret;
715                 blen -= ret;
716                 return buf_len - blen;
717         }
718         case INTEL_PT_TIP_PGD:
719         case INTEL_PT_TIP_PGE:
720         case INTEL_PT_TIP:
721         case INTEL_PT_FUP:
722                 if (!(packet->count))
723                         return snprintf(buf, buf_len, "%s no ip", name);
724                 fallthrough;
725         case INTEL_PT_CYC:
726         case INTEL_PT_VMCS:
727         case INTEL_PT_MTC:
728         case INTEL_PT_MNT:
729         case INTEL_PT_CBR:
730         case INTEL_PT_TSC:
731                 return snprintf(buf, buf_len, "%s 0x%llx", name, payload);
732         case INTEL_PT_TMA:
733                 return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name,
734                                 (unsigned)payload, packet->count);
735         case INTEL_PT_MODE_EXEC:
736                 return snprintf(buf, buf_len, "%s IF:%d %lld",
737                                 name, !!(packet->count & 4), payload);
738         case INTEL_PT_MODE_TSX:
739                 return snprintf(buf, buf_len, "%s TXAbort:%u InTX:%u",
740                                 name, (unsigned)(payload >> 1) & 1,
741                                 (unsigned)payload & 1);
742         case INTEL_PT_PIP:
743                 nr = packet->payload & INTEL_PT_VMX_NR_FLAG ? 1 : 0;
744                 payload &= ~INTEL_PT_VMX_NR_FLAG;
745                 ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
746                                name, payload >> 1, nr);
747                 return ret;
748         case INTEL_PT_PTWRITE:
749                 return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
750         case INTEL_PT_PTWRITE_IP:
751                 return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
752         case INTEL_PT_BEP:
753         case INTEL_PT_EXSTOP:
754                 return snprintf(buf, buf_len, "%s IP:0", name);
755         case INTEL_PT_BEP_IP:
756         case INTEL_PT_EXSTOP_IP:
757                 return snprintf(buf, buf_len, "%s IP:1", name);
758         case INTEL_PT_MWAIT:
759                 return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x",
760                                 name, payload, (unsigned int)(payload & 0xff),
761                                 (unsigned int)((payload >> 32) & 0x3));
762         case INTEL_PT_PWRE:
763                 return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u",
764                                 name, payload, !!(payload & 0x80),
765                                 (unsigned int)((payload >> 12) & 0xf),
766                                 (unsigned int)((payload >> 8) & 0xf));
767         case INTEL_PT_PWRX:
768                 return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x",
769                                 name, payload,
770                                 (unsigned int)((payload >> 4) & 0xf),
771                                 (unsigned int)(payload & 0xf),
772                                 (unsigned int)((payload >> 8) & 0xf));
773         case INTEL_PT_BBP:
774                 return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx",
775                                 name, packet->count ? "4" : "8", payload);
776         case INTEL_PT_BIP:
777                 return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx",
778                                 name, packet->count, payload);
779         case INTEL_PT_CFE:
780         case INTEL_PT_CFE_IP:
781                 return snprintf(buf, buf_len, "%s IP:%d Type 0x%02x Vector 0x%llx",
782                                 name, packet->type == INTEL_PT_CFE_IP, packet->count, payload);
783         case INTEL_PT_EVD:
784                 return snprintf(buf, buf_len, "%s Type 0x%02x Payload 0x%llx",
785                                 name, packet->count, payload);
786         default:
787                 break;
788         }
789         return snprintf(buf, buf_len, "%s 0x%llx (%d)",
790                         name, payload, packet->count);
791 }
792 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php