1 /* 2 * Copyright (c) 2014-2018, Intel Corporation 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * * Neither the name of Intel Corporation nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "pt_time.h" 30 #include "pt_opcodes.h" 31 32 #include "intel-pt.h" 33 34 #include <string.h> 35 #include <limits.h> 36 37 38 void pt_time_init(struct pt_time *time) 39 { 40 if (!time) 41 return; 42 43 memset(time, 0, sizeof(*time)); 44 } 45 46 int pt_time_query_tsc(uint64_t *tsc, uint32_t *lost_mtc, 47 uint32_t *lost_cyc, const struct pt_time *time) 48 { 49 if (!tsc || !time) 50 return -pte_internal; 51 52 *tsc = time->tsc; 53 54 if (lost_mtc) 55 *lost_mtc = time->lost_mtc; 56 if (lost_cyc) 57 *lost_cyc = time->lost_cyc; 58 59 if (!time->have_tsc) 60 return -pte_no_time; 61 62 return 0; 63 } 64 65 int pt_time_query_cbr(uint32_t *cbr, const struct pt_time *time) 66 { 67 if (!cbr || !time) 68 return -pte_internal; 69 70 if (!time->have_cbr) 71 return -pte_no_cbr; 72 73 *cbr = time->cbr; 74 75 return 0; 76 } 77 78 /* Compute the distance between two CTC sources. 79 * 80 * We adjust a single wrap-around but fail if the distance is bigger than that. 81 * 82 * Returns zero on success, a negative error code otherwise. 83 */ 84 static int pt_time_ctc_delta(uint32_t *ctc_delta, uint32_t ctc, 85 uint32_t last_ctc, const struct pt_config *config) 86 { 87 if (!config || !ctc_delta) 88 return -pte_internal; 89 90 /* Correct a single wrap-around. If we lost enough MTCs to wrap 91 * around twice, timing will be wrong until the next TSC. 92 */ 93 if (ctc < last_ctc) { 94 ctc += 1u << (config->mtc_freq + pt_pl_mtc_bit_size); 95 96 /* Since we only store the CTC between TMA/MTC or MTC/TMC a 97 * single correction should suffice. 98 */ 99 if (ctc < last_ctc) 100 return -pte_bad_packet; 101 } 102 103 *ctc_delta = ctc - last_ctc; 104 return 0; 105 } 106 107 /* Translate CTC into the same unit as the FastCounter by multiplying with P. 108 * 109 * Returns zero on success, a negative error code otherwise. 110 */ 111 static int pt_time_ctc_fc(uint64_t *fc, uint64_t ctc, 112 const struct pt_config *config) 113 { 114 uint32_t eax, ebx; 115 116 if (!fc || !config) 117 return -pte_internal; 118 119 eax = config->cpuid_0x15_eax; 120 ebx = config->cpuid_0x15_ebx; 121 122 /* Neither multiply nor divide by zero. */ 123 if (!eax || !ebx) 124 return -pte_bad_config; 125 126 *fc = (ctc * ebx) / eax; 127 return 0; 128 } 129 130 int pt_time_update_tsc(struct pt_time *time, 131 const struct pt_packet_tsc *packet, 132 const struct pt_config *config) 133 { 134 (void) config; 135 136 if (!time || !packet) 137 return -pte_internal; 138 139 time->have_tsc = 1; 140 time->have_tma = 0; 141 time->have_mtc = 0; 142 time->tsc = time->base = packet->tsc; 143 time->ctc = 0; 144 time->fc = 0ull; 145 146 /* We got the full time; we recover from previous losses. */ 147 time->lost_mtc = 0; 148 time->lost_cyc = 0; 149 150 return 0; 151 } 152 153 int pt_time_update_cbr(struct pt_time *time, 154 const struct pt_packet_cbr *packet, 155 const struct pt_config *config) 156 { 157 (void) config; 158 159 if (!time || !packet) 160 return -pte_internal; 161 162 time->have_cbr = 1; 163 time->cbr = packet->ratio; 164 165 return 0; 166 } 167 168 int pt_time_update_tma(struct pt_time *time, 169 const struct pt_packet_tma *packet, 170 const struct pt_config *config) 171 { 172 uint32_t ctc, mtc_freq, mtc_hi, ctc_mask; 173 uint64_t fc; 174 175 if (!time || !packet || !config) 176 return -pte_internal; 177 178 /* Without a TSC something is seriously wrong. */ 179 if (!time->have_tsc) 180 return -pte_bad_context; 181 182 /* We shouldn't have more than one TMA per TSC. */ 183 if (time->have_tma) 184 return -pte_bad_context; 185 186 /* We're ignoring MTC between TSC and TMA. */ 187 if (time->have_mtc) 188 return -pte_internal; 189 190 ctc = packet->ctc; 191 fc = packet->fc; 192 193 mtc_freq = config->mtc_freq; 194 mtc_hi = mtc_freq + pt_pl_mtc_bit_size; 195 196 /* A mask for the relevant CTC bits ignoring high-order bits that are 197 * not provided by MTC. 198 */ 199 ctc_mask = (1u << mtc_hi) - 1u; 200 201 time->have_tma = 1; 202 time->base -= fc; 203 time->fc += fc; 204 205 /* If the MTC frequency is low enough that TMA provides the full CTC 206 * value, we can use the TMA as an MTC. 207 * 208 * If it isn't, we will estimate the preceding MTC based on the CTC bits 209 * the TMA provides at the next MTC. We forget about the previous MTC 210 * in this case. 211 * 212 * If no MTC packets are dropped around TMA, we will estimate the 213 * forgotten value again at the next MTC. 214 * 215 * If MTC packets are dropped, we can't really tell where in this 216 * extended MTC period the TSC occurred. The estimation will place it 217 * right before the next MTC. 218 */ 219 if (mtc_hi <= pt_pl_tma_ctc_bit_size) 220 time->have_mtc = 1; 221 222 /* In both cases, we store the TMA's CTC bits until the next MTC. */ 223 time->ctc = time->ctc_cyc = ctc & ctc_mask; 224 225 return 0; 226 } 227 228 int pt_time_update_mtc(struct pt_time *time, 229 const struct pt_packet_mtc *packet, 230 const struct pt_config *config) 231 { 232 uint32_t last_ctc, ctc, ctc_delta; 233 uint64_t tsc, base; 234 uint8_t mtc_freq; 235 int errcode, have_tsc, have_tma, have_mtc; 236 237 if (!time || !packet || !config) 238 return -pte_internal; 239 240 have_tsc = time->have_tsc; 241 have_tma = time->have_tma; 242 have_mtc = time->have_mtc; 243 244 /* We ignore MTCs between TSC and TMA to avoid apparent CTC overflows. 245 * 246 * Later MTCs will ensure that no time is lost - provided TMA provides 247 * enough bits. If TMA doesn't provide any of the MTC bits we may place 248 * the TSC into the wrong MTC period. 249 */ 250 if (have_tsc && !have_tma) 251 return 0; 252 253 base = time->base; 254 last_ctc = time->ctc; 255 mtc_freq = config->mtc_freq; 256 257 ctc = packet->ctc << mtc_freq; 258 259 /* Store our CTC value if we have or would have reset FC. */ 260 if (time->fc || time->lost_cyc || !have_mtc) 261 time->ctc_cyc = ctc; 262 263 /* Prepare for the next packet in case we error out below. */ 264 time->have_mtc = 1; 265 time->fc = 0ull; 266 time->ctc = ctc; 267 268 /* We recover from previous CYC losses. */ 269 time->lost_cyc = 0; 270 271 /* Avoid a big jump when we see the first MTC with an arbitrary CTC 272 * payload. 273 */ 274 if (!have_mtc) { 275 uint32_t ctc_lo, ctc_hi; 276 277 /* If we have not seen a TMA, we ignore this first MTC. 278 * 279 * We have no idea where in this MTC period tracing started. 280 * We could lose an entire MTC period or just a tiny fraction. 281 * 282 * On the other hand, if we assumed a previous MTC value, we 283 * might make just the same error. 284 */ 285 if (!have_tma) 286 return 0; 287 288 /* The TMA's CTC value didn't provide enough bits - otherwise, 289 * we would have treated the TMA as an MTC. 290 */ 291 if (last_ctc & ~pt_pl_tma_ctc_mask) 292 return -pte_internal; 293 294 /* Split this MTC's CTC value into low and high parts with 295 * respect to the bits provided by TMA. 296 */ 297 ctc_lo = ctc & pt_pl_tma_ctc_mask; 298 ctc_hi = ctc & ~pt_pl_tma_ctc_mask; 299 300 /* We estimate the high-order CTC bits that are not provided by 301 * TMA based on the CTC bits provided by this MTC. 302 * 303 * We assume that no MTC packets were dropped around TMA. If 304 * there are, we might place the TSC into the wrong MTC period 305 * depending on how many CTC bits TMA provides and how many MTC 306 * packets were dropped. 307 * 308 * Note that we may underflow which results in more bits to be 309 * set than MTC packets may provide. Drop those extra bits. 310 */ 311 if (ctc_lo < last_ctc) { 312 ctc_hi -= 1u << pt_pl_tma_ctc_bit_size; 313 ctc_hi &= pt_pl_mtc_mask << mtc_freq; 314 } 315 316 last_ctc |= ctc_hi; 317 } 318 319 errcode = pt_time_ctc_delta(&ctc_delta, ctc, last_ctc, config); 320 if (errcode < 0) { 321 time->lost_mtc += 1; 322 return errcode; 323 } 324 325 errcode = pt_time_ctc_fc(&tsc, ctc_delta, config); 326 if (errcode < 0) 327 return errcode; 328 329 base += tsc; 330 time->tsc = time->base = base; 331 332 return 0; 333 } 334 335 /* Adjust a CYC packet's payload spanning multiple MTC periods. 336 * 337 * CYC packets measure the Fast Counter since the last CYC(-eligible) packet. 338 * Depending on the CYC threshold, we may not get a CYC for each MTC, so a CYC 339 * period may overlap with or even span multiple MTC periods. 340 * 341 * We can't do much about the overlap case without examining all packets in 342 * the respective periods. We leave this as expected imprecision. 343 * 344 * If we find a CYC packet to span multiple MTC packets, though, we try to 345 * approximate the portion for the current MTC period by subtracting the 346 * estimated portion for previous MTC periods using calibration information. 347 * 348 * We only consider MTC. For the first CYC after TSC, the corresponding TMA 349 * will contain the Fast Counter at TSC. 350 * 351 * Returns zero on success, a negative error code otherwise. 352 */ 353 static int pt_time_adjust_cyc(uint64_t *cyc, const struct pt_time *time, 354 const struct pt_config *config, uint64_t fcr) 355 { 356 uint32_t last_ctc, ctc, ctc_delta; 357 uint64_t fc, total_cyc, old_cyc; 358 int errcode; 359 360 if (!time || !config || !fcr) 361 return -pte_internal; 362 363 last_ctc = time->ctc_cyc; 364 ctc = time->ctc; 365 366 /* There is nothing to do if this is the current MTC period. */ 367 if (ctc == last_ctc) 368 return 0; 369 370 /* Calibration computes 371 * 372 * fc = (ctc_delta * cpuid[0x15].ebx) / cpuid[0x15].eax. 373 * fcr = (fc << pt_tcal_fcr_shr) / cyc 374 * 375 * So cyc = (fc << pt_tcal_fcr_shr) / fcr. 376 */ 377 378 errcode = pt_time_ctc_delta(&ctc_delta, ctc, last_ctc, config); 379 if (errcode < 0) 380 return errcode; 381 382 errcode = pt_time_ctc_fc(&fc, ctc_delta, config); 383 if (errcode < 0) 384 return errcode; 385 386 old_cyc = (fc << pt_tcal_fcr_shr) / fcr; 387 total_cyc = *cyc; 388 389 /* Make sure we don't wrap around. If we would, attribute the entire 390 * CYC payload to any previous MTC period. 391 * 392 * We lost an unknown portion of the CYC payload for the current MTC 393 * period, but it's usually better to run too slow than too fast. 394 */ 395 if (total_cyc < old_cyc) 396 total_cyc = old_cyc; 397 398 *cyc = total_cyc - old_cyc; 399 return 0; 400 } 401 402 int pt_time_update_cyc(struct pt_time *time, 403 const struct pt_packet_cyc *packet, 404 const struct pt_config *config, uint64_t fcr) 405 { 406 uint64_t cyc, fc; 407 408 if (!time || !packet || !config) 409 return -pte_internal; 410 411 if (!fcr) { 412 time->lost_cyc += 1; 413 return 0; 414 } 415 416 cyc = packet->value; 417 fc = time->fc; 418 if (!fc) { 419 int errcode; 420 421 errcode = pt_time_adjust_cyc(&cyc, time, config, fcr); 422 if (errcode < 0) 423 return errcode; 424 } 425 426 fc += (cyc * fcr) >> pt_tcal_fcr_shr; 427 428 time->fc = fc; 429 time->tsc = time->base + fc; 430 431 return 0; 432 } 433 434 void pt_tcal_init(struct pt_time_cal *tcal) 435 { 436 if (!tcal) 437 return; 438 439 memset(tcal, 0, sizeof(*tcal)); 440 441 tcal->min_fcr = UINT64_MAX; 442 } 443 444 static int pt_tcal_have_fcr(const struct pt_time_cal *tcal) 445 { 446 if (!tcal) 447 return 0; 448 449 return (tcal->min_fcr <= tcal->max_fcr); 450 } 451 452 int pt_tcal_fcr(uint64_t *fcr, const struct pt_time_cal *tcal) 453 { 454 if (!fcr || !tcal) 455 return -pte_internal; 456 457 if (!pt_tcal_have_fcr(tcal)) 458 return -pte_no_time; 459 460 *fcr = tcal->fcr; 461 462 return 0; 463 } 464 465 int pt_tcal_set_fcr(struct pt_time_cal *tcal, uint64_t fcr) 466 { 467 if (!tcal) 468 return -pte_internal; 469 470 tcal->fcr = fcr; 471 472 if (fcr < tcal->min_fcr) 473 tcal->min_fcr = fcr; 474 475 if (fcr > tcal->max_fcr) 476 tcal->max_fcr = fcr; 477 478 return 0; 479 } 480 481 int pt_tcal_update_tsc(struct pt_time_cal *tcal, 482 const struct pt_packet_tsc *packet, 483 const struct pt_config *config) 484 { 485 (void) config; 486 487 if (!tcal || !packet) 488 return -pte_internal; 489 490 /* A TSC outside of PSB+ may indicate loss of time. We do not use it 491 * for calibration. We store the TSC value for calibration at the next 492 * TSC in PSB+, though. 493 */ 494 tcal->tsc = packet->tsc; 495 tcal->cyc_tsc = 0ull; 496 497 return 0; 498 } 499 500 int pt_tcal_header_tsc(struct pt_time_cal *tcal, 501 const struct pt_packet_tsc *packet, 502 const struct pt_config *config) 503 { 504 uint64_t tsc, last_tsc, tsc_delta, cyc, fcr; 505 506 (void) config; 507 508 if (!tcal || !packet) 509 return -pte_internal; 510 511 last_tsc = tcal->tsc; 512 cyc = tcal->cyc_tsc; 513 514 tsc = packet->tsc; 515 516 tcal->tsc = tsc; 517 tcal->cyc_tsc = 0ull; 518 519 if (!last_tsc || !cyc) 520 return 0; 521 522 /* Correct a single wrap-around. */ 523 if (tsc < last_tsc) { 524 tsc += 1ull << pt_pl_tsc_bit_size; 525 526 if (tsc < last_tsc) 527 return -pte_bad_packet; 528 } 529 530 tsc_delta = tsc - last_tsc; 531 532 /* We shift the nominator to improve rounding precision. 533 * 534 * Since we're only collecting the CYCs between two TSC, we shouldn't 535 * overflow. Let's rather fail than overflow. 536 */ 537 if (tsc_delta & ~(~0ull >> pt_tcal_fcr_shr)) 538 return -pte_internal; 539 540 fcr = (tsc_delta << pt_tcal_fcr_shr) / cyc; 541 542 return pt_tcal_set_fcr(tcal, fcr); 543 } 544 545 int pt_tcal_update_cbr(struct pt_time_cal *tcal, 546 const struct pt_packet_cbr *packet, 547 const struct pt_config *config) 548 { 549 /* A CBR outside of PSB+ indicates a frequency change. Reset our 550 * calibration state. 551 */ 552 pt_tcal_init(tcal); 553 554 return pt_tcal_header_cbr(tcal, packet, config); 555 } 556 557 int pt_tcal_header_cbr(struct pt_time_cal *tcal, 558 const struct pt_packet_cbr *packet, 559 const struct pt_config *config) 560 { 561 uint64_t cbr, p1, fcr; 562 563 if (!tcal || !packet || !config) 564 return -pte_internal; 565 566 p1 = config->nom_freq; 567 if (!p1) 568 return 0; 569 570 /* If we know the nominal frequency, we can use it for calibration. */ 571 cbr = packet->ratio; 572 573 fcr = (p1 << pt_tcal_fcr_shr) / cbr; 574 575 return pt_tcal_set_fcr(tcal, fcr); 576 } 577 578 int pt_tcal_update_tma(struct pt_time_cal *tcal, 579 const struct pt_packet_tma *packet, 580 const struct pt_config *config) 581 { 582 (void) tcal; 583 (void) packet; 584 (void) config; 585 586 /* Nothing to do. */ 587 return 0; 588 } 589 590 int pt_tcal_update_mtc(struct pt_time_cal *tcal, 591 const struct pt_packet_mtc *packet, 592 const struct pt_config *config) 593 { 594 uint32_t last_ctc, ctc, ctc_delta, have_mtc; 595 uint64_t cyc, fc, fcr; 596 int errcode; 597 598 if (!tcal || !packet || !config) 599 return -pte_internal; 600 601 last_ctc = tcal->ctc; 602 have_mtc = tcal->have_mtc; 603 cyc = tcal->cyc_mtc; 604 605 ctc = packet->ctc << config->mtc_freq; 606 607 /* We need at least two MTC (including this). */ 608 if (!have_mtc) { 609 tcal->cyc_mtc = 0ull; 610 tcal->ctc = ctc; 611 tcal->have_mtc = 1; 612 613 return 0; 614 } 615 616 /* Without any cycles, we can't calibrate. Try again at the next 617 * MTC and distribute the cycles over the combined MTC period. 618 */ 619 if (!cyc) 620 return 0; 621 622 /* Prepare for the next packet in case we error out below. */ 623 tcal->have_mtc = 1; 624 tcal->cyc_mtc = 0ull; 625 tcal->ctc = ctc; 626 627 /* Let's pretend we will fail. We'll correct it at the end. */ 628 tcal->lost_mtc += 1; 629 630 errcode = pt_time_ctc_delta(&ctc_delta, ctc, last_ctc, config); 631 if (errcode < 0) 632 return errcode; 633 634 errcode = pt_time_ctc_fc(&fc, ctc_delta, config); 635 if (errcode < 0) 636 return errcode; 637 638 /* We shift the nominator to improve rounding precision. 639 * 640 * Since we're only collecting the CYCs between two MTC, we shouldn't 641 * overflow. Let's rather fail than overflow. 642 */ 643 if (fc & ~(~0ull >> pt_tcal_fcr_shr)) 644 return -pte_internal; 645 646 fcr = (fc << pt_tcal_fcr_shr) / cyc; 647 648 errcode = pt_tcal_set_fcr(tcal, fcr); 649 if (errcode < 0) 650 return errcode; 651 652 /* We updated the FCR. This recovers from previous MTC losses. */ 653 tcal->lost_mtc = 0; 654 655 return 0; 656 } 657 658 int pt_tcal_update_cyc(struct pt_time_cal *tcal, 659 const struct pt_packet_cyc *packet, 660 const struct pt_config *config) 661 { 662 uint64_t cyc; 663 664 (void) config; 665 666 if (!tcal || !packet) 667 return -pte_internal; 668 669 cyc = packet->value; 670 tcal->cyc_mtc += cyc; 671 tcal->cyc_tsc += cyc; 672 673 return 0; 674 } 675