blob: 75c4bd74d521c9948e47d11331a8db9a4b8448c2 [file] [log] [blame]
Thomas Gleixner2025cf92019-05-29 07:18:02 -07001// SPDX-License-Identifier: GPL-2.0-only
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002/*
3 * intel_pt_decoder.c: Intel Processor Trace support
4 * Copyright (c) 2013-2014, Intel Corporation.
Adrian Hunterf4aa0812015-07-17 19:33:40 +03005 */
6
7#ifndef _GNU_SOURCE
8#define _GNU_SOURCE
9#endif
10#include <stdlib.h>
11#include <stdbool.h>
12#include <string.h>
13#include <errno.h>
14#include <stdint.h>
15#include <inttypes.h>
Arnaldo Carvalho de Melo7ea68562017-02-09 15:22:22 -030016#include <linux/compiler.h>
Arnaldo Carvalho de Melofa0d9842019-08-30 12:52:25 -030017#include <linux/string.h>
Arnaldo Carvalho de Melo7f7c5362019-07-04 11:32:27 -030018#include <linux/zalloc.h>
Adrian Hunterf4aa0812015-07-17 19:33:40 +030019
Adrian Hunter5a99d992019-02-06 12:39:44 +020020#include "../auxtrace.h"
Adrian Hunterf4aa0812015-07-17 19:33:40 +030021
22#include "intel-pt-insn-decoder.h"
23#include "intel-pt-pkt-decoder.h"
24#include "intel-pt-decoder.h"
25#include "intel-pt-log.h"
26
27#define INTEL_PT_BLK_SIZE 1024
28
29#define BIT63 (((uint64_t)1 << 63))
30
31#define INTEL_PT_RETURN 1
32
33/* Maximum number of loops with no packets consumed i.e. stuck in a loop */
34#define INTEL_PT_MAX_LOOPS 10000
35
36struct intel_pt_blk {
37 struct intel_pt_blk *prev;
38 uint64_t ip[INTEL_PT_BLK_SIZE];
39};
40
41struct intel_pt_stack {
42 struct intel_pt_blk *blk;
43 struct intel_pt_blk *spare;
44 int pos;
45};
46
47enum intel_pt_pkt_state {
48 INTEL_PT_STATE_NO_PSB,
49 INTEL_PT_STATE_NO_IP,
50 INTEL_PT_STATE_ERR_RESYNC,
51 INTEL_PT_STATE_IN_SYNC,
Adrian Hunter61b6e082019-05-10 15:41:42 +030052 INTEL_PT_STATE_TNT_CONT,
Adrian Hunterf4aa0812015-07-17 19:33:40 +030053 INTEL_PT_STATE_TNT,
54 INTEL_PT_STATE_TIP,
55 INTEL_PT_STATE_TIP_PGD,
56 INTEL_PT_STATE_FUP,
57 INTEL_PT_STATE_FUP_NO_TIP,
58};
59
Adrian Hunter3f04d982017-05-26 11:17:03 +030060static inline bool intel_pt_sample_time(enum intel_pt_pkt_state pkt_state)
61{
62 switch (pkt_state) {
63 case INTEL_PT_STATE_NO_PSB:
64 case INTEL_PT_STATE_NO_IP:
65 case INTEL_PT_STATE_ERR_RESYNC:
66 case INTEL_PT_STATE_IN_SYNC:
Adrian Hunter61b6e082019-05-10 15:41:42 +030067 case INTEL_PT_STATE_TNT_CONT:
Adrian Hunter3f04d982017-05-26 11:17:03 +030068 return true;
Adrian Hunter61b6e082019-05-10 15:41:42 +030069 case INTEL_PT_STATE_TNT:
Adrian Hunter3f04d982017-05-26 11:17:03 +030070 case INTEL_PT_STATE_TIP:
71 case INTEL_PT_STATE_TIP_PGD:
72 case INTEL_PT_STATE_FUP:
73 case INTEL_PT_STATE_FUP_NO_TIP:
74 return false;
75 default:
76 return true;
77 };
78}
79
Adrian Hunterf4aa0812015-07-17 19:33:40 +030080#ifdef INTEL_PT_STRICT
81#define INTEL_PT_STATE_ERR1 INTEL_PT_STATE_NO_PSB
82#define INTEL_PT_STATE_ERR2 INTEL_PT_STATE_NO_PSB
83#define INTEL_PT_STATE_ERR3 INTEL_PT_STATE_NO_PSB
84#define INTEL_PT_STATE_ERR4 INTEL_PT_STATE_NO_PSB
85#else
86#define INTEL_PT_STATE_ERR1 (decoder->pkt_state)
87#define INTEL_PT_STATE_ERR2 INTEL_PT_STATE_NO_IP
88#define INTEL_PT_STATE_ERR3 INTEL_PT_STATE_ERR_RESYNC
89#define INTEL_PT_STATE_ERR4 INTEL_PT_STATE_IN_SYNC
90#endif
91
92struct intel_pt_decoder {
93 int (*get_trace)(struct intel_pt_buffer *buffer, void *data);
94 int (*walk_insn)(struct intel_pt_insn *intel_pt_insn,
95 uint64_t *insn_cnt_ptr, uint64_t *ip, uint64_t to_ip,
96 uint64_t max_insn_cnt, void *data);
Adrian Hunter9f1d1222016-09-23 17:38:47 +030097 bool (*pgd_ip)(uint64_t ip, void *data);
Adrian Hunter4d678e92019-06-04 16:00:02 +030098 int (*lookahead)(void *data, intel_pt_lookahead_cb_t cb, void *cb_data);
Adrian Hunterf4aa0812015-07-17 19:33:40 +030099 void *data;
100 struct intel_pt_state state;
101 const unsigned char *buf;
102 size_t len;
103 bool return_compression;
Adrian Hunter83959812017-05-26 11:17:11 +0300104 bool branch_enable;
Adrian Hunter79b58422015-07-17 19:33:55 +0300105 bool mtc_insn;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300106 bool pge;
Adrian Hunter79b58422015-07-17 19:33:55 +0300107 bool have_tma;
Adrian Huntercc336182015-07-17 19:33:57 +0300108 bool have_cyc;
Adrian Hunter3bccbe22016-09-28 14:41:36 +0300109 bool fixup_last_mtc;
Adrian Hunteree14ac02017-05-26 11:17:06 +0300110 bool have_last_ip;
Adrian Hunter9bc668e2019-05-20 14:37:15 +0300111 bool in_psb;
Adrian Hunter9fb52332018-05-31 13:23:45 +0300112 enum intel_pt_param_flags flags;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300113 uint64_t pos;
114 uint64_t last_ip;
115 uint64_t ip;
116 uint64_t cr3;
117 uint64_t timestamp;
118 uint64_t tsc_timestamp;
119 uint64_t ref_timestamp;
Adrian Huntera7fa19f2019-06-04 16:00:06 +0300120 uint64_t buf_timestamp;
Adrian Hunter3f04d982017-05-26 11:17:03 +0300121 uint64_t sample_timestamp;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300122 uint64_t ret_addr;
Adrian Hunter79b58422015-07-17 19:33:55 +0300123 uint64_t ctc_timestamp;
124 uint64_t ctc_delta;
Adrian Huntercc336182015-07-17 19:33:57 +0300125 uint64_t cycle_cnt;
126 uint64_t cyc_ref_timestamp;
Adrian Hunter79b58422015-07-17 19:33:55 +0300127 uint32_t last_mtc;
128 uint32_t tsc_ctc_ratio_n;
129 uint32_t tsc_ctc_ratio_d;
130 uint32_t tsc_ctc_mult;
131 uint32_t tsc_slip;
132 uint32_t ctc_rem_mask;
133 int mtc_shift;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300134 struct intel_pt_stack stack;
135 enum intel_pt_pkt_state pkt_state;
Adrian Hunteredff7802019-06-10 10:27:53 +0300136 enum intel_pt_pkt_ctx pkt_ctx;
Adrian Hunter4c355952019-06-10 10:27:55 +0300137 enum intel_pt_pkt_ctx prev_pkt_ctx;
138 enum intel_pt_blk_type blk_type;
139 int blk_type_pos;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300140 struct intel_pt_pkt packet;
141 struct intel_pt_pkt tnt;
142 int pkt_step;
143 int pkt_len;
Adrian Huntercc336182015-07-17 19:33:57 +0300144 int last_packet_type;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300145 unsigned int cbr;
Adrian Hunter0a7c700d2017-05-26 11:17:16 +0300146 unsigned int cbr_seen;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300147 unsigned int max_non_turbo_ratio;
Adrian Huntercc336182015-07-17 19:33:57 +0300148 double max_non_turbo_ratio_fp;
149 double cbr_cyc_to_tsc;
150 double calc_cyc_to_tsc;
151 bool have_calc_cyc_to_tsc;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300152 int exec_mode;
153 unsigned int insn_bytes;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300154 uint64_t period;
155 enum intel_pt_period_type period_type;
Adrian Hunter2a21d032015-07-17 19:33:48 +0300156 uint64_t tot_insn_cnt;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300157 uint64_t period_insn_cnt;
158 uint64_t period_mask;
159 uint64_t period_ticks;
160 uint64_t last_masked_timestamp;
Adrian Hunter7b4b4f82019-05-20 14:37:11 +0300161 uint64_t tot_cyc_cnt;
162 uint64_t sample_tot_cyc_cnt;
Adrian Hunter3f055162019-05-20 14:37:17 +0300163 uint64_t base_cyc_cnt;
164 uint64_t cyc_cnt_timestamp;
165 double tsc_to_cyc;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300166 bool continuous_period;
167 bool overflow;
168 bool set_fup_tx_flags;
Adrian Huntera472e652017-05-26 11:17:14 +0300169 bool set_fup_ptw;
170 bool set_fup_mwait;
171 bool set_fup_pwre;
172 bool set_fup_exstop;
Adrian Hunter4c355952019-06-10 10:27:55 +0300173 bool set_fup_bep;
Adrian Hunter7b4b4f82019-05-20 14:37:11 +0300174 bool sample_cyc;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300175 unsigned int fup_tx_flags;
176 unsigned int tx_flags;
Adrian Huntera472e652017-05-26 11:17:14 +0300177 uint64_t fup_ptw_payload;
178 uint64_t fup_mwait_payload;
179 uint64_t fup_pwre_payload;
Adrian Hunter0a7c700d2017-05-26 11:17:16 +0300180 uint64_t cbr_payload;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300181 uint64_t timestamp_insn_cnt;
Adrian Hunter3f04d982017-05-26 11:17:03 +0300182 uint64_t sample_insn_cnt;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300183 uint64_t stuck_ip;
184 int no_progress;
185 int stuck_ip_prd;
186 int stuck_ip_cnt;
187 const unsigned char *next_buf;
188 size_t next_len;
189 unsigned char temp_buf[INTEL_PT_PKT_MAX_SZ];
190};
191
192static uint64_t intel_pt_lower_power_of_2(uint64_t x)
193{
194 int i;
195
196 for (i = 0; x != 1; i++)
197 x >>= 1;
198
199 return x << i;
200}
201
202static void intel_pt_setup_period(struct intel_pt_decoder *decoder)
203{
204 if (decoder->period_type == INTEL_PT_PERIOD_TICKS) {
205 uint64_t period;
206
207 period = intel_pt_lower_power_of_2(decoder->period);
208 decoder->period_mask = ~(period - 1);
209 decoder->period_ticks = period;
210 }
211}
212
Adrian Hunter79b58422015-07-17 19:33:55 +0300213static uint64_t multdiv(uint64_t t, uint32_t n, uint32_t d)
214{
215 if (!d)
216 return 0;
217 return (t / d) * n + ((t % d) * n) / d;
218}
219
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300220struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
221{
222 struct intel_pt_decoder *decoder;
223
224 if (!params->get_trace || !params->walk_insn)
225 return NULL;
226
227 decoder = zalloc(sizeof(struct intel_pt_decoder));
228 if (!decoder)
229 return NULL;
230
231 decoder->get_trace = params->get_trace;
232 decoder->walk_insn = params->walk_insn;
Adrian Hunter9f1d1222016-09-23 17:38:47 +0300233 decoder->pgd_ip = params->pgd_ip;
Adrian Hunter4d678e92019-06-04 16:00:02 +0300234 decoder->lookahead = params->lookahead;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300235 decoder->data = params->data;
236 decoder->return_compression = params->return_compression;
Adrian Hunter83959812017-05-26 11:17:11 +0300237 decoder->branch_enable = params->branch_enable;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300238
Adrian Hunter9fb52332018-05-31 13:23:45 +0300239 decoder->flags = params->flags;
240
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300241 decoder->period = params->period;
242 decoder->period_type = params->period_type;
243
Adrian Huntercc336182015-07-17 19:33:57 +0300244 decoder->max_non_turbo_ratio = params->max_non_turbo_ratio;
245 decoder->max_non_turbo_ratio_fp = params->max_non_turbo_ratio;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300246
247 intel_pt_setup_period(decoder);
248
Adrian Hunter79b58422015-07-17 19:33:55 +0300249 decoder->mtc_shift = params->mtc_period;
250 decoder->ctc_rem_mask = (1 << decoder->mtc_shift) - 1;
251
252 decoder->tsc_ctc_ratio_n = params->tsc_ctc_ratio_n;
253 decoder->tsc_ctc_ratio_d = params->tsc_ctc_ratio_d;
254
255 if (!decoder->tsc_ctc_ratio_n)
256 decoder->tsc_ctc_ratio_d = 0;
257
258 if (decoder->tsc_ctc_ratio_d) {
259 if (!(decoder->tsc_ctc_ratio_n % decoder->tsc_ctc_ratio_d))
260 decoder->tsc_ctc_mult = decoder->tsc_ctc_ratio_n /
261 decoder->tsc_ctc_ratio_d;
Adrian Hunter79b58422015-07-17 19:33:55 +0300262 }
Adrian Hunterf3b4e062019-03-25 15:51:35 +0200263
264 /*
265 * A TSC packet can slip past MTC packets so that the timestamp appears
266 * to go backwards. One estimate is that can be up to about 40 CPU
267 * cycles, which is certainly less than 0x1000 TSC ticks, but accept
268 * slippage an order of magnitude more to be on the safe side.
269 */
270 decoder->tsc_slip = 0x10000;
Adrian Hunter79b58422015-07-17 19:33:55 +0300271
272 intel_pt_log("timestamp: mtc_shift %u\n", decoder->mtc_shift);
273 intel_pt_log("timestamp: tsc_ctc_ratio_n %u\n", decoder->tsc_ctc_ratio_n);
274 intel_pt_log("timestamp: tsc_ctc_ratio_d %u\n", decoder->tsc_ctc_ratio_d);
275 intel_pt_log("timestamp: tsc_ctc_mult %u\n", decoder->tsc_ctc_mult);
276 intel_pt_log("timestamp: tsc_slip %#x\n", decoder->tsc_slip);
277
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300278 return decoder;
279}
280
281static void intel_pt_pop_blk(struct intel_pt_stack *stack)
282{
283 struct intel_pt_blk *blk = stack->blk;
284
285 stack->blk = blk->prev;
286 if (!stack->spare)
287 stack->spare = blk;
288 else
289 free(blk);
290}
291
292static uint64_t intel_pt_pop(struct intel_pt_stack *stack)
293{
294 if (!stack->pos) {
295 if (!stack->blk)
296 return 0;
297 intel_pt_pop_blk(stack);
298 if (!stack->blk)
299 return 0;
300 stack->pos = INTEL_PT_BLK_SIZE;
301 }
302 return stack->blk->ip[--stack->pos];
303}
304
305static int intel_pt_alloc_blk(struct intel_pt_stack *stack)
306{
307 struct intel_pt_blk *blk;
308
309 if (stack->spare) {
310 blk = stack->spare;
311 stack->spare = NULL;
312 } else {
313 blk = malloc(sizeof(struct intel_pt_blk));
314 if (!blk)
315 return -ENOMEM;
316 }
317
318 blk->prev = stack->blk;
319 stack->blk = blk;
320 stack->pos = 0;
321 return 0;
322}
323
324static int intel_pt_push(struct intel_pt_stack *stack, uint64_t ip)
325{
326 int err;
327
328 if (!stack->blk || stack->pos == INTEL_PT_BLK_SIZE) {
329 err = intel_pt_alloc_blk(stack);
330 if (err)
331 return err;
332 }
333
334 stack->blk->ip[stack->pos++] = ip;
335 return 0;
336}
337
338static void intel_pt_clear_stack(struct intel_pt_stack *stack)
339{
340 while (stack->blk)
341 intel_pt_pop_blk(stack);
342 stack->pos = 0;
343}
344
345static void intel_pt_free_stack(struct intel_pt_stack *stack)
346{
347 intel_pt_clear_stack(stack);
348 zfree(&stack->blk);
349 zfree(&stack->spare);
350}
351
352void intel_pt_decoder_free(struct intel_pt_decoder *decoder)
353{
354 intel_pt_free_stack(&decoder->stack);
355 free(decoder);
356}
357
358static int intel_pt_ext_err(int code)
359{
360 switch (code) {
361 case -ENOMEM:
362 return INTEL_PT_ERR_NOMEM;
363 case -ENOSYS:
364 return INTEL_PT_ERR_INTERN;
365 case -EBADMSG:
366 return INTEL_PT_ERR_BADPKT;
367 case -ENODATA:
368 return INTEL_PT_ERR_NODATA;
369 case -EILSEQ:
370 return INTEL_PT_ERR_NOINSN;
371 case -ENOENT:
372 return INTEL_PT_ERR_MISMAT;
373 case -EOVERFLOW:
374 return INTEL_PT_ERR_OVR;
375 case -ENOSPC:
376 return INTEL_PT_ERR_LOST;
377 case -ELOOP:
378 return INTEL_PT_ERR_NELOOP;
379 default:
380 return INTEL_PT_ERR_UNK;
381 }
382}
383
384static const char *intel_pt_err_msgs[] = {
385 [INTEL_PT_ERR_NOMEM] = "Memory allocation failed",
386 [INTEL_PT_ERR_INTERN] = "Internal error",
387 [INTEL_PT_ERR_BADPKT] = "Bad packet",
388 [INTEL_PT_ERR_NODATA] = "No more data",
389 [INTEL_PT_ERR_NOINSN] = "Failed to get instruction",
390 [INTEL_PT_ERR_MISMAT] = "Trace doesn't match instruction",
391 [INTEL_PT_ERR_OVR] = "Overflow packet",
392 [INTEL_PT_ERR_LOST] = "Lost trace data",
393 [INTEL_PT_ERR_UNK] = "Unknown error!",
394 [INTEL_PT_ERR_NELOOP] = "Never-ending loop",
395};
396
397int intel_pt__strerror(int code, char *buf, size_t buflen)
398{
Colin Ian Kingc0664892016-04-24 19:56:43 +0100399 if (code < 1 || code >= INTEL_PT_ERR_MAX)
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300400 code = INTEL_PT_ERR_UNK;
401 strlcpy(buf, intel_pt_err_msgs[code], buflen);
402 return 0;
403}
404
Adrian Huntere1717e02016-07-20 12:00:06 +0300405static uint64_t intel_pt_calc_ip(const struct intel_pt_pkt *packet,
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300406 uint64_t last_ip)
407{
408 uint64_t ip;
409
410 switch (packet->count) {
Adrian Huntere1717e02016-07-20 12:00:06 +0300411 case 1:
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300412 ip = (last_ip & (uint64_t)0xffffffffffff0000ULL) |
413 packet->payload;
414 break;
Adrian Huntere1717e02016-07-20 12:00:06 +0300415 case 2:
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300416 ip = (last_ip & (uint64_t)0xffffffff00000000ULL) |
417 packet->payload;
418 break;
Adrian Huntere1717e02016-07-20 12:00:06 +0300419 case 3:
420 ip = packet->payload;
421 /* Sign-extend 6-byte ip */
422 if (ip & (uint64_t)0x800000000000ULL)
423 ip |= (uint64_t)0xffff000000000000ULL;
424 break;
425 case 4:
426 ip = (last_ip & (uint64_t)0xffff000000000000ULL) |
427 packet->payload;
428 break;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300429 case 6:
430 ip = packet->payload;
431 break;
432 default:
433 return 0;
434 }
435
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300436 return ip;
437}
438
439static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder)
440{
Adrian Huntere1717e02016-07-20 12:00:06 +0300441 decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip);
Adrian Hunteree14ac02017-05-26 11:17:06 +0300442 decoder->have_last_ip = true;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300443}
444
445static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder)
446{
447 intel_pt_set_last_ip(decoder);
448 decoder->ip = decoder->last_ip;
449}
450
451static void intel_pt_decoder_log_packet(struct intel_pt_decoder *decoder)
452{
453 intel_pt_log_packet(&decoder->packet, decoder->pkt_len, decoder->pos,
454 decoder->buf);
455}
456
457static int intel_pt_bug(struct intel_pt_decoder *decoder)
458{
459 intel_pt_log("ERROR: Internal error\n");
460 decoder->pkt_state = INTEL_PT_STATE_NO_PSB;
461 return -ENOSYS;
462}
463
464static inline void intel_pt_clear_tx_flags(struct intel_pt_decoder *decoder)
465{
466 decoder->tx_flags = 0;
467}
468
469static inline void intel_pt_update_in_tx(struct intel_pt_decoder *decoder)
470{
471 decoder->tx_flags = decoder->packet.payload & INTEL_PT_IN_TX;
472}
473
474static int intel_pt_bad_packet(struct intel_pt_decoder *decoder)
475{
476 intel_pt_clear_tx_flags(decoder);
Adrian Hunter79b58422015-07-17 19:33:55 +0300477 decoder->have_tma = false;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300478 decoder->pkt_len = 1;
479 decoder->pkt_step = 1;
480 intel_pt_decoder_log_packet(decoder);
481 if (decoder->pkt_state != INTEL_PT_STATE_NO_PSB) {
482 intel_pt_log("ERROR: Bad packet\n");
483 decoder->pkt_state = INTEL_PT_STATE_ERR1;
484 }
485 return -EBADMSG;
486}
487
Adrian Hunter948e9dc2019-05-20 14:37:10 +0300488static inline void intel_pt_update_sample_time(struct intel_pt_decoder *decoder)
489{
490 decoder->sample_timestamp = decoder->timestamp;
491 decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
492}
493
Adrian Hunter6492e5f2019-06-04 16:00:04 +0300494static void intel_pt_reposition(struct intel_pt_decoder *decoder)
495{
496 decoder->ip = 0;
497 decoder->pkt_state = INTEL_PT_STATE_NO_PSB;
498 decoder->timestamp = 0;
499 decoder->have_tma = false;
500}
501
Adrian Hunter6c1f0b12019-06-04 16:00:05 +0300502static int intel_pt_get_data(struct intel_pt_decoder *decoder, bool reposition)
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300503{
504 struct intel_pt_buffer buffer = { .buf = 0, };
505 int ret;
506
507 decoder->pkt_step = 0;
508
509 intel_pt_log("Getting more data\n");
510 ret = decoder->get_trace(&buffer, decoder->data);
511 if (ret)
512 return ret;
513 decoder->buf = buffer.buf;
514 decoder->len = buffer.len;
515 if (!decoder->len) {
516 intel_pt_log("No more data\n");
517 return -ENODATA;
518 }
Adrian Huntera7fa19f2019-06-04 16:00:06 +0300519 decoder->buf_timestamp = buffer.ref_timestamp;
Adrian Hunter6c1f0b12019-06-04 16:00:05 +0300520 if (!buffer.consecutive || reposition) {
Adrian Hunter6492e5f2019-06-04 16:00:04 +0300521 intel_pt_reposition(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300522 decoder->ref_timestamp = buffer.ref_timestamp;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300523 decoder->state.trace_nr = buffer.trace_nr;
524 intel_pt_log("Reference timestamp 0x%" PRIx64 "\n",
525 decoder->ref_timestamp);
526 return -ENOLINK;
527 }
528
529 return 0;
530}
531
Adrian Hunter6c1f0b12019-06-04 16:00:05 +0300532static int intel_pt_get_next_data(struct intel_pt_decoder *decoder,
533 bool reposition)
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300534{
535 if (!decoder->next_buf)
Adrian Hunter6c1f0b12019-06-04 16:00:05 +0300536 return intel_pt_get_data(decoder, reposition);
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300537
538 decoder->buf = decoder->next_buf;
539 decoder->len = decoder->next_len;
540 decoder->next_buf = 0;
541 decoder->next_len = 0;
542 return 0;
543}
544
545static int intel_pt_get_split_packet(struct intel_pt_decoder *decoder)
546{
547 unsigned char *buf = decoder->temp_buf;
548 size_t old_len, len, n;
549 int ret;
550
551 old_len = decoder->len;
552 len = decoder->len;
553 memcpy(buf, decoder->buf, len);
554
Adrian Hunter6c1f0b12019-06-04 16:00:05 +0300555 ret = intel_pt_get_data(decoder, false);
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300556 if (ret) {
557 decoder->pos += old_len;
558 return ret < 0 ? ret : -EINVAL;
559 }
560
561 n = INTEL_PT_PKT_MAX_SZ - len;
562 if (n > decoder->len)
563 n = decoder->len;
564 memcpy(buf + len, decoder->buf, n);
565 len += n;
566
Adrian Hunter4c355952019-06-10 10:27:55 +0300567 decoder->prev_pkt_ctx = decoder->pkt_ctx;
Adrian Hunteredff7802019-06-10 10:27:53 +0300568 ret = intel_pt_get_packet(buf, len, &decoder->packet, &decoder->pkt_ctx);
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300569 if (ret < (int)old_len) {
570 decoder->next_buf = decoder->buf;
571 decoder->next_len = decoder->len;
572 decoder->buf = buf;
573 decoder->len = old_len;
574 return intel_pt_bad_packet(decoder);
575 }
576
577 decoder->next_buf = decoder->buf + (ret - old_len);
578 decoder->next_len = decoder->len - (ret - old_len);
579
580 decoder->buf = buf;
581 decoder->len = ret;
582
583 return ret;
584}
585
Adrian Huntercc336182015-07-17 19:33:57 +0300586struct intel_pt_pkt_info {
587 struct intel_pt_decoder *decoder;
588 struct intel_pt_pkt packet;
589 uint64_t pos;
590 int pkt_len;
591 int last_packet_type;
592 void *data;
593};
594
595typedef int (*intel_pt_pkt_cb_t)(struct intel_pt_pkt_info *pkt_info);
596
597/* Lookahead packets in current buffer */
598static int intel_pt_pkt_lookahead(struct intel_pt_decoder *decoder,
599 intel_pt_pkt_cb_t cb, void *data)
600{
601 struct intel_pt_pkt_info pkt_info;
602 const unsigned char *buf = decoder->buf;
Adrian Hunteredff7802019-06-10 10:27:53 +0300603 enum intel_pt_pkt_ctx pkt_ctx = decoder->pkt_ctx;
Adrian Huntercc336182015-07-17 19:33:57 +0300604 size_t len = decoder->len;
605 int ret;
606
607 pkt_info.decoder = decoder;
608 pkt_info.pos = decoder->pos;
609 pkt_info.pkt_len = decoder->pkt_step;
610 pkt_info.last_packet_type = decoder->last_packet_type;
611 pkt_info.data = data;
612
613 while (1) {
614 do {
615 pkt_info.pos += pkt_info.pkt_len;
616 buf += pkt_info.pkt_len;
617 len -= pkt_info.pkt_len;
618
619 if (!len)
620 return INTEL_PT_NEED_MORE_BYTES;
621
Adrian Hunteredff7802019-06-10 10:27:53 +0300622 ret = intel_pt_get_packet(buf, len, &pkt_info.packet,
623 &pkt_ctx);
Adrian Huntercc336182015-07-17 19:33:57 +0300624 if (!ret)
625 return INTEL_PT_NEED_MORE_BYTES;
626 if (ret < 0)
627 return ret;
628
629 pkt_info.pkt_len = ret;
630 } while (pkt_info.packet.type == INTEL_PT_PAD);
631
632 ret = cb(&pkt_info);
633 if (ret)
634 return 0;
635
636 pkt_info.last_packet_type = pkt_info.packet.type;
637 }
638}
639
640struct intel_pt_calc_cyc_to_tsc_info {
641 uint64_t cycle_cnt;
642 unsigned int cbr;
643 uint32_t last_mtc;
644 uint64_t ctc_timestamp;
645 uint64_t ctc_delta;
646 uint64_t tsc_timestamp;
647 uint64_t timestamp;
648 bool have_tma;
Adrian Hunter3bccbe22016-09-28 14:41:36 +0300649 bool fixup_last_mtc;
Adrian Huntercc336182015-07-17 19:33:57 +0300650 bool from_mtc;
651 double cbr_cyc_to_tsc;
652};
653
Adrian Hunter3bccbe22016-09-28 14:41:36 +0300654/*
655 * MTC provides a 8-bit slice of CTC but the TMA packet only provides the lower
656 * 16 bits of CTC. If mtc_shift > 8 then some of the MTC bits are not in the CTC
657 * provided by the TMA packet. Fix-up the last_mtc calculated from the TMA
658 * packet by copying the missing bits from the current MTC assuming the least
659 * difference between the two, and that the current MTC comes after last_mtc.
660 */
661static void intel_pt_fixup_last_mtc(uint32_t mtc, int mtc_shift,
662 uint32_t *last_mtc)
663{
664 uint32_t first_missing_bit = 1U << (16 - mtc_shift);
665 uint32_t mask = ~(first_missing_bit - 1);
666
667 *last_mtc |= mtc & mask;
668 if (*last_mtc >= mtc) {
669 *last_mtc -= first_missing_bit;
670 *last_mtc &= 0xff;
671 }
672}
673
Adrian Huntercc336182015-07-17 19:33:57 +0300674static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
675{
676 struct intel_pt_decoder *decoder = pkt_info->decoder;
677 struct intel_pt_calc_cyc_to_tsc_info *data = pkt_info->data;
678 uint64_t timestamp;
679 double cyc_to_tsc;
680 unsigned int cbr;
681 uint32_t mtc, mtc_delta, ctc, fc, ctc_rem;
682
683 switch (pkt_info->packet.type) {
684 case INTEL_PT_TNT:
685 case INTEL_PT_TIP_PGE:
686 case INTEL_PT_TIP:
687 case INTEL_PT_FUP:
688 case INTEL_PT_PSB:
689 case INTEL_PT_PIP:
690 case INTEL_PT_MODE_EXEC:
691 case INTEL_PT_MODE_TSX:
692 case INTEL_PT_PSBEND:
693 case INTEL_PT_PAD:
694 case INTEL_PT_VMCS:
695 case INTEL_PT_MNT:
Adrian Huntera472e652017-05-26 11:17:14 +0300696 case INTEL_PT_PTWRITE:
697 case INTEL_PT_PTWRITE_IP:
Adrian Hunteredff7802019-06-10 10:27:53 +0300698 case INTEL_PT_BBP:
699 case INTEL_PT_BIP:
700 case INTEL_PT_BEP:
701 case INTEL_PT_BEP_IP:
Adrian Huntercc336182015-07-17 19:33:57 +0300702 return 0;
703
704 case INTEL_PT_MTC:
705 if (!data->have_tma)
706 return 0;
707
708 mtc = pkt_info->packet.payload;
Adrian Hunter3bccbe22016-09-28 14:41:36 +0300709 if (decoder->mtc_shift > 8 && data->fixup_last_mtc) {
710 data->fixup_last_mtc = false;
711 intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
712 &data->last_mtc);
713 }
Adrian Huntercc336182015-07-17 19:33:57 +0300714 if (mtc > data->last_mtc)
715 mtc_delta = mtc - data->last_mtc;
716 else
717 mtc_delta = mtc + 256 - data->last_mtc;
718 data->ctc_delta += mtc_delta << decoder->mtc_shift;
719 data->last_mtc = mtc;
720
721 if (decoder->tsc_ctc_mult) {
722 timestamp = data->ctc_timestamp +
723 data->ctc_delta * decoder->tsc_ctc_mult;
724 } else {
725 timestamp = data->ctc_timestamp +
726 multdiv(data->ctc_delta,
727 decoder->tsc_ctc_ratio_n,
728 decoder->tsc_ctc_ratio_d);
729 }
730
731 if (timestamp < data->timestamp)
732 return 1;
733
734 if (pkt_info->last_packet_type != INTEL_PT_CYC) {
735 data->timestamp = timestamp;
736 return 0;
737 }
738
739 break;
740
741 case INTEL_PT_TSC:
Adrian Hunter38b65b02017-05-26 11:17:37 +0300742 /*
743 * For now, do not support using TSC packets - refer
744 * intel_pt_calc_cyc_to_tsc().
745 */
746 if (data->from_mtc)
747 return 1;
Adrian Huntercc336182015-07-17 19:33:57 +0300748 timestamp = pkt_info->packet.payload |
749 (data->timestamp & (0xffULL << 56));
750 if (data->from_mtc && timestamp < data->timestamp &&
751 data->timestamp - timestamp < decoder->tsc_slip)
752 return 1;
Adrian Hunter9992c2d2015-09-25 16:15:34 +0300753 if (timestamp < data->timestamp)
Adrian Huntercc336182015-07-17 19:33:57 +0300754 timestamp += (1ULL << 56);
755 if (pkt_info->last_packet_type != INTEL_PT_CYC) {
756 if (data->from_mtc)
757 return 1;
758 data->tsc_timestamp = timestamp;
759 data->timestamp = timestamp;
760 return 0;
761 }
762 break;
763
764 case INTEL_PT_TMA:
765 if (data->from_mtc)
766 return 1;
767
768 if (!decoder->tsc_ctc_ratio_d)
769 return 0;
770
771 ctc = pkt_info->packet.payload;
772 fc = pkt_info->packet.count;
773 ctc_rem = ctc & decoder->ctc_rem_mask;
774
775 data->last_mtc = (ctc >> decoder->mtc_shift) & 0xff;
776
777 data->ctc_timestamp = data->tsc_timestamp - fc;
778 if (decoder->tsc_ctc_mult) {
779 data->ctc_timestamp -= ctc_rem * decoder->tsc_ctc_mult;
780 } else {
781 data->ctc_timestamp -=
782 multdiv(ctc_rem, decoder->tsc_ctc_ratio_n,
783 decoder->tsc_ctc_ratio_d);
784 }
785
786 data->ctc_delta = 0;
787 data->have_tma = true;
Adrian Hunter3bccbe22016-09-28 14:41:36 +0300788 data->fixup_last_mtc = true;
Adrian Huntercc336182015-07-17 19:33:57 +0300789
790 return 0;
791
792 case INTEL_PT_CYC:
793 data->cycle_cnt += pkt_info->packet.payload;
794 return 0;
795
796 case INTEL_PT_CBR:
797 cbr = pkt_info->packet.payload;
798 if (data->cbr && data->cbr != cbr)
799 return 1;
800 data->cbr = cbr;
801 data->cbr_cyc_to_tsc = decoder->max_non_turbo_ratio_fp / cbr;
802 return 0;
803
804 case INTEL_PT_TIP_PGD:
805 case INTEL_PT_TRACESTOP:
Adrian Huntera472e652017-05-26 11:17:14 +0300806 case INTEL_PT_EXSTOP:
807 case INTEL_PT_EXSTOP_IP:
808 case INTEL_PT_MWAIT:
809 case INTEL_PT_PWRE:
810 case INTEL_PT_PWRX:
Adrian Huntercc336182015-07-17 19:33:57 +0300811 case INTEL_PT_OVF:
812 case INTEL_PT_BAD: /* Does not happen */
813 default:
814 return 1;
815 }
816
817 if (!data->cbr && decoder->cbr) {
818 data->cbr = decoder->cbr;
819 data->cbr_cyc_to_tsc = decoder->cbr_cyc_to_tsc;
820 }
821
822 if (!data->cycle_cnt)
823 return 1;
824
825 cyc_to_tsc = (double)(timestamp - decoder->timestamp) / data->cycle_cnt;
826
827 if (data->cbr && cyc_to_tsc > data->cbr_cyc_to_tsc &&
828 cyc_to_tsc / data->cbr_cyc_to_tsc > 1.25) {
829 intel_pt_log("Timestamp: calculated %g TSC ticks per cycle too big (c.f. CBR-based value %g), pos " x64_fmt "\n",
830 cyc_to_tsc, data->cbr_cyc_to_tsc, pkt_info->pos);
831 return 1;
832 }
833
834 decoder->calc_cyc_to_tsc = cyc_to_tsc;
835 decoder->have_calc_cyc_to_tsc = true;
836
837 if (data->cbr) {
838 intel_pt_log("Timestamp: calculated %g TSC ticks per cycle c.f. CBR-based value %g, pos " x64_fmt "\n",
839 cyc_to_tsc, data->cbr_cyc_to_tsc, pkt_info->pos);
840 } else {
841 intel_pt_log("Timestamp: calculated %g TSC ticks per cycle c.f. unknown CBR-based value, pos " x64_fmt "\n",
842 cyc_to_tsc, pkt_info->pos);
843 }
844
845 return 1;
846}
847
848static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder,
849 bool from_mtc)
850{
851 struct intel_pt_calc_cyc_to_tsc_info data = {
852 .cycle_cnt = 0,
853 .cbr = 0,
854 .last_mtc = decoder->last_mtc,
855 .ctc_timestamp = decoder->ctc_timestamp,
856 .ctc_delta = decoder->ctc_delta,
857 .tsc_timestamp = decoder->tsc_timestamp,
858 .timestamp = decoder->timestamp,
859 .have_tma = decoder->have_tma,
Adrian Hunter3bccbe22016-09-28 14:41:36 +0300860 .fixup_last_mtc = decoder->fixup_last_mtc,
Adrian Huntercc336182015-07-17 19:33:57 +0300861 .from_mtc = from_mtc,
862 .cbr_cyc_to_tsc = 0,
863 };
864
Adrian Hunter38b65b02017-05-26 11:17:37 +0300865 /*
866 * For now, do not support using TSC packets for at least the reasons:
867 * 1) timing might have stopped
868 * 2) TSC packets within PSB+ can slip against CYC packets
869 */
870 if (!from_mtc)
871 return;
872
Adrian Huntercc336182015-07-17 19:33:57 +0300873 intel_pt_pkt_lookahead(decoder, intel_pt_calc_cyc_cb, &data);
874}
875
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300876static int intel_pt_get_next_packet(struct intel_pt_decoder *decoder)
877{
878 int ret;
879
Adrian Huntercc336182015-07-17 19:33:57 +0300880 decoder->last_packet_type = decoder->packet.type;
881
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300882 do {
883 decoder->pos += decoder->pkt_step;
884 decoder->buf += decoder->pkt_step;
885 decoder->len -= decoder->pkt_step;
886
887 if (!decoder->len) {
Adrian Hunter6c1f0b12019-06-04 16:00:05 +0300888 ret = intel_pt_get_next_data(decoder, false);
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300889 if (ret)
890 return ret;
891 }
892
Adrian Hunter4c355952019-06-10 10:27:55 +0300893 decoder->prev_pkt_ctx = decoder->pkt_ctx;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300894 ret = intel_pt_get_packet(decoder->buf, decoder->len,
Adrian Hunteredff7802019-06-10 10:27:53 +0300895 &decoder->packet, &decoder->pkt_ctx);
Adrian Hunter26ee2bc2019-02-06 12:39:46 +0200896 if (ret == INTEL_PT_NEED_MORE_BYTES && BITS_PER_LONG == 32 &&
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300897 decoder->len < INTEL_PT_PKT_MAX_SZ && !decoder->next_buf) {
898 ret = intel_pt_get_split_packet(decoder);
899 if (ret < 0)
900 return ret;
901 }
902 if (ret <= 0)
903 return intel_pt_bad_packet(decoder);
904
905 decoder->pkt_len = ret;
906 decoder->pkt_step = ret;
907 intel_pt_decoder_log_packet(decoder);
908 } while (decoder->packet.type == INTEL_PT_PAD);
909
910 return 0;
911}
912
913static uint64_t intel_pt_next_period(struct intel_pt_decoder *decoder)
914{
915 uint64_t timestamp, masked_timestamp;
916
917 timestamp = decoder->timestamp + decoder->timestamp_insn_cnt;
918 masked_timestamp = timestamp & decoder->period_mask;
919 if (decoder->continuous_period) {
Adrian Hunter7ba8fa22019-05-10 15:41:41 +0300920 if (masked_timestamp > decoder->last_masked_timestamp)
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300921 return 1;
922 } else {
923 timestamp += 1;
924 masked_timestamp = timestamp & decoder->period_mask;
Adrian Hunter7ba8fa22019-05-10 15:41:41 +0300925 if (masked_timestamp > decoder->last_masked_timestamp) {
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300926 decoder->last_masked_timestamp = masked_timestamp;
927 decoder->continuous_period = true;
928 }
929 }
Adrian Hunter7ba8fa22019-05-10 15:41:41 +0300930
931 if (masked_timestamp < decoder->last_masked_timestamp)
932 return decoder->period_ticks;
933
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300934 return decoder->period_ticks - (timestamp - masked_timestamp);
935}
936
937static uint64_t intel_pt_next_sample(struct intel_pt_decoder *decoder)
938{
939 switch (decoder->period_type) {
940 case INTEL_PT_PERIOD_INSTRUCTIONS:
941 return decoder->period - decoder->period_insn_cnt;
942 case INTEL_PT_PERIOD_TICKS:
943 return intel_pt_next_period(decoder);
944 case INTEL_PT_PERIOD_NONE:
Adrian Hunter79b58422015-07-17 19:33:55 +0300945 case INTEL_PT_PERIOD_MTC:
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300946 default:
947 return 0;
948 }
949}
950
951static void intel_pt_sample_insn(struct intel_pt_decoder *decoder)
952{
953 uint64_t timestamp, masked_timestamp;
954
955 switch (decoder->period_type) {
956 case INTEL_PT_PERIOD_INSTRUCTIONS:
957 decoder->period_insn_cnt = 0;
958 break;
959 case INTEL_PT_PERIOD_TICKS:
960 timestamp = decoder->timestamp + decoder->timestamp_insn_cnt;
961 masked_timestamp = timestamp & decoder->period_mask;
Adrian Hunter7ba8fa22019-05-10 15:41:41 +0300962 if (masked_timestamp > decoder->last_masked_timestamp)
963 decoder->last_masked_timestamp = masked_timestamp;
964 else
965 decoder->last_masked_timestamp += decoder->period_ticks;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300966 break;
967 case INTEL_PT_PERIOD_NONE:
Adrian Hunter79b58422015-07-17 19:33:55 +0300968 case INTEL_PT_PERIOD_MTC:
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300969 default:
970 break;
971 }
972
973 decoder->state.type |= INTEL_PT_INSTRUCTION;
974}
975
976static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
977 struct intel_pt_insn *intel_pt_insn, uint64_t ip)
978{
979 uint64_t max_insn_cnt, insn_cnt = 0;
980 int err;
981
Adrian Hunter79b58422015-07-17 19:33:55 +0300982 if (!decoder->mtc_insn)
983 decoder->mtc_insn = true;
984
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300985 max_insn_cnt = intel_pt_next_sample(decoder);
986
987 err = decoder->walk_insn(intel_pt_insn, &insn_cnt, &decoder->ip, ip,
988 max_insn_cnt, decoder->data);
989
Adrian Hunter2a21d032015-07-17 19:33:48 +0300990 decoder->tot_insn_cnt += insn_cnt;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300991 decoder->timestamp_insn_cnt += insn_cnt;
Adrian Hunter3f04d982017-05-26 11:17:03 +0300992 decoder->sample_insn_cnt += insn_cnt;
Adrian Hunterf4aa0812015-07-17 19:33:40 +0300993 decoder->period_insn_cnt += insn_cnt;
994
995 if (err) {
996 decoder->no_progress = 0;
997 decoder->pkt_state = INTEL_PT_STATE_ERR2;
998 intel_pt_log_at("ERROR: Failed to get instruction",
999 decoder->ip);
1000 if (err == -ENOENT)
1001 return -ENOLINK;
1002 return -EILSEQ;
1003 }
1004
1005 if (ip && decoder->ip == ip) {
1006 err = -EAGAIN;
1007 goto out;
1008 }
1009
1010 if (max_insn_cnt && insn_cnt >= max_insn_cnt)
1011 intel_pt_sample_insn(decoder);
1012
1013 if (intel_pt_insn->branch == INTEL_PT_BR_NO_BRANCH) {
1014 decoder->state.type = INTEL_PT_INSTRUCTION;
1015 decoder->state.from_ip = decoder->ip;
1016 decoder->state.to_ip = 0;
1017 decoder->ip += intel_pt_insn->length;
1018 err = INTEL_PT_RETURN;
1019 goto out;
1020 }
1021
1022 if (intel_pt_insn->op == INTEL_PT_OP_CALL) {
1023 /* Zero-length calls are excluded */
1024 if (intel_pt_insn->branch != INTEL_PT_BR_UNCONDITIONAL ||
1025 intel_pt_insn->rel) {
1026 err = intel_pt_push(&decoder->stack, decoder->ip +
1027 intel_pt_insn->length);
1028 if (err)
1029 goto out;
1030 }
1031 } else if (intel_pt_insn->op == INTEL_PT_OP_RET) {
1032 decoder->ret_addr = intel_pt_pop(&decoder->stack);
1033 }
1034
1035 if (intel_pt_insn->branch == INTEL_PT_BR_UNCONDITIONAL) {
1036 int cnt = decoder->no_progress++;
1037
1038 decoder->state.from_ip = decoder->ip;
1039 decoder->ip += intel_pt_insn->length +
1040 intel_pt_insn->rel;
1041 decoder->state.to_ip = decoder->ip;
1042 err = INTEL_PT_RETURN;
1043
1044 /*
1045 * Check for being stuck in a loop. This can happen if a
1046 * decoder error results in the decoder erroneously setting the
1047 * ip to an address that is itself in an infinite loop that
1048 * consumes no packets. When that happens, there must be an
1049 * unconditional branch.
1050 */
1051 if (cnt) {
1052 if (cnt == 1) {
1053 decoder->stuck_ip = decoder->state.to_ip;
1054 decoder->stuck_ip_prd = 1;
1055 decoder->stuck_ip_cnt = 1;
1056 } else if (cnt > INTEL_PT_MAX_LOOPS ||
1057 decoder->state.to_ip == decoder->stuck_ip) {
1058 intel_pt_log_at("ERROR: Never-ending loop",
1059 decoder->state.to_ip);
1060 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
1061 err = -ELOOP;
1062 goto out;
1063 } else if (!--decoder->stuck_ip_cnt) {
1064 decoder->stuck_ip_prd += 1;
1065 decoder->stuck_ip_cnt = decoder->stuck_ip_prd;
1066 decoder->stuck_ip = decoder->state.to_ip;
1067 }
1068 }
1069 goto out_no_progress;
1070 }
1071out:
1072 decoder->no_progress = 0;
1073out_no_progress:
1074 decoder->state.insn_op = intel_pt_insn->op;
1075 decoder->state.insn_len = intel_pt_insn->length;
Andi Kleenfaaa8762016-10-07 16:42:26 +03001076 memcpy(decoder->state.insn, intel_pt_insn->buf,
1077 INTEL_PT_INSN_BUF_SZ);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001078
1079 if (decoder->tx_flags & INTEL_PT_IN_TX)
1080 decoder->state.flags |= INTEL_PT_IN_TX;
1081
1082 return err;
1083}
1084
Adrian Huntera472e652017-05-26 11:17:14 +03001085static bool intel_pt_fup_event(struct intel_pt_decoder *decoder)
1086{
1087 bool ret = false;
1088
1089 if (decoder->set_fup_tx_flags) {
1090 decoder->set_fup_tx_flags = false;
1091 decoder->tx_flags = decoder->fup_tx_flags;
1092 decoder->state.type = INTEL_PT_TRANSACTION;
1093 decoder->state.from_ip = decoder->ip;
1094 decoder->state.to_ip = 0;
1095 decoder->state.flags = decoder->fup_tx_flags;
1096 return true;
1097 }
1098 if (decoder->set_fup_ptw) {
1099 decoder->set_fup_ptw = false;
1100 decoder->state.type = INTEL_PT_PTW;
1101 decoder->state.flags |= INTEL_PT_FUP_IP;
1102 decoder->state.from_ip = decoder->ip;
1103 decoder->state.to_ip = 0;
1104 decoder->state.ptw_payload = decoder->fup_ptw_payload;
1105 return true;
1106 }
1107 if (decoder->set_fup_mwait) {
1108 decoder->set_fup_mwait = false;
1109 decoder->state.type = INTEL_PT_MWAIT_OP;
1110 decoder->state.from_ip = decoder->ip;
1111 decoder->state.to_ip = 0;
1112 decoder->state.mwait_payload = decoder->fup_mwait_payload;
1113 ret = true;
1114 }
1115 if (decoder->set_fup_pwre) {
1116 decoder->set_fup_pwre = false;
1117 decoder->state.type |= INTEL_PT_PWR_ENTRY;
1118 decoder->state.type &= ~INTEL_PT_BRANCH;
1119 decoder->state.from_ip = decoder->ip;
1120 decoder->state.to_ip = 0;
1121 decoder->state.pwre_payload = decoder->fup_pwre_payload;
1122 ret = true;
1123 }
1124 if (decoder->set_fup_exstop) {
1125 decoder->set_fup_exstop = false;
1126 decoder->state.type |= INTEL_PT_EX_STOP;
1127 decoder->state.type &= ~INTEL_PT_BRANCH;
1128 decoder->state.flags |= INTEL_PT_FUP_IP;
1129 decoder->state.from_ip = decoder->ip;
1130 decoder->state.to_ip = 0;
1131 ret = true;
1132 }
Adrian Hunter4c355952019-06-10 10:27:55 +03001133 if (decoder->set_fup_bep) {
1134 decoder->set_fup_bep = false;
1135 decoder->state.type |= INTEL_PT_BLK_ITEMS;
1136 decoder->state.type &= ~INTEL_PT_BRANCH;
1137 decoder->state.from_ip = decoder->ip;
1138 decoder->state.to_ip = 0;
1139 ret = true;
1140 }
Adrian Huntera472e652017-05-26 11:17:14 +03001141 return ret;
1142}
1143
Adrian Hunter9fb52332018-05-31 13:23:45 +03001144static inline bool intel_pt_fup_with_nlip(struct intel_pt_decoder *decoder,
1145 struct intel_pt_insn *intel_pt_insn,
1146 uint64_t ip, int err)
1147{
1148 return decoder->flags & INTEL_PT_FUP_WITH_NLIP && !err &&
1149 intel_pt_insn->branch == INTEL_PT_BR_INDIRECT &&
1150 ip == decoder->ip + intel_pt_insn->length;
1151}
1152
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001153static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
1154{
1155 struct intel_pt_insn intel_pt_insn;
1156 uint64_t ip;
1157 int err;
1158
1159 ip = decoder->last_ip;
1160
1161 while (1) {
1162 err = intel_pt_walk_insn(decoder, &intel_pt_insn, ip);
1163 if (err == INTEL_PT_RETURN)
1164 return 0;
Adrian Hunter9fb52332018-05-31 13:23:45 +03001165 if (err == -EAGAIN ||
1166 intel_pt_fup_with_nlip(decoder, &intel_pt_insn, ip, err)) {
Adrian Hunter401136b2020-07-10 18:10:53 +03001167 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
Adrian Huntera472e652017-05-26 11:17:14 +03001168 if (intel_pt_fup_event(decoder))
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001169 return 0;
Adrian Hunter9fb52332018-05-31 13:23:45 +03001170 return -EAGAIN;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001171 }
1172 decoder->set_fup_tx_flags = false;
1173 if (err)
1174 return err;
1175
1176 if (intel_pt_insn.branch == INTEL_PT_BR_INDIRECT) {
1177 intel_pt_log_at("ERROR: Unexpected indirect branch",
1178 decoder->ip);
1179 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
1180 return -ENOENT;
1181 }
1182
1183 if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) {
1184 intel_pt_log_at("ERROR: Unexpected conditional branch",
1185 decoder->ip);
1186 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
1187 return -ENOENT;
1188 }
1189
1190 intel_pt_bug(decoder);
1191 }
1192}
1193
1194static int intel_pt_walk_tip(struct intel_pt_decoder *decoder)
1195{
1196 struct intel_pt_insn intel_pt_insn;
1197 int err;
1198
1199 err = intel_pt_walk_insn(decoder, &intel_pt_insn, 0);
Adrian Hunter9f1d1222016-09-23 17:38:47 +03001200 if (err == INTEL_PT_RETURN &&
1201 decoder->pgd_ip &&
1202 decoder->pkt_state == INTEL_PT_STATE_TIP_PGD &&
1203 (decoder->state.type & INTEL_PT_BRANCH) &&
1204 decoder->pgd_ip(decoder->state.to_ip, decoder->data)) {
1205 /* Unconditional branch leaving filter region */
1206 decoder->no_progress = 0;
1207 decoder->pge = false;
1208 decoder->continuous_period = false;
1209 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
Adrian Hunterbea63852018-09-20 16:00:48 +03001210 decoder->state.type |= INTEL_PT_TRACE_END;
Adrian Hunter9f1d1222016-09-23 17:38:47 +03001211 return 0;
1212 }
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001213 if (err == INTEL_PT_RETURN)
1214 return 0;
1215 if (err)
1216 return err;
1217
1218 if (intel_pt_insn.branch == INTEL_PT_BR_INDIRECT) {
1219 if (decoder->pkt_state == INTEL_PT_STATE_TIP_PGD) {
1220 decoder->pge = false;
1221 decoder->continuous_period = false;
1222 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1223 decoder->state.from_ip = decoder->ip;
Adrian Hunterbea63852018-09-20 16:00:48 +03001224 if (decoder->packet.count == 0) {
1225 decoder->state.to_ip = 0;
1226 } else {
1227 decoder->state.to_ip = decoder->last_ip;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001228 decoder->ip = decoder->last_ip;
Adrian Hunterbea63852018-09-20 16:00:48 +03001229 }
1230 decoder->state.type |= INTEL_PT_TRACE_END;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001231 } else {
1232 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1233 decoder->state.from_ip = decoder->ip;
1234 if (decoder->packet.count == 0) {
1235 decoder->state.to_ip = 0;
1236 } else {
1237 decoder->state.to_ip = decoder->last_ip;
1238 decoder->ip = decoder->last_ip;
1239 }
1240 }
1241 return 0;
1242 }
1243
1244 if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) {
Adrian Hunter9f1d1222016-09-23 17:38:47 +03001245 uint64_t to_ip = decoder->ip + intel_pt_insn.length +
1246 intel_pt_insn.rel;
1247
1248 if (decoder->pgd_ip &&
1249 decoder->pkt_state == INTEL_PT_STATE_TIP_PGD &&
1250 decoder->pgd_ip(to_ip, decoder->data)) {
1251 /* Conditional branch leaving filter region */
1252 decoder->pge = false;
1253 decoder->continuous_period = false;
1254 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1255 decoder->ip = to_ip;
1256 decoder->state.from_ip = decoder->ip;
Adrian Hunterbea63852018-09-20 16:00:48 +03001257 decoder->state.to_ip = to_ip;
1258 decoder->state.type |= INTEL_PT_TRACE_END;
Adrian Hunter9f1d1222016-09-23 17:38:47 +03001259 return 0;
1260 }
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001261 intel_pt_log_at("ERROR: Conditional branch when expecting indirect branch",
1262 decoder->ip);
1263 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
1264 return -ENOENT;
1265 }
1266
1267 return intel_pt_bug(decoder);
1268}
1269
1270static int intel_pt_walk_tnt(struct intel_pt_decoder *decoder)
1271{
1272 struct intel_pt_insn intel_pt_insn;
1273 int err;
1274
1275 while (1) {
1276 err = intel_pt_walk_insn(decoder, &intel_pt_insn, 0);
1277 if (err == INTEL_PT_RETURN)
1278 return 0;
1279 if (err)
1280 return err;
1281
1282 if (intel_pt_insn.op == INTEL_PT_OP_RET) {
1283 if (!decoder->return_compression) {
1284 intel_pt_log_at("ERROR: RET when expecting conditional branch",
1285 decoder->ip);
1286 decoder->pkt_state = INTEL_PT_STATE_ERR3;
1287 return -ENOENT;
1288 }
1289 if (!decoder->ret_addr) {
1290 intel_pt_log_at("ERROR: Bad RET compression (stack empty)",
1291 decoder->ip);
1292 decoder->pkt_state = INTEL_PT_STATE_ERR3;
1293 return -ENOENT;
1294 }
1295 if (!(decoder->tnt.payload & BIT63)) {
1296 intel_pt_log_at("ERROR: Bad RET compression (TNT=N)",
1297 decoder->ip);
1298 decoder->pkt_state = INTEL_PT_STATE_ERR3;
1299 return -ENOENT;
1300 }
1301 decoder->tnt.count -= 1;
Adrian Hunter61b6e082019-05-10 15:41:42 +03001302 if (decoder->tnt.count)
1303 decoder->pkt_state = INTEL_PT_STATE_TNT_CONT;
1304 else
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001305 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1306 decoder->tnt.payload <<= 1;
1307 decoder->state.from_ip = decoder->ip;
1308 decoder->ip = decoder->ret_addr;
1309 decoder->state.to_ip = decoder->ip;
1310 return 0;
1311 }
1312
1313 if (intel_pt_insn.branch == INTEL_PT_BR_INDIRECT) {
1314 /* Handle deferred TIPs */
1315 err = intel_pt_get_next_packet(decoder);
1316 if (err)
1317 return err;
1318 if (decoder->packet.type != INTEL_PT_TIP ||
1319 decoder->packet.count == 0) {
1320 intel_pt_log_at("ERROR: Missing deferred TIP for indirect branch",
1321 decoder->ip);
1322 decoder->pkt_state = INTEL_PT_STATE_ERR3;
1323 decoder->pkt_step = 0;
1324 return -ENOENT;
1325 }
1326 intel_pt_set_last_ip(decoder);
1327 decoder->state.from_ip = decoder->ip;
1328 decoder->state.to_ip = decoder->last_ip;
1329 decoder->ip = decoder->last_ip;
1330 return 0;
1331 }
1332
1333 if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) {
1334 decoder->tnt.count -= 1;
Adrian Hunter61b6e082019-05-10 15:41:42 +03001335 if (decoder->tnt.count)
1336 decoder->pkt_state = INTEL_PT_STATE_TNT_CONT;
1337 else
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001338 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1339 if (decoder->tnt.payload & BIT63) {
1340 decoder->tnt.payload <<= 1;
1341 decoder->state.from_ip = decoder->ip;
1342 decoder->ip += intel_pt_insn.length +
1343 intel_pt_insn.rel;
1344 decoder->state.to_ip = decoder->ip;
1345 return 0;
1346 }
1347 /* Instruction sample for a non-taken branch */
1348 if (decoder->state.type & INTEL_PT_INSTRUCTION) {
1349 decoder->tnt.payload <<= 1;
1350 decoder->state.type = INTEL_PT_INSTRUCTION;
1351 decoder->state.from_ip = decoder->ip;
1352 decoder->state.to_ip = 0;
1353 decoder->ip += intel_pt_insn.length;
1354 return 0;
1355 }
Adrian Hunter7b4b4f82019-05-20 14:37:11 +03001356 decoder->sample_cyc = false;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001357 decoder->ip += intel_pt_insn.length;
Adrian Hunter1b6599a2019-05-10 15:41:43 +03001358 if (!decoder->tnt.count) {
Adrian Hunter948e9dc2019-05-20 14:37:10 +03001359 intel_pt_update_sample_time(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001360 return -EAGAIN;
Adrian Hunter1b6599a2019-05-10 15:41:43 +03001361 }
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001362 decoder->tnt.payload <<= 1;
1363 continue;
1364 }
1365
1366 return intel_pt_bug(decoder);
1367 }
1368}
1369
1370static int intel_pt_mode_tsx(struct intel_pt_decoder *decoder, bool *no_tip)
1371{
1372 unsigned int fup_tx_flags;
1373 int err;
1374
1375 fup_tx_flags = decoder->packet.payload &
1376 (INTEL_PT_IN_TX | INTEL_PT_ABORT_TX);
1377 err = intel_pt_get_next_packet(decoder);
1378 if (err)
1379 return err;
1380 if (decoder->packet.type == INTEL_PT_FUP) {
1381 decoder->fup_tx_flags = fup_tx_flags;
1382 decoder->set_fup_tx_flags = true;
1383 if (!(decoder->fup_tx_flags & INTEL_PT_ABORT_TX))
1384 *no_tip = true;
1385 } else {
1386 intel_pt_log_at("ERROR: Missing FUP after MODE.TSX",
1387 decoder->pos);
1388 intel_pt_update_in_tx(decoder);
1389 }
1390 return 0;
1391}
1392
Adrian Huntere72b52a2019-06-04 16:00:03 +03001393static uint64_t intel_pt_8b_tsc(uint64_t timestamp, uint64_t ref_timestamp)
1394{
1395 timestamp |= (ref_timestamp & (0xffULL << 56));
1396
1397 if (timestamp < ref_timestamp) {
1398 if (ref_timestamp - timestamp > (1ULL << 55))
1399 timestamp += (1ULL << 56);
1400 } else {
1401 if (timestamp - ref_timestamp > (1ULL << 55))
1402 timestamp -= (1ULL << 56);
1403 }
1404
1405 return timestamp;
1406}
1407
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001408static void intel_pt_calc_tsc_timestamp(struct intel_pt_decoder *decoder)
1409{
1410 uint64_t timestamp;
1411
Adrian Hunter79b58422015-07-17 19:33:55 +03001412 decoder->have_tma = false;
1413
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001414 if (decoder->ref_timestamp) {
Adrian Huntere72b52a2019-06-04 16:00:03 +03001415 timestamp = intel_pt_8b_tsc(decoder->packet.payload,
1416 decoder->ref_timestamp);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001417 decoder->tsc_timestamp = timestamp;
1418 decoder->timestamp = timestamp;
1419 decoder->ref_timestamp = 0;
1420 decoder->timestamp_insn_cnt = 0;
1421 } else if (decoder->timestamp) {
1422 timestamp = decoder->packet.payload |
1423 (decoder->timestamp & (0xffULL << 56));
Adrian Hunter79b58422015-07-17 19:33:55 +03001424 decoder->tsc_timestamp = timestamp;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001425 if (timestamp < decoder->timestamp &&
Adrian Hunter79b58422015-07-17 19:33:55 +03001426 decoder->timestamp - timestamp < decoder->tsc_slip) {
1427 intel_pt_log_to("Suppressing backwards timestamp",
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001428 timestamp);
1429 timestamp = decoder->timestamp;
1430 }
Adrian Hunter9992c2d2015-09-25 16:15:34 +03001431 if (timestamp < decoder->timestamp) {
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001432 intel_pt_log_to("Wraparound timestamp", timestamp);
1433 timestamp += (1ULL << 56);
Adrian Hunter79b58422015-07-17 19:33:55 +03001434 decoder->tsc_timestamp = timestamp;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001435 }
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001436 decoder->timestamp = timestamp;
1437 decoder->timestamp_insn_cnt = 0;
1438 }
1439
Adrian Huntercc336182015-07-17 19:33:57 +03001440 if (decoder->last_packet_type == INTEL_PT_CYC) {
1441 decoder->cyc_ref_timestamp = decoder->timestamp;
1442 decoder->cycle_cnt = 0;
1443 decoder->have_calc_cyc_to_tsc = false;
1444 intel_pt_calc_cyc_to_tsc(decoder, false);
1445 }
1446
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001447 intel_pt_log_to("Setting timestamp", decoder->timestamp);
1448}
1449
1450static int intel_pt_overflow(struct intel_pt_decoder *decoder)
1451{
1452 intel_pt_log("ERROR: Buffer overflow\n");
1453 intel_pt_clear_tx_flags(decoder);
Adrian Hunter91d29b22018-03-07 16:02:24 +02001454 decoder->timestamp_insn_cnt = 0;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001455 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
1456 decoder->overflow = true;
1457 return -EOVERFLOW;
1458}
1459
Adrian Hunter3f055162019-05-20 14:37:17 +03001460static inline void intel_pt_mtc_cyc_cnt_pge(struct intel_pt_decoder *decoder)
1461{
1462 if (decoder->have_cyc)
1463 return;
1464
1465 decoder->cyc_cnt_timestamp = decoder->timestamp;
1466 decoder->base_cyc_cnt = decoder->tot_cyc_cnt;
1467}
1468
1469static inline void intel_pt_mtc_cyc_cnt_cbr(struct intel_pt_decoder *decoder)
1470{
1471 decoder->tsc_to_cyc = decoder->cbr / decoder->max_non_turbo_ratio_fp;
1472
1473 if (decoder->pge)
1474 intel_pt_mtc_cyc_cnt_pge(decoder);
1475}
1476
1477static inline void intel_pt_mtc_cyc_cnt_upd(struct intel_pt_decoder *decoder)
1478{
1479 uint64_t tot_cyc_cnt, tsc_delta;
1480
1481 if (decoder->have_cyc)
1482 return;
1483
1484 decoder->sample_cyc = true;
1485
1486 if (!decoder->pge || decoder->timestamp <= decoder->cyc_cnt_timestamp)
1487 return;
1488
1489 tsc_delta = decoder->timestamp - decoder->cyc_cnt_timestamp;
1490 tot_cyc_cnt = tsc_delta * decoder->tsc_to_cyc + decoder->base_cyc_cnt;
1491
1492 if (tot_cyc_cnt > decoder->tot_cyc_cnt)
1493 decoder->tot_cyc_cnt = tot_cyc_cnt;
1494}
1495
Adrian Hunter79b58422015-07-17 19:33:55 +03001496static void intel_pt_calc_tma(struct intel_pt_decoder *decoder)
1497{
1498 uint32_t ctc = decoder->packet.payload;
1499 uint32_t fc = decoder->packet.count;
1500 uint32_t ctc_rem = ctc & decoder->ctc_rem_mask;
1501
1502 if (!decoder->tsc_ctc_ratio_d)
1503 return;
1504
Adrian Hunter3f055162019-05-20 14:37:17 +03001505 if (decoder->pge && !decoder->in_psb)
1506 intel_pt_mtc_cyc_cnt_pge(decoder);
1507 else
1508 intel_pt_mtc_cyc_cnt_upd(decoder);
1509
Adrian Hunter79b58422015-07-17 19:33:55 +03001510 decoder->last_mtc = (ctc >> decoder->mtc_shift) & 0xff;
1511 decoder->ctc_timestamp = decoder->tsc_timestamp - fc;
1512 if (decoder->tsc_ctc_mult) {
1513 decoder->ctc_timestamp -= ctc_rem * decoder->tsc_ctc_mult;
1514 } else {
1515 decoder->ctc_timestamp -= multdiv(ctc_rem,
1516 decoder->tsc_ctc_ratio_n,
1517 decoder->tsc_ctc_ratio_d);
1518 }
1519 decoder->ctc_delta = 0;
1520 decoder->have_tma = true;
Adrian Hunter3bccbe22016-09-28 14:41:36 +03001521 decoder->fixup_last_mtc = true;
Adrian Hunter79b58422015-07-17 19:33:55 +03001522 intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x CTC rem %#x\n",
1523 decoder->ctc_timestamp, decoder->last_mtc, ctc_rem);
1524}
1525
1526static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder)
1527{
1528 uint64_t timestamp;
1529 uint32_t mtc, mtc_delta;
1530
1531 if (!decoder->have_tma)
1532 return;
1533
1534 mtc = decoder->packet.payload;
1535
Adrian Hunter3bccbe22016-09-28 14:41:36 +03001536 if (decoder->mtc_shift > 8 && decoder->fixup_last_mtc) {
1537 decoder->fixup_last_mtc = false;
1538 intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
1539 &decoder->last_mtc);
1540 }
1541
Adrian Hunter79b58422015-07-17 19:33:55 +03001542 if (mtc > decoder->last_mtc)
1543 mtc_delta = mtc - decoder->last_mtc;
1544 else
1545 mtc_delta = mtc + 256 - decoder->last_mtc;
1546
1547 decoder->ctc_delta += mtc_delta << decoder->mtc_shift;
1548
1549 if (decoder->tsc_ctc_mult) {
1550 timestamp = decoder->ctc_timestamp +
1551 decoder->ctc_delta * decoder->tsc_ctc_mult;
1552 } else {
1553 timestamp = decoder->ctc_timestamp +
1554 multdiv(decoder->ctc_delta,
1555 decoder->tsc_ctc_ratio_n,
1556 decoder->tsc_ctc_ratio_d);
1557 }
1558
1559 if (timestamp < decoder->timestamp)
1560 intel_pt_log("Suppressing MTC timestamp " x64_fmt " less than current timestamp " x64_fmt "\n",
1561 timestamp, decoder->timestamp);
1562 else
1563 decoder->timestamp = timestamp;
1564
Adrian Hunter3f055162019-05-20 14:37:17 +03001565 intel_pt_mtc_cyc_cnt_upd(decoder);
1566
Adrian Hunter79b58422015-07-17 19:33:55 +03001567 decoder->timestamp_insn_cnt = 0;
1568 decoder->last_mtc = mtc;
Adrian Huntercc336182015-07-17 19:33:57 +03001569
1570 if (decoder->last_packet_type == INTEL_PT_CYC) {
1571 decoder->cyc_ref_timestamp = decoder->timestamp;
1572 decoder->cycle_cnt = 0;
1573 decoder->have_calc_cyc_to_tsc = false;
1574 intel_pt_calc_cyc_to_tsc(decoder, true);
1575 }
Adrian Hunterf6c23e32018-11-05 09:35:05 +02001576
1577 intel_pt_log_to("Setting timestamp", decoder->timestamp);
Adrian Huntercc336182015-07-17 19:33:57 +03001578}
1579
1580static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder)
1581{
Adrian Hunter26fb2fb2017-05-26 11:17:15 +03001582 unsigned int cbr = decoder->packet.payload & 0xff;
Adrian Huntercc336182015-07-17 19:33:57 +03001583
Adrian Hunter0a7c700d2017-05-26 11:17:16 +03001584 decoder->cbr_payload = decoder->packet.payload;
1585
Adrian Huntercc336182015-07-17 19:33:57 +03001586 if (decoder->cbr == cbr)
1587 return;
1588
1589 decoder->cbr = cbr;
1590 decoder->cbr_cyc_to_tsc = decoder->max_non_turbo_ratio_fp / cbr;
Adrian Hunter3f055162019-05-20 14:37:17 +03001591
1592 intel_pt_mtc_cyc_cnt_cbr(decoder);
Adrian Huntercc336182015-07-17 19:33:57 +03001593}
1594
1595static void intel_pt_calc_cyc_timestamp(struct intel_pt_decoder *decoder)
1596{
1597 uint64_t timestamp = decoder->cyc_ref_timestamp;
1598
1599 decoder->have_cyc = true;
1600
1601 decoder->cycle_cnt += decoder->packet.payload;
Adrian Hunter7b4b4f82019-05-20 14:37:11 +03001602 if (decoder->pge)
1603 decoder->tot_cyc_cnt += decoder->packet.payload;
1604 decoder->sample_cyc = true;
Adrian Huntercc336182015-07-17 19:33:57 +03001605
1606 if (!decoder->cyc_ref_timestamp)
1607 return;
1608
1609 if (decoder->have_calc_cyc_to_tsc)
1610 timestamp += decoder->cycle_cnt * decoder->calc_cyc_to_tsc;
1611 else if (decoder->cbr)
1612 timestamp += decoder->cycle_cnt * decoder->cbr_cyc_to_tsc;
1613 else
1614 return;
1615
1616 if (timestamp < decoder->timestamp)
1617 intel_pt_log("Suppressing CYC timestamp " x64_fmt " less than current timestamp " x64_fmt "\n",
1618 timestamp, decoder->timestamp);
1619 else
1620 decoder->timestamp = timestamp;
Adrian Hunter51ee6482016-09-28 14:41:35 +03001621
1622 decoder->timestamp_insn_cnt = 0;
Adrian Hunterf6c23e32018-11-05 09:35:05 +02001623
1624 intel_pt_log_to("Setting timestamp", decoder->timestamp);
Adrian Hunter79b58422015-07-17 19:33:55 +03001625}
1626
Adrian Hunter4c355952019-06-10 10:27:55 +03001627static void intel_pt_bbp(struct intel_pt_decoder *decoder)
1628{
1629 if (decoder->prev_pkt_ctx == INTEL_PT_NO_CTX) {
1630 memset(decoder->state.items.mask, 0, sizeof(decoder->state.items.mask));
1631 decoder->state.items.is_32_bit = false;
1632 }
1633 decoder->blk_type = decoder->packet.payload;
1634 decoder->blk_type_pos = intel_pt_blk_type_pos(decoder->blk_type);
1635 if (decoder->blk_type == INTEL_PT_GP_REGS)
1636 decoder->state.items.is_32_bit = decoder->packet.count;
1637 if (decoder->blk_type_pos < 0) {
1638 intel_pt_log("WARNING: Unknown block type %u\n",
1639 decoder->blk_type);
1640 } else if (decoder->state.items.mask[decoder->blk_type_pos]) {
1641 intel_pt_log("WARNING: Duplicate block type %u\n",
1642 decoder->blk_type);
1643 }
1644}
1645
1646static void intel_pt_bip(struct intel_pt_decoder *decoder)
1647{
1648 uint32_t id = decoder->packet.count;
1649 uint32_t bit = 1 << id;
1650 int pos = decoder->blk_type_pos;
1651
1652 if (pos < 0 || id >= INTEL_PT_BLK_ITEM_ID_CNT) {
1653 intel_pt_log("WARNING: Unknown block item %u type %d\n",
1654 id, decoder->blk_type);
1655 return;
1656 }
1657
1658 if (decoder->state.items.mask[pos] & bit) {
1659 intel_pt_log("WARNING: Duplicate block item %u type %d\n",
1660 id, decoder->blk_type);
1661 }
1662
1663 decoder->state.items.mask[pos] |= bit;
1664 decoder->state.items.val[pos][id] = decoder->packet.payload;
1665}
1666
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001667/* Walk PSB+ packets when already in sync. */
1668static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
1669{
1670 int err;
1671
Adrian Hunter9bc668e2019-05-20 14:37:15 +03001672 decoder->in_psb = true;
1673
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001674 while (1) {
1675 err = intel_pt_get_next_packet(decoder);
1676 if (err)
Adrian Hunter9bc668e2019-05-20 14:37:15 +03001677 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001678
1679 switch (decoder->packet.type) {
1680 case INTEL_PT_PSBEND:
Adrian Hunter9bc668e2019-05-20 14:37:15 +03001681 err = 0;
1682 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001683
1684 case INTEL_PT_TIP_PGD:
1685 case INTEL_PT_TIP_PGE:
1686 case INTEL_PT_TIP:
1687 case INTEL_PT_TNT:
Adrian Hunter3d498072015-07-17 19:33:53 +03001688 case INTEL_PT_TRACESTOP:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001689 case INTEL_PT_BAD:
1690 case INTEL_PT_PSB:
Adrian Huntera472e652017-05-26 11:17:14 +03001691 case INTEL_PT_PTWRITE:
1692 case INTEL_PT_PTWRITE_IP:
1693 case INTEL_PT_EXSTOP:
1694 case INTEL_PT_EXSTOP_IP:
1695 case INTEL_PT_MWAIT:
1696 case INTEL_PT_PWRE:
1697 case INTEL_PT_PWRX:
Adrian Hunteredff7802019-06-10 10:27:53 +03001698 case INTEL_PT_BBP:
1699 case INTEL_PT_BIP:
1700 case INTEL_PT_BEP:
1701 case INTEL_PT_BEP_IP:
Adrian Hunter79b58422015-07-17 19:33:55 +03001702 decoder->have_tma = false;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001703 intel_pt_log("ERROR: Unexpected packet\n");
Adrian Hunter9bc668e2019-05-20 14:37:15 +03001704 err = -EAGAIN;
1705 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001706
1707 case INTEL_PT_OVF:
Adrian Hunter9bc668e2019-05-20 14:37:15 +03001708 err = intel_pt_overflow(decoder);
1709 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001710
1711 case INTEL_PT_TSC:
1712 intel_pt_calc_tsc_timestamp(decoder);
1713 break;
1714
Adrian Hunter3d498072015-07-17 19:33:53 +03001715 case INTEL_PT_TMA:
Adrian Hunter79b58422015-07-17 19:33:55 +03001716 intel_pt_calc_tma(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03001717 break;
1718
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001719 case INTEL_PT_CBR:
Adrian Huntercc336182015-07-17 19:33:57 +03001720 intel_pt_calc_cbr(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001721 break;
1722
1723 case INTEL_PT_MODE_EXEC:
1724 decoder->exec_mode = decoder->packet.payload;
1725 break;
1726
1727 case INTEL_PT_PIP:
Adrian Hunter3d498072015-07-17 19:33:53 +03001728 decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001729 break;
1730
1731 case INTEL_PT_FUP:
1732 decoder->pge = true;
Adrian Hunterf952eac2017-05-26 11:17:07 +03001733 if (decoder->packet.count)
1734 intel_pt_set_last_ip(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001735 break;
1736
1737 case INTEL_PT_MODE_TSX:
1738 intel_pt_update_in_tx(decoder);
1739 break;
1740
Adrian Hunter3d498072015-07-17 19:33:53 +03001741 case INTEL_PT_MTC:
Adrian Hunter79b58422015-07-17 19:33:55 +03001742 intel_pt_calc_mtc_timestamp(decoder);
1743 if (decoder->period_type == INTEL_PT_PERIOD_MTC)
1744 decoder->state.type |= INTEL_PT_INSTRUCTION;
Adrian Hunter3d498072015-07-17 19:33:53 +03001745 break;
1746
1747 case INTEL_PT_CYC:
1748 case INTEL_PT_VMCS:
1749 case INTEL_PT_MNT:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001750 case INTEL_PT_PAD:
1751 default:
1752 break;
1753 }
1754 }
Adrian Hunter9bc668e2019-05-20 14:37:15 +03001755out:
1756 decoder->in_psb = false;
1757
1758 return err;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001759}
1760
1761static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder)
1762{
1763 int err;
1764
1765 if (decoder->tx_flags & INTEL_PT_ABORT_TX) {
1766 decoder->tx_flags = 0;
1767 decoder->state.flags &= ~INTEL_PT_IN_TX;
1768 decoder->state.flags |= INTEL_PT_ABORT_TX;
1769 } else {
1770 decoder->state.flags |= INTEL_PT_ASYNC;
1771 }
1772
1773 while (1) {
1774 err = intel_pt_get_next_packet(decoder);
1775 if (err)
1776 return err;
1777
1778 switch (decoder->packet.type) {
1779 case INTEL_PT_TNT:
1780 case INTEL_PT_FUP:
Adrian Hunter3d498072015-07-17 19:33:53 +03001781 case INTEL_PT_TRACESTOP:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001782 case INTEL_PT_PSB:
1783 case INTEL_PT_TSC:
Adrian Hunter3d498072015-07-17 19:33:53 +03001784 case INTEL_PT_TMA:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001785 case INTEL_PT_MODE_TSX:
1786 case INTEL_PT_BAD:
1787 case INTEL_PT_PSBEND:
Adrian Huntera472e652017-05-26 11:17:14 +03001788 case INTEL_PT_PTWRITE:
1789 case INTEL_PT_PTWRITE_IP:
1790 case INTEL_PT_EXSTOP:
1791 case INTEL_PT_EXSTOP_IP:
1792 case INTEL_PT_MWAIT:
1793 case INTEL_PT_PWRE:
1794 case INTEL_PT_PWRX:
Adrian Hunteredff7802019-06-10 10:27:53 +03001795 case INTEL_PT_BBP:
1796 case INTEL_PT_BIP:
1797 case INTEL_PT_BEP:
1798 case INTEL_PT_BEP_IP:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001799 intel_pt_log("ERROR: Missing TIP after FUP\n");
1800 decoder->pkt_state = INTEL_PT_STATE_ERR3;
Adrian Hunter1c196a62018-03-07 16:02:23 +02001801 decoder->pkt_step = 0;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001802 return -ENOENT;
1803
Adrian Hunterbd2e49e2018-05-31 13:23:43 +03001804 case INTEL_PT_CBR:
1805 intel_pt_calc_cbr(decoder);
1806 break;
1807
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001808 case INTEL_PT_OVF:
1809 return intel_pt_overflow(decoder);
1810
1811 case INTEL_PT_TIP_PGD:
1812 decoder->state.from_ip = decoder->ip;
Adrian Hunterbea63852018-09-20 16:00:48 +03001813 if (decoder->packet.count == 0) {
1814 decoder->state.to_ip = 0;
1815 } else {
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001816 intel_pt_set_ip(decoder);
Adrian Hunterbea63852018-09-20 16:00:48 +03001817 decoder->state.to_ip = decoder->ip;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001818 }
1819 decoder->pge = false;
1820 decoder->continuous_period = false;
Adrian Hunterbea63852018-09-20 16:00:48 +03001821 decoder->state.type |= INTEL_PT_TRACE_END;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001822 return 0;
1823
1824 case INTEL_PT_TIP_PGE:
1825 decoder->pge = true;
1826 intel_pt_log("Omitting PGE ip " x64_fmt "\n",
1827 decoder->ip);
1828 decoder->state.from_ip = 0;
1829 if (decoder->packet.count == 0) {
1830 decoder->state.to_ip = 0;
1831 } else {
1832 intel_pt_set_ip(decoder);
1833 decoder->state.to_ip = decoder->ip;
1834 }
Adrian Hunterbea63852018-09-20 16:00:48 +03001835 decoder->state.type |= INTEL_PT_TRACE_BEGIN;
Adrian Hunter3f055162019-05-20 14:37:17 +03001836 intel_pt_mtc_cyc_cnt_pge(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001837 return 0;
1838
1839 case INTEL_PT_TIP:
1840 decoder->state.from_ip = decoder->ip;
1841 if (decoder->packet.count == 0) {
1842 decoder->state.to_ip = 0;
1843 } else {
1844 intel_pt_set_ip(decoder);
1845 decoder->state.to_ip = decoder->ip;
1846 }
1847 return 0;
1848
1849 case INTEL_PT_PIP:
Adrian Hunter3d498072015-07-17 19:33:53 +03001850 decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
1851 break;
1852
1853 case INTEL_PT_MTC:
Adrian Hunter79b58422015-07-17 19:33:55 +03001854 intel_pt_calc_mtc_timestamp(decoder);
1855 if (decoder->period_type == INTEL_PT_PERIOD_MTC)
1856 decoder->state.type |= INTEL_PT_INSTRUCTION;
Adrian Hunter3d498072015-07-17 19:33:53 +03001857 break;
1858
1859 case INTEL_PT_CYC:
Adrian Huntercc336182015-07-17 19:33:57 +03001860 intel_pt_calc_cyc_timestamp(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001861 break;
1862
1863 case INTEL_PT_MODE_EXEC:
1864 decoder->exec_mode = decoder->packet.payload;
1865 break;
1866
Adrian Hunter3d498072015-07-17 19:33:53 +03001867 case INTEL_PT_VMCS:
1868 case INTEL_PT_MNT:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001869 case INTEL_PT_PAD:
1870 break;
1871
1872 default:
1873 return intel_pt_bug(decoder);
1874 }
1875 }
1876}
1877
1878static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
1879{
1880 bool no_tip = false;
1881 int err;
1882
1883 while (1) {
1884 err = intel_pt_get_next_packet(decoder);
1885 if (err)
1886 return err;
1887next:
1888 switch (decoder->packet.type) {
1889 case INTEL_PT_TNT:
1890 if (!decoder->packet.count)
1891 break;
1892 decoder->tnt = decoder->packet;
1893 decoder->pkt_state = INTEL_PT_STATE_TNT;
1894 err = intel_pt_walk_tnt(decoder);
1895 if (err == -EAGAIN)
1896 break;
1897 return err;
1898
1899 case INTEL_PT_TIP_PGD:
1900 if (decoder->packet.count != 0)
1901 intel_pt_set_last_ip(decoder);
1902 decoder->pkt_state = INTEL_PT_STATE_TIP_PGD;
1903 return intel_pt_walk_tip(decoder);
1904
1905 case INTEL_PT_TIP_PGE: {
1906 decoder->pge = true;
Adrian Hunter3f055162019-05-20 14:37:17 +03001907 intel_pt_mtc_cyc_cnt_pge(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001908 if (decoder->packet.count == 0) {
1909 intel_pt_log_at("Skipping zero TIP.PGE",
1910 decoder->pos);
1911 break;
1912 }
1913 intel_pt_set_ip(decoder);
1914 decoder->state.from_ip = 0;
1915 decoder->state.to_ip = decoder->ip;
Adrian Hunterbea63852018-09-20 16:00:48 +03001916 decoder->state.type |= INTEL_PT_TRACE_BEGIN;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001917 return 0;
1918 }
1919
1920 case INTEL_PT_OVF:
1921 return intel_pt_overflow(decoder);
1922
1923 case INTEL_PT_TIP:
1924 if (decoder->packet.count != 0)
1925 intel_pt_set_last_ip(decoder);
1926 decoder->pkt_state = INTEL_PT_STATE_TIP;
1927 return intel_pt_walk_tip(decoder);
1928
1929 case INTEL_PT_FUP:
1930 if (decoder->packet.count == 0) {
1931 intel_pt_log_at("Skipping zero FUP",
1932 decoder->pos);
1933 no_tip = false;
1934 break;
1935 }
1936 intel_pt_set_last_ip(decoder);
Adrian Hunter83959812017-05-26 11:17:11 +03001937 if (!decoder->branch_enable) {
1938 decoder->ip = decoder->last_ip;
Adrian Huntera472e652017-05-26 11:17:14 +03001939 if (intel_pt_fup_event(decoder))
1940 return 0;
1941 no_tip = false;
Adrian Hunter83959812017-05-26 11:17:11 +03001942 break;
1943 }
Adrian Huntera472e652017-05-26 11:17:14 +03001944 if (decoder->set_fup_mwait)
1945 no_tip = true;
Adrian Hunter401136b2020-07-10 18:10:53 +03001946 if (no_tip)
1947 decoder->pkt_state = INTEL_PT_STATE_FUP_NO_TIP;
1948 else
1949 decoder->pkt_state = INTEL_PT_STATE_FUP;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001950 err = intel_pt_walk_fup(decoder);
Adrian Hunter401136b2020-07-10 18:10:53 +03001951 if (err != -EAGAIN)
1952 return err;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001953 if (no_tip) {
1954 no_tip = false;
1955 break;
1956 }
1957 return intel_pt_walk_fup_tip(decoder);
1958
Adrian Hunter3d498072015-07-17 19:33:53 +03001959 case INTEL_PT_TRACESTOP:
Adrian Hunter7eacca32015-07-17 19:33:59 +03001960 decoder->pge = false;
1961 decoder->continuous_period = false;
1962 intel_pt_clear_tx_flags(decoder);
1963 decoder->have_tma = false;
Adrian Hunter3d498072015-07-17 19:33:53 +03001964 break;
1965
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001966 case INTEL_PT_PSB:
Adrian Hunteree14ac02017-05-26 11:17:06 +03001967 decoder->last_ip = 0;
1968 decoder->have_last_ip = true;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001969 intel_pt_clear_stack(&decoder->stack);
1970 err = intel_pt_walk_psbend(decoder);
1971 if (err == -EAGAIN)
1972 goto next;
1973 if (err)
1974 return err;
Adrian Hunter91de8682019-06-22 12:32:43 +03001975 /*
1976 * PSB+ CBR will not have changed but cater for the
1977 * possibility of another CBR change that gets caught up
1978 * in the PSB+.
1979 */
1980 if (decoder->cbr != decoder->cbr_seen)
1981 return 0;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03001982 break;
1983
1984 case INTEL_PT_PIP:
Adrian Hunter3d498072015-07-17 19:33:53 +03001985 decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
1986 break;
1987
1988 case INTEL_PT_MTC:
Adrian Hunter79b58422015-07-17 19:33:55 +03001989 intel_pt_calc_mtc_timestamp(decoder);
1990 if (decoder->period_type != INTEL_PT_PERIOD_MTC)
1991 break;
1992 /*
1993 * Ensure that there has been an instruction since the
1994 * last MTC.
1995 */
1996 if (!decoder->mtc_insn)
1997 break;
1998 decoder->mtc_insn = false;
1999 /* Ensure that there is a timestamp */
2000 if (!decoder->timestamp)
2001 break;
2002 decoder->state.type = INTEL_PT_INSTRUCTION;
2003 decoder->state.from_ip = decoder->ip;
2004 decoder->state.to_ip = 0;
2005 decoder->mtc_insn = false;
2006 return 0;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002007
2008 case INTEL_PT_TSC:
2009 intel_pt_calc_tsc_timestamp(decoder);
2010 break;
2011
Adrian Hunter3d498072015-07-17 19:33:53 +03002012 case INTEL_PT_TMA:
Adrian Hunter79b58422015-07-17 19:33:55 +03002013 intel_pt_calc_tma(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002014 break;
2015
2016 case INTEL_PT_CYC:
Adrian Huntercc336182015-07-17 19:33:57 +03002017 intel_pt_calc_cyc_timestamp(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002018 break;
2019
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002020 case INTEL_PT_CBR:
Adrian Huntercc336182015-07-17 19:33:57 +03002021 intel_pt_calc_cbr(decoder);
Adrian Hunterabe5a1d2019-06-22 12:32:42 +03002022 if (decoder->cbr != decoder->cbr_seen)
Adrian Hunter0a7c700d2017-05-26 11:17:16 +03002023 return 0;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002024 break;
2025
2026 case INTEL_PT_MODE_EXEC:
2027 decoder->exec_mode = decoder->packet.payload;
2028 break;
2029
2030 case INTEL_PT_MODE_TSX:
2031 /* MODE_TSX need not be followed by FUP */
2032 if (!decoder->pge) {
2033 intel_pt_update_in_tx(decoder);
2034 break;
2035 }
2036 err = intel_pt_mode_tsx(decoder, &no_tip);
2037 if (err)
2038 return err;
2039 goto next;
2040
2041 case INTEL_PT_BAD: /* Does not happen */
2042 return intel_pt_bug(decoder);
2043
2044 case INTEL_PT_PSBEND:
Adrian Hunter3d498072015-07-17 19:33:53 +03002045 case INTEL_PT_VMCS:
2046 case INTEL_PT_MNT:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002047 case INTEL_PT_PAD:
2048 break;
2049
Adrian Huntera472e652017-05-26 11:17:14 +03002050 case INTEL_PT_PTWRITE_IP:
2051 decoder->fup_ptw_payload = decoder->packet.payload;
2052 err = intel_pt_get_next_packet(decoder);
2053 if (err)
2054 return err;
2055 if (decoder->packet.type == INTEL_PT_FUP) {
2056 decoder->set_fup_ptw = true;
2057 no_tip = true;
2058 } else {
2059 intel_pt_log_at("ERROR: Missing FUP after PTWRITE",
2060 decoder->pos);
2061 }
2062 goto next;
2063
2064 case INTEL_PT_PTWRITE:
2065 decoder->state.type = INTEL_PT_PTW;
2066 decoder->state.from_ip = decoder->ip;
2067 decoder->state.to_ip = 0;
2068 decoder->state.ptw_payload = decoder->packet.payload;
2069 return 0;
2070
2071 case INTEL_PT_MWAIT:
2072 decoder->fup_mwait_payload = decoder->packet.payload;
2073 decoder->set_fup_mwait = true;
2074 break;
2075
2076 case INTEL_PT_PWRE:
2077 if (decoder->set_fup_mwait) {
2078 decoder->fup_pwre_payload =
2079 decoder->packet.payload;
2080 decoder->set_fup_pwre = true;
2081 break;
2082 }
2083 decoder->state.type = INTEL_PT_PWR_ENTRY;
2084 decoder->state.from_ip = decoder->ip;
2085 decoder->state.to_ip = 0;
2086 decoder->state.pwrx_payload = decoder->packet.payload;
2087 return 0;
2088
2089 case INTEL_PT_EXSTOP_IP:
2090 err = intel_pt_get_next_packet(decoder);
2091 if (err)
2092 return err;
2093 if (decoder->packet.type == INTEL_PT_FUP) {
2094 decoder->set_fup_exstop = true;
2095 no_tip = true;
2096 } else {
2097 intel_pt_log_at("ERROR: Missing FUP after EXSTOP",
2098 decoder->pos);
2099 }
2100 goto next;
2101
2102 case INTEL_PT_EXSTOP:
2103 decoder->state.type = INTEL_PT_EX_STOP;
2104 decoder->state.from_ip = decoder->ip;
2105 decoder->state.to_ip = 0;
2106 return 0;
2107
2108 case INTEL_PT_PWRX:
2109 decoder->state.type = INTEL_PT_PWR_EXIT;
2110 decoder->state.from_ip = decoder->ip;
2111 decoder->state.to_ip = 0;
2112 decoder->state.pwrx_payload = decoder->packet.payload;
2113 return 0;
2114
Adrian Hunteredff7802019-06-10 10:27:53 +03002115 case INTEL_PT_BBP:
Adrian Hunter4c355952019-06-10 10:27:55 +03002116 intel_pt_bbp(decoder);
Adrian Hunteredff7802019-06-10 10:27:53 +03002117 break;
2118
Adrian Hunter4c355952019-06-10 10:27:55 +03002119 case INTEL_PT_BIP:
2120 intel_pt_bip(decoder);
2121 break;
2122
2123 case INTEL_PT_BEP:
2124 decoder->state.type = INTEL_PT_BLK_ITEMS;
2125 decoder->state.from_ip = decoder->ip;
2126 decoder->state.to_ip = 0;
2127 return 0;
2128
2129 case INTEL_PT_BEP_IP:
2130 err = intel_pt_get_next_packet(decoder);
2131 if (err)
2132 return err;
2133 if (decoder->packet.type == INTEL_PT_FUP) {
2134 decoder->set_fup_bep = true;
2135 no_tip = true;
2136 } else {
2137 intel_pt_log_at("ERROR: Missing FUP after BEP",
2138 decoder->pos);
2139 }
2140 goto next;
2141
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002142 default:
2143 return intel_pt_bug(decoder);
2144 }
2145 }
2146}
2147
Adrian Huntere1717e02016-07-20 12:00:06 +03002148static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder)
2149{
Adrian Hunterf952eac2017-05-26 11:17:07 +03002150 return decoder->packet.count &&
2151 (decoder->have_last_ip || decoder->packet.count == 3 ||
2152 decoder->packet.count == 6);
Adrian Huntere1717e02016-07-20 12:00:06 +03002153}
2154
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002155/* Walk PSB+ packets to get in sync. */
2156static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
2157{
2158 int err;
2159
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002160 decoder->in_psb = true;
2161
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002162 while (1) {
2163 err = intel_pt_get_next_packet(decoder);
2164 if (err)
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002165 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002166
2167 switch (decoder->packet.type) {
2168 case INTEL_PT_TIP_PGD:
2169 decoder->continuous_period = false;
Arnaldo Carvalho de Melo7ea68562017-02-09 15:22:22 -03002170 __fallthrough;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002171 case INTEL_PT_TIP_PGE:
2172 case INTEL_PT_TIP:
Adrian Huntera472e652017-05-26 11:17:14 +03002173 case INTEL_PT_PTWRITE:
2174 case INTEL_PT_PTWRITE_IP:
2175 case INTEL_PT_EXSTOP:
2176 case INTEL_PT_EXSTOP_IP:
2177 case INTEL_PT_MWAIT:
2178 case INTEL_PT_PWRE:
2179 case INTEL_PT_PWRX:
Adrian Hunteredff7802019-06-10 10:27:53 +03002180 case INTEL_PT_BBP:
2181 case INTEL_PT_BIP:
2182 case INTEL_PT_BEP:
2183 case INTEL_PT_BEP_IP:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002184 intel_pt_log("ERROR: Unexpected packet\n");
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002185 err = -ENOENT;
2186 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002187
2188 case INTEL_PT_FUP:
2189 decoder->pge = true;
Adrian Huntere1717e02016-07-20 12:00:06 +03002190 if (intel_pt_have_ip(decoder)) {
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002191 uint64_t current_ip = decoder->ip;
2192
2193 intel_pt_set_ip(decoder);
2194 if (current_ip)
2195 intel_pt_log_to("Setting IP",
2196 decoder->ip);
2197 }
2198 break;
2199
Adrian Hunter3d498072015-07-17 19:33:53 +03002200 case INTEL_PT_MTC:
Adrian Hunter79b58422015-07-17 19:33:55 +03002201 intel_pt_calc_mtc_timestamp(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002202 break;
2203
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002204 case INTEL_PT_TSC:
2205 intel_pt_calc_tsc_timestamp(decoder);
2206 break;
2207
Adrian Hunter3d498072015-07-17 19:33:53 +03002208 case INTEL_PT_TMA:
Adrian Hunter79b58422015-07-17 19:33:55 +03002209 intel_pt_calc_tma(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002210 break;
2211
2212 case INTEL_PT_CYC:
Adrian Huntercc336182015-07-17 19:33:57 +03002213 intel_pt_calc_cyc_timestamp(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002214 break;
2215
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002216 case INTEL_PT_CBR:
Adrian Huntercc336182015-07-17 19:33:57 +03002217 intel_pt_calc_cbr(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002218 break;
2219
2220 case INTEL_PT_PIP:
Adrian Hunter3d498072015-07-17 19:33:53 +03002221 decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002222 break;
2223
2224 case INTEL_PT_MODE_EXEC:
2225 decoder->exec_mode = decoder->packet.payload;
2226 break;
2227
2228 case INTEL_PT_MODE_TSX:
2229 intel_pt_update_in_tx(decoder);
2230 break;
2231
Adrian Hunter3d498072015-07-17 19:33:53 +03002232 case INTEL_PT_TRACESTOP:
Adrian Hunter7eacca32015-07-17 19:33:59 +03002233 decoder->pge = false;
2234 decoder->continuous_period = false;
2235 intel_pt_clear_tx_flags(decoder);
Arnaldo Carvalho de Melo7ea68562017-02-09 15:22:22 -03002236 __fallthrough;
2237
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002238 case INTEL_PT_TNT:
Adrian Hunter79b58422015-07-17 19:33:55 +03002239 decoder->have_tma = false;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002240 intel_pt_log("ERROR: Unexpected packet\n");
2241 if (decoder->ip)
2242 decoder->pkt_state = INTEL_PT_STATE_ERR4;
2243 else
2244 decoder->pkt_state = INTEL_PT_STATE_ERR3;
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002245 err = -ENOENT;
2246 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002247
2248 case INTEL_PT_BAD: /* Does not happen */
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002249 err = intel_pt_bug(decoder);
2250 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002251
2252 case INTEL_PT_OVF:
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002253 err = intel_pt_overflow(decoder);
2254 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002255
2256 case INTEL_PT_PSBEND:
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002257 err = 0;
2258 goto out;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002259
2260 case INTEL_PT_PSB:
Adrian Hunter3d498072015-07-17 19:33:53 +03002261 case INTEL_PT_VMCS:
2262 case INTEL_PT_MNT:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002263 case INTEL_PT_PAD:
2264 default:
2265 break;
2266 }
2267 }
Adrian Hunter9bc668e2019-05-20 14:37:15 +03002268out:
2269 decoder->in_psb = false;
2270
2271 return err;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002272}
2273
2274static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
2275{
2276 int err;
2277
2278 while (1) {
2279 err = intel_pt_get_next_packet(decoder);
2280 if (err)
2281 return err;
2282
2283 switch (decoder->packet.type) {
2284 case INTEL_PT_TIP_PGD:
2285 decoder->continuous_period = false;
Adrian Hunterf3c98c42019-05-20 14:37:16 +03002286 decoder->pge = false;
Adrian Huntere1717e02016-07-20 12:00:06 +03002287 if (intel_pt_have_ip(decoder))
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002288 intel_pt_set_ip(decoder);
Adrian Hunterbea63852018-09-20 16:00:48 +03002289 if (!decoder->ip)
2290 break;
Adrian Hunterf3c98c42019-05-20 14:37:16 +03002291 decoder->state.type |= INTEL_PT_TRACE_END;
2292 return 0;
2293
2294 case INTEL_PT_TIP_PGE:
2295 decoder->pge = true;
Adrian Hunter3f055162019-05-20 14:37:17 +03002296 intel_pt_mtc_cyc_cnt_pge(decoder);
Adrian Hunterf3c98c42019-05-20 14:37:16 +03002297 if (intel_pt_have_ip(decoder))
2298 intel_pt_set_ip(decoder);
2299 if (!decoder->ip)
2300 break;
2301 decoder->state.type |= INTEL_PT_TRACE_BEGIN;
2302 return 0;
2303
2304 case INTEL_PT_TIP:
2305 decoder->pge = true;
2306 if (intel_pt_have_ip(decoder))
2307 intel_pt_set_ip(decoder);
2308 if (!decoder->ip)
2309 break;
Adrian Hunterbea63852018-09-20 16:00:48 +03002310 return 0;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002311
2312 case INTEL_PT_FUP:
Adrian Hunter622b7a42017-05-26 11:17:08 +03002313 if (intel_pt_have_ip(decoder))
2314 intel_pt_set_ip(decoder);
2315 if (decoder->ip)
2316 return 0;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002317 break;
2318
Adrian Hunter3d498072015-07-17 19:33:53 +03002319 case INTEL_PT_MTC:
Adrian Hunter79b58422015-07-17 19:33:55 +03002320 intel_pt_calc_mtc_timestamp(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002321 break;
2322
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002323 case INTEL_PT_TSC:
2324 intel_pt_calc_tsc_timestamp(decoder);
2325 break;
2326
Adrian Hunter3d498072015-07-17 19:33:53 +03002327 case INTEL_PT_TMA:
Adrian Hunter79b58422015-07-17 19:33:55 +03002328 intel_pt_calc_tma(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002329 break;
2330
2331 case INTEL_PT_CYC:
Adrian Huntercc336182015-07-17 19:33:57 +03002332 intel_pt_calc_cyc_timestamp(decoder);
Adrian Hunter3d498072015-07-17 19:33:53 +03002333 break;
2334
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002335 case INTEL_PT_CBR:
Adrian Huntercc336182015-07-17 19:33:57 +03002336 intel_pt_calc_cbr(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002337 break;
2338
2339 case INTEL_PT_PIP:
Adrian Hunter3d498072015-07-17 19:33:53 +03002340 decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002341 break;
2342
2343 case INTEL_PT_MODE_EXEC:
2344 decoder->exec_mode = decoder->packet.payload;
2345 break;
2346
2347 case INTEL_PT_MODE_TSX:
2348 intel_pt_update_in_tx(decoder);
2349 break;
2350
2351 case INTEL_PT_OVF:
2352 return intel_pt_overflow(decoder);
2353
2354 case INTEL_PT_BAD: /* Does not happen */
2355 return intel_pt_bug(decoder);
2356
Adrian Hunter3d498072015-07-17 19:33:53 +03002357 case INTEL_PT_TRACESTOP:
Adrian Hunter7eacca32015-07-17 19:33:59 +03002358 decoder->pge = false;
2359 decoder->continuous_period = false;
2360 intel_pt_clear_tx_flags(decoder);
2361 decoder->have_tma = false;
Adrian Hunter3d498072015-07-17 19:33:53 +03002362 break;
2363
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002364 case INTEL_PT_PSB:
Adrian Hunteree14ac02017-05-26 11:17:06 +03002365 decoder->last_ip = 0;
2366 decoder->have_last_ip = true;
Adrian Hunter12b70802017-05-26 11:17:04 +03002367 intel_pt_clear_stack(&decoder->stack);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002368 err = intel_pt_walk_psb(decoder);
2369 if (err)
2370 return err;
2371 if (decoder->ip) {
2372 /* Do not have a sample */
2373 decoder->state.type = 0;
2374 return 0;
2375 }
2376 break;
2377
2378 case INTEL_PT_TNT:
2379 case INTEL_PT_PSBEND:
Adrian Hunter3d498072015-07-17 19:33:53 +03002380 case INTEL_PT_VMCS:
2381 case INTEL_PT_MNT:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002382 case INTEL_PT_PAD:
Adrian Huntera472e652017-05-26 11:17:14 +03002383 case INTEL_PT_PTWRITE:
2384 case INTEL_PT_PTWRITE_IP:
2385 case INTEL_PT_EXSTOP:
2386 case INTEL_PT_EXSTOP_IP:
2387 case INTEL_PT_MWAIT:
2388 case INTEL_PT_PWRE:
2389 case INTEL_PT_PWRX:
Adrian Hunteredff7802019-06-10 10:27:53 +03002390 case INTEL_PT_BBP:
2391 case INTEL_PT_BIP:
2392 case INTEL_PT_BEP:
2393 case INTEL_PT_BEP_IP:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002394 default:
2395 break;
2396 }
2397 }
2398}
2399
2400static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
2401{
2402 int err;
2403
Adrian Hunter6a558f12017-05-26 11:17:09 +03002404 decoder->set_fup_tx_flags = false;
Adrian Huntera472e652017-05-26 11:17:14 +03002405 decoder->set_fup_ptw = false;
2406 decoder->set_fup_mwait = false;
2407 decoder->set_fup_pwre = false;
2408 decoder->set_fup_exstop = false;
Adrian Hunter4c355952019-06-10 10:27:55 +03002409 decoder->set_fup_bep = false;
Adrian Hunter6a558f12017-05-26 11:17:09 +03002410
Adrian Hunter83959812017-05-26 11:17:11 +03002411 if (!decoder->branch_enable) {
2412 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
2413 decoder->overflow = false;
2414 decoder->state.type = 0; /* Do not have a sample */
2415 return 0;
2416 }
2417
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002418 intel_pt_log("Scanning for full IP\n");
2419 err = intel_pt_walk_to_ip(decoder);
2420 if (err)
2421 return err;
2422
2423 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
2424 decoder->overflow = false;
2425
2426 decoder->state.from_ip = 0;
2427 decoder->state.to_ip = decoder->ip;
2428 intel_pt_log_to("Setting IP", decoder->ip);
2429
2430 return 0;
2431}
2432
2433static int intel_pt_part_psb(struct intel_pt_decoder *decoder)
2434{
2435 const unsigned char *end = decoder->buf + decoder->len;
2436 size_t i;
2437
2438 for (i = INTEL_PT_PSB_LEN - 1; i; i--) {
2439 if (i > decoder->len)
2440 continue;
2441 if (!memcmp(end - i, INTEL_PT_PSB_STR, i))
2442 return i;
2443 }
2444 return 0;
2445}
2446
2447static int intel_pt_rest_psb(struct intel_pt_decoder *decoder, int part_psb)
2448{
2449 size_t rest_psb = INTEL_PT_PSB_LEN - part_psb;
2450 const char *psb = INTEL_PT_PSB_STR;
2451
2452 if (rest_psb > decoder->len ||
2453 memcmp(decoder->buf, psb + part_psb, rest_psb))
2454 return 0;
2455
2456 return rest_psb;
2457}
2458
2459static int intel_pt_get_split_psb(struct intel_pt_decoder *decoder,
2460 int part_psb)
2461{
2462 int rest_psb, ret;
2463
2464 decoder->pos += decoder->len;
2465 decoder->len = 0;
2466
Adrian Hunter6c1f0b12019-06-04 16:00:05 +03002467 ret = intel_pt_get_next_data(decoder, false);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002468 if (ret)
2469 return ret;
2470
2471 rest_psb = intel_pt_rest_psb(decoder, part_psb);
2472 if (!rest_psb)
2473 return 0;
2474
2475 decoder->pos -= part_psb;
2476 decoder->next_buf = decoder->buf + rest_psb;
2477 decoder->next_len = decoder->len - rest_psb;
2478 memcpy(decoder->temp_buf, INTEL_PT_PSB_STR, INTEL_PT_PSB_LEN);
2479 decoder->buf = decoder->temp_buf;
2480 decoder->len = INTEL_PT_PSB_LEN;
2481
2482 return 0;
2483}
2484
2485static int intel_pt_scan_for_psb(struct intel_pt_decoder *decoder)
2486{
2487 unsigned char *next;
2488 int ret;
2489
2490 intel_pt_log("Scanning for PSB\n");
2491 while (1) {
2492 if (!decoder->len) {
Adrian Hunter6c1f0b12019-06-04 16:00:05 +03002493 ret = intel_pt_get_next_data(decoder, false);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002494 if (ret)
2495 return ret;
2496 }
2497
2498 next = memmem(decoder->buf, decoder->len, INTEL_PT_PSB_STR,
2499 INTEL_PT_PSB_LEN);
2500 if (!next) {
2501 int part_psb;
2502
2503 part_psb = intel_pt_part_psb(decoder);
2504 if (part_psb) {
2505 ret = intel_pt_get_split_psb(decoder, part_psb);
2506 if (ret)
2507 return ret;
2508 } else {
2509 decoder->pos += decoder->len;
2510 decoder->len = 0;
2511 }
2512 continue;
2513 }
2514
2515 decoder->pkt_step = next - decoder->buf;
2516 return intel_pt_get_next_packet(decoder);
2517 }
2518}
2519
2520static int intel_pt_sync(struct intel_pt_decoder *decoder)
2521{
2522 int err;
2523
2524 decoder->pge = false;
2525 decoder->continuous_period = false;
Adrian Hunteree14ac02017-05-26 11:17:06 +03002526 decoder->have_last_ip = false;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002527 decoder->last_ip = 0;
2528 decoder->ip = 0;
2529 intel_pt_clear_stack(&decoder->stack);
2530
2531 err = intel_pt_scan_for_psb(decoder);
2532 if (err)
2533 return err;
2534
Adrian Hunteree14ac02017-05-26 11:17:06 +03002535 decoder->have_last_ip = true;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002536 decoder->pkt_state = INTEL_PT_STATE_NO_IP;
2537
2538 err = intel_pt_walk_psb(decoder);
2539 if (err)
2540 return err;
2541
2542 if (decoder->ip) {
2543 decoder->state.type = 0; /* Do not have a sample */
2544 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
2545 } else {
2546 return intel_pt_sync_ip(decoder);
2547 }
2548
2549 return 0;
2550}
2551
2552static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder)
2553{
Adrian Hunter3f04d982017-05-26 11:17:03 +03002554 uint64_t est = decoder->sample_insn_cnt << 1;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002555
2556 if (!decoder->cbr || !decoder->max_non_turbo_ratio)
2557 goto out;
2558
2559 est *= decoder->max_non_turbo_ratio;
2560 est /= decoder->cbr;
2561out:
Adrian Hunter3f04d982017-05-26 11:17:03 +03002562 return decoder->sample_timestamp + est;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002563}
2564
2565const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
2566{
2567 int err;
2568
2569 do {
2570 decoder->state.type = INTEL_PT_BRANCH;
2571 decoder->state.flags = 0;
2572
2573 switch (decoder->pkt_state) {
2574 case INTEL_PT_STATE_NO_PSB:
2575 err = intel_pt_sync(decoder);
2576 break;
2577 case INTEL_PT_STATE_NO_IP:
Adrian Hunteree14ac02017-05-26 11:17:06 +03002578 decoder->have_last_ip = false;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002579 decoder->last_ip = 0;
Adrian Hunterad7167a2017-05-26 11:17:05 +03002580 decoder->ip = 0;
Adrian Hunter04194202017-05-26 11:17:10 +03002581 __fallthrough;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002582 case INTEL_PT_STATE_ERR_RESYNC:
2583 err = intel_pt_sync_ip(decoder);
2584 break;
2585 case INTEL_PT_STATE_IN_SYNC:
2586 err = intel_pt_walk_trace(decoder);
2587 break;
2588 case INTEL_PT_STATE_TNT:
Adrian Hunter61b6e082019-05-10 15:41:42 +03002589 case INTEL_PT_STATE_TNT_CONT:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002590 err = intel_pt_walk_tnt(decoder);
2591 if (err == -EAGAIN)
2592 err = intel_pt_walk_trace(decoder);
2593 break;
2594 case INTEL_PT_STATE_TIP:
2595 case INTEL_PT_STATE_TIP_PGD:
2596 err = intel_pt_walk_tip(decoder);
2597 break;
2598 case INTEL_PT_STATE_FUP:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002599 err = intel_pt_walk_fup(decoder);
2600 if (err == -EAGAIN)
2601 err = intel_pt_walk_fup_tip(decoder);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002602 break;
2603 case INTEL_PT_STATE_FUP_NO_TIP:
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002604 err = intel_pt_walk_fup(decoder);
2605 if (err == -EAGAIN)
2606 err = intel_pt_walk_trace(decoder);
2607 break;
2608 default:
2609 err = intel_pt_bug(decoder);
2610 break;
2611 }
2612 } while (err == -ENOLINK);
2613
Adrian Hunter22c06892017-05-26 11:17:02 +03002614 if (err) {
2615 decoder->state.err = intel_pt_ext_err(err);
2616 decoder->state.from_ip = decoder->ip;
Adrian Hunter948e9dc2019-05-20 14:37:10 +03002617 intel_pt_update_sample_time(decoder);
Adrian Hunter7b4b4f82019-05-20 14:37:11 +03002618 decoder->sample_tot_cyc_cnt = decoder->tot_cyc_cnt;
Adrian Hunter22c06892017-05-26 11:17:02 +03002619 } else {
2620 decoder->state.err = 0;
Adrian Hunterabe5a1d2019-06-22 12:32:42 +03002621 if (decoder->cbr != decoder->cbr_seen) {
Adrian Hunter0a7c700d2017-05-26 11:17:16 +03002622 decoder->cbr_seen = decoder->cbr;
Adrian Hunterabe5a1d2019-06-22 12:32:42 +03002623 if (!decoder->state.type) {
2624 decoder->state.from_ip = decoder->ip;
2625 decoder->state.to_ip = 0;
2626 }
Adrian Hunter0a7c700d2017-05-26 11:17:16 +03002627 decoder->state.type |= INTEL_PT_CBR_CHG;
2628 decoder->state.cbr_payload = decoder->cbr_payload;
Adrian Hunter51b09182019-06-22 12:32:44 +03002629 decoder->state.cbr = decoder->cbr;
Adrian Hunter0a7c700d2017-05-26 11:17:16 +03002630 }
Adrian Hunter3f04d982017-05-26 11:17:03 +03002631 if (intel_pt_sample_time(decoder->pkt_state)) {
Adrian Hunter948e9dc2019-05-20 14:37:10 +03002632 intel_pt_update_sample_time(decoder);
Adrian Hunter7b4b4f82019-05-20 14:37:11 +03002633 if (decoder->sample_cyc)
2634 decoder->sample_tot_cyc_cnt = decoder->tot_cyc_cnt;
Adrian Hunter3f04d982017-05-26 11:17:03 +03002635 }
Adrian Hunter22c06892017-05-26 11:17:02 +03002636 }
2637
Adrian Hunter3f04d982017-05-26 11:17:03 +03002638 decoder->state.timestamp = decoder->sample_timestamp;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002639 decoder->state.est_timestamp = intel_pt_est_timestamp(decoder);
2640 decoder->state.cr3 = decoder->cr3;
Adrian Hunter2a21d032015-07-17 19:33:48 +03002641 decoder->state.tot_insn_cnt = decoder->tot_insn_cnt;
Adrian Hunter7b4b4f82019-05-20 14:37:11 +03002642 decoder->state.tot_cyc_cnt = decoder->sample_tot_cyc_cnt;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002643
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002644 return &decoder->state;
2645}
2646
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002647/**
2648 * intel_pt_next_psb - move buffer pointer to the start of the next PSB packet.
2649 * @buf: pointer to buffer pointer
2650 * @len: size of buffer
2651 *
2652 * Updates the buffer pointer to point to the start of the next PSB packet if
2653 * there is one, otherwise the buffer pointer is unchanged. If @buf is updated,
2654 * @len is adjusted accordingly.
2655 *
2656 * Return: %true if a PSB packet is found, %false otherwise.
2657 */
2658static bool intel_pt_next_psb(unsigned char **buf, size_t *len)
2659{
2660 unsigned char *next;
2661
2662 next = memmem(*buf, *len, INTEL_PT_PSB_STR, INTEL_PT_PSB_LEN);
2663 if (next) {
2664 *len -= next - *buf;
2665 *buf = next;
2666 return true;
2667 }
2668 return false;
2669}
2670
2671/**
2672 * intel_pt_step_psb - move buffer pointer to the start of the following PSB
2673 * packet.
2674 * @buf: pointer to buffer pointer
2675 * @len: size of buffer
2676 *
2677 * Updates the buffer pointer to point to the start of the following PSB packet
2678 * (skipping the PSB at @buf itself) if there is one, otherwise the buffer
2679 * pointer is unchanged. If @buf is updated, @len is adjusted accordingly.
2680 *
2681 * Return: %true if a PSB packet is found, %false otherwise.
2682 */
2683static bool intel_pt_step_psb(unsigned char **buf, size_t *len)
2684{
2685 unsigned char *next;
2686
2687 if (!*len)
2688 return false;
2689
2690 next = memmem(*buf + 1, *len - 1, INTEL_PT_PSB_STR, INTEL_PT_PSB_LEN);
2691 if (next) {
2692 *len -= next - *buf;
2693 *buf = next;
2694 return true;
2695 }
2696 return false;
2697}
2698
2699/**
2700 * intel_pt_last_psb - find the last PSB packet in a buffer.
2701 * @buf: buffer
2702 * @len: size of buffer
2703 *
2704 * This function finds the last PSB in a buffer.
2705 *
2706 * Return: A pointer to the last PSB in @buf if found, %NULL otherwise.
2707 */
2708static unsigned char *intel_pt_last_psb(unsigned char *buf, size_t len)
2709{
2710 const char *n = INTEL_PT_PSB_STR;
2711 unsigned char *p;
2712 size_t k;
2713
2714 if (len < INTEL_PT_PSB_LEN)
2715 return NULL;
2716
2717 k = len - INTEL_PT_PSB_LEN + 1;
2718 while (1) {
2719 p = memrchr(buf, n[0], k);
2720 if (!p)
2721 return NULL;
2722 if (!memcmp(p + 1, n + 1, INTEL_PT_PSB_LEN - 1))
2723 return p;
2724 k = p - buf;
2725 if (!k)
2726 return NULL;
2727 }
2728}
2729
2730/**
2731 * intel_pt_next_tsc - find and return next TSC.
2732 * @buf: buffer
2733 * @len: size of buffer
2734 * @tsc: TSC value returned
Adrian Hunter117db4b2018-03-07 16:02:21 +02002735 * @rem: returns remaining size when TSC is found
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002736 *
2737 * Find a TSC packet in @buf and return the TSC value. This function assumes
2738 * that @buf starts at a PSB and that PSB+ will contain TSC and so stops if a
2739 * PSBEND packet is found.
2740 *
2741 * Return: %true if TSC is found, false otherwise.
2742 */
Adrian Hunter117db4b2018-03-07 16:02:21 +02002743static bool intel_pt_next_tsc(unsigned char *buf, size_t len, uint64_t *tsc,
2744 size_t *rem)
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002745{
Adrian Hunteredff7802019-06-10 10:27:53 +03002746 enum intel_pt_pkt_ctx ctx = INTEL_PT_NO_CTX;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002747 struct intel_pt_pkt packet;
2748 int ret;
2749
2750 while (len) {
Adrian Hunteredff7802019-06-10 10:27:53 +03002751 ret = intel_pt_get_packet(buf, len, &packet, &ctx);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002752 if (ret <= 0)
2753 return false;
2754 if (packet.type == INTEL_PT_TSC) {
2755 *tsc = packet.payload;
Adrian Hunter117db4b2018-03-07 16:02:21 +02002756 *rem = len;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002757 return true;
2758 }
2759 if (packet.type == INTEL_PT_PSBEND)
2760 return false;
2761 buf += ret;
2762 len -= ret;
2763 }
2764 return false;
2765}
2766
2767/**
2768 * intel_pt_tsc_cmp - compare 7-byte TSCs.
2769 * @tsc1: first TSC to compare
2770 * @tsc2: second TSC to compare
2771 *
2772 * This function compares 7-byte TSC values allowing for the possibility that
2773 * TSC wrapped around. Generally it is not possible to know if TSC has wrapped
2774 * around so for that purpose this function assumes the absolute difference is
2775 * less than half the maximum difference.
2776 *
2777 * Return: %-1 if @tsc1 is before @tsc2, %0 if @tsc1 == @tsc2, %1 if @tsc1 is
2778 * after @tsc2.
2779 */
2780static int intel_pt_tsc_cmp(uint64_t tsc1, uint64_t tsc2)
2781{
2782 const uint64_t halfway = (1ULL << 55);
2783
2784 if (tsc1 == tsc2)
2785 return 0;
2786
2787 if (tsc1 < tsc2) {
2788 if (tsc2 - tsc1 < halfway)
2789 return -1;
2790 else
2791 return 1;
2792 } else {
2793 if (tsc1 - tsc2 < halfway)
2794 return 1;
2795 else
2796 return -1;
2797 }
2798}
2799
Adrian Hunter5a99d992019-02-06 12:39:44 +02002800#define MAX_PADDING (PERF_AUXTRACE_RECORD_ALIGNMENT - 1)
2801
2802/**
2803 * adj_for_padding - adjust overlap to account for padding.
2804 * @buf_b: second buffer
2805 * @buf_a: first buffer
2806 * @len_a: size of first buffer
2807 *
2808 * @buf_a might have up to 7 bytes of padding appended. Adjust the overlap
2809 * accordingly.
2810 *
2811 * Return: A pointer into @buf_b from where non-overlapped data starts
2812 */
2813static unsigned char *adj_for_padding(unsigned char *buf_b,
2814 unsigned char *buf_a, size_t len_a)
2815{
2816 unsigned char *p = buf_b - MAX_PADDING;
2817 unsigned char *q = buf_a + len_a - MAX_PADDING;
2818 int i;
2819
2820 for (i = MAX_PADDING; i; i--, p++, q++) {
2821 if (*p != *q)
2822 break;
2823 }
2824
2825 return p;
2826}
2827
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002828/**
2829 * intel_pt_find_overlap_tsc - determine start of non-overlapped trace data
2830 * using TSC.
2831 * @buf_a: first buffer
2832 * @len_a: size of first buffer
2833 * @buf_b: second buffer
2834 * @len_b: size of second buffer
Adrian Hunter117db4b2018-03-07 16:02:21 +02002835 * @consecutive: returns true if there is data in buf_b that is consecutive
2836 * to buf_a
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002837 *
2838 * If the trace contains TSC we can look at the last TSC of @buf_a and the
2839 * first TSC of @buf_b in order to determine if the buffers overlap, and then
2840 * walk forward in @buf_b until a later TSC is found. A precondition is that
2841 * @buf_a and @buf_b are positioned at a PSB.
2842 *
2843 * Return: A pointer into @buf_b from where non-overlapped data starts, or
2844 * @buf_b + @len_b if there is no non-overlapped data.
2845 */
2846static unsigned char *intel_pt_find_overlap_tsc(unsigned char *buf_a,
2847 size_t len_a,
2848 unsigned char *buf_b,
Adrian Hunter117db4b2018-03-07 16:02:21 +02002849 size_t len_b, bool *consecutive)
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002850{
2851 uint64_t tsc_a, tsc_b;
2852 unsigned char *p;
Adrian Hunter117db4b2018-03-07 16:02:21 +02002853 size_t len, rem_a, rem_b;
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002854
2855 p = intel_pt_last_psb(buf_a, len_a);
2856 if (!p)
2857 return buf_b; /* No PSB in buf_a => no overlap */
2858
2859 len = len_a - (p - buf_a);
Adrian Hunter117db4b2018-03-07 16:02:21 +02002860 if (!intel_pt_next_tsc(p, len, &tsc_a, &rem_a)) {
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002861 /* The last PSB+ in buf_a is incomplete, so go back one more */
2862 len_a -= len;
2863 p = intel_pt_last_psb(buf_a, len_a);
2864 if (!p)
2865 return buf_b; /* No full PSB+ => assume no overlap */
2866 len = len_a - (p - buf_a);
Adrian Hunter117db4b2018-03-07 16:02:21 +02002867 if (!intel_pt_next_tsc(p, len, &tsc_a, &rem_a))
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002868 return buf_b; /* No TSC in buf_a => assume no overlap */
2869 }
2870
2871 while (1) {
2872 /* Ignore PSB+ with no TSC */
Adrian Hunter117db4b2018-03-07 16:02:21 +02002873 if (intel_pt_next_tsc(buf_b, len_b, &tsc_b, &rem_b)) {
2874 int cmp = intel_pt_tsc_cmp(tsc_a, tsc_b);
2875
2876 /* Same TSC, so buffers are consecutive */
2877 if (!cmp && rem_b >= rem_a) {
Adrian Hunter5a99d992019-02-06 12:39:44 +02002878 unsigned char *start;
2879
Adrian Hunter117db4b2018-03-07 16:02:21 +02002880 *consecutive = true;
Adrian Hunter5a99d992019-02-06 12:39:44 +02002881 start = buf_b + len_b - (rem_b - rem_a);
2882 return adj_for_padding(start, buf_a, len_a);
Adrian Hunter117db4b2018-03-07 16:02:21 +02002883 }
2884 if (cmp < 0)
2885 return buf_b; /* tsc_a < tsc_b => no overlap */
2886 }
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002887
2888 if (!intel_pt_step_psb(&buf_b, &len_b))
2889 return buf_b + len_b; /* No PSB in buf_b => no data */
2890 }
2891}
2892
2893/**
2894 * intel_pt_find_overlap - determine start of non-overlapped trace data.
2895 * @buf_a: first buffer
2896 * @len_a: size of first buffer
2897 * @buf_b: second buffer
2898 * @len_b: size of second buffer
2899 * @have_tsc: can use TSC packets to detect overlap
Adrian Hunter117db4b2018-03-07 16:02:21 +02002900 * @consecutive: returns true if there is data in buf_b that is consecutive
2901 * to buf_a
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002902 *
2903 * When trace samples or snapshots are recorded there is the possibility that
2904 * the data overlaps. Note that, for the purposes of decoding, data is only
2905 * useful if it begins with a PSB packet.
2906 *
2907 * Return: A pointer into @buf_b from where non-overlapped data starts, or
2908 * @buf_b + @len_b if there is no non-overlapped data.
2909 */
2910unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a,
2911 unsigned char *buf_b, size_t len_b,
Adrian Hunter117db4b2018-03-07 16:02:21 +02002912 bool have_tsc, bool *consecutive)
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002913{
2914 unsigned char *found;
2915
2916 /* Buffer 'b' must start at PSB so throw away everything before that */
2917 if (!intel_pt_next_psb(&buf_b, &len_b))
2918 return buf_b + len_b; /* No PSB */
2919
2920 if (!intel_pt_next_psb(&buf_a, &len_a))
2921 return buf_b; /* No overlap */
2922
2923 if (have_tsc) {
Adrian Hunter117db4b2018-03-07 16:02:21 +02002924 found = intel_pt_find_overlap_tsc(buf_a, len_a, buf_b, len_b,
2925 consecutive);
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002926 if (found)
2927 return found;
2928 }
2929
2930 /*
2931 * Buffer 'b' cannot end within buffer 'a' so, for comparison purposes,
2932 * we can ignore the first part of buffer 'a'.
2933 */
2934 while (len_b < len_a) {
2935 if (!intel_pt_step_psb(&buf_a, &len_a))
2936 return buf_b; /* No overlap */
2937 }
2938
2939 /* Now len_b >= len_a */
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002940 while (1) {
2941 /* Potential overlap so check the bytes */
2942 found = memmem(buf_a, len_a, buf_b, len_a);
Adrian Hunter117db4b2018-03-07 16:02:21 +02002943 if (found) {
2944 *consecutive = true;
Adrian Hunter5a99d992019-02-06 12:39:44 +02002945 return adj_for_padding(buf_b + len_a, buf_a, len_a);
Adrian Hunter117db4b2018-03-07 16:02:21 +02002946 }
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002947
2948 /* Try again at next PSB in buffer 'a' */
2949 if (!intel_pt_step_psb(&buf_a, &len_a))
2950 return buf_b; /* No overlap */
Adrian Hunterf4aa0812015-07-17 19:33:40 +03002951 }
2952}
Adrian Huntera7fa19f2019-06-04 16:00:06 +03002953
2954/**
2955 * struct fast_forward_data - data used by intel_pt_ff_cb().
2956 * @timestamp: timestamp to fast forward towards
2957 * @buf_timestamp: buffer timestamp of last buffer with trace data earlier than
2958 * the fast forward timestamp.
2959 */
2960struct fast_forward_data {
2961 uint64_t timestamp;
2962 uint64_t buf_timestamp;
2963};
2964
2965/**
2966 * intel_pt_ff_cb - fast forward lookahead callback.
2967 * @buffer: Intel PT trace buffer
2968 * @data: opaque pointer to fast forward data (struct fast_forward_data)
2969 *
2970 * Determine if @buffer trace is past the fast forward timestamp.
2971 *
2972 * Return: 1 (stop lookahead) if @buffer trace is past the fast forward
2973 * timestamp, and 0 otherwise.
2974 */
2975static int intel_pt_ff_cb(struct intel_pt_buffer *buffer, void *data)
2976{
2977 struct fast_forward_data *d = data;
2978 unsigned char *buf;
2979 uint64_t tsc;
2980 size_t rem;
2981 size_t len;
2982
2983 buf = (unsigned char *)buffer->buf;
2984 len = buffer->len;
2985
2986 if (!intel_pt_next_psb(&buf, &len) ||
2987 !intel_pt_next_tsc(buf, len, &tsc, &rem))
2988 return 0;
2989
2990 tsc = intel_pt_8b_tsc(tsc, buffer->ref_timestamp);
2991
2992 intel_pt_log("Buffer 1st timestamp " x64_fmt " ref timestamp " x64_fmt "\n",
2993 tsc, buffer->ref_timestamp);
2994
2995 /*
2996 * If the buffer contains a timestamp earlier that the fast forward
2997 * timestamp, then record it, else stop.
2998 */
2999 if (tsc < d->timestamp)
3000 d->buf_timestamp = buffer->ref_timestamp;
3001 else
3002 return 1;
3003
3004 return 0;
3005}
3006
3007/**
3008 * intel_pt_fast_forward - reposition decoder forwards.
3009 * @decoder: Intel PT decoder
3010 * @timestamp: timestamp to fast forward towards
3011 *
3012 * Reposition decoder at the last PSB with a timestamp earlier than @timestamp.
3013 *
3014 * Return: 0 on success or negative error code on failure.
3015 */
3016int intel_pt_fast_forward(struct intel_pt_decoder *decoder, uint64_t timestamp)
3017{
3018 struct fast_forward_data d = { .timestamp = timestamp };
3019 unsigned char *buf;
3020 size_t len;
3021 int err;
3022
3023 intel_pt_log("Fast forward towards timestamp " x64_fmt "\n", timestamp);
3024
3025 /* Find buffer timestamp of buffer to fast forward to */
3026 err = decoder->lookahead(decoder->data, intel_pt_ff_cb, &d);
3027 if (err < 0)
3028 return err;
3029
3030 /* Walk to buffer with same buffer timestamp */
3031 if (d.buf_timestamp) {
3032 do {
3033 decoder->pos += decoder->len;
3034 decoder->len = 0;
3035 err = intel_pt_get_next_data(decoder, true);
3036 /* -ENOLINK means non-consecutive trace */
3037 if (err && err != -ENOLINK)
3038 return err;
3039 } while (decoder->buf_timestamp != d.buf_timestamp);
3040 }
3041
3042 if (!decoder->buf)
3043 return 0;
3044
3045 buf = (unsigned char *)decoder->buf;
3046 len = decoder->len;
3047
3048 if (!intel_pt_next_psb(&buf, &len))
3049 return 0;
3050
3051 /*
3052 * Walk PSBs while the PSB timestamp is less than the fast forward
3053 * timestamp.
3054 */
3055 do {
3056 uint64_t tsc;
3057 size_t rem;
3058
3059 if (!intel_pt_next_tsc(buf, len, &tsc, &rem))
3060 break;
3061 tsc = intel_pt_8b_tsc(tsc, decoder->buf_timestamp);
3062 /*
3063 * A TSC packet can slip past MTC packets but, after fast
3064 * forward, decoding starts at the TSC timestamp. That means
3065 * the timestamps may not be exactly the same as the timestamps
3066 * that would have been decoded without fast forward.
3067 */
3068 if (tsc < timestamp) {
3069 intel_pt_log("Fast forward to next PSB timestamp " x64_fmt "\n", tsc);
3070 decoder->pos += decoder->len - len;
3071 decoder->buf = buf;
3072 decoder->len = len;
3073 intel_pt_reposition(decoder);
3074 } else {
3075 break;
3076 }
3077 } while (intel_pt_step_psb(&buf, &len));
3078
3079 return 0;
3080}