diff options
Diffstat (limited to 'tools/perf/util/intel-pt-decoder/intel-pt-decoder.c')
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 304 |
1 files changed, 276 insertions, 28 deletions
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c index 7cf7f7aca4d2..aa1593ce551d 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | |||
| @@ -64,6 +64,25 @@ enum intel_pt_pkt_state { | |||
| 64 | INTEL_PT_STATE_FUP_NO_TIP, | 64 | INTEL_PT_STATE_FUP_NO_TIP, |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | static inline bool intel_pt_sample_time(enum intel_pt_pkt_state pkt_state) | ||
| 68 | { | ||
| 69 | switch (pkt_state) { | ||
| 70 | case INTEL_PT_STATE_NO_PSB: | ||
| 71 | case INTEL_PT_STATE_NO_IP: | ||
| 72 | case INTEL_PT_STATE_ERR_RESYNC: | ||
| 73 | case INTEL_PT_STATE_IN_SYNC: | ||
| 74 | case INTEL_PT_STATE_TNT: | ||
| 75 | return true; | ||
| 76 | case INTEL_PT_STATE_TIP: | ||
| 77 | case INTEL_PT_STATE_TIP_PGD: | ||
| 78 | case INTEL_PT_STATE_FUP: | ||
| 79 | case INTEL_PT_STATE_FUP_NO_TIP: | ||
| 80 | return false; | ||
| 81 | default: | ||
| 82 | return true; | ||
| 83 | }; | ||
| 84 | } | ||
| 85 | |||
| 67 | #ifdef INTEL_PT_STRICT | 86 | #ifdef INTEL_PT_STRICT |
| 68 | #define INTEL_PT_STATE_ERR1 INTEL_PT_STATE_NO_PSB | 87 | #define INTEL_PT_STATE_ERR1 INTEL_PT_STATE_NO_PSB |
| 69 | #define INTEL_PT_STATE_ERR2 INTEL_PT_STATE_NO_PSB | 88 | #define INTEL_PT_STATE_ERR2 INTEL_PT_STATE_NO_PSB |
| @@ -87,11 +106,13 @@ struct intel_pt_decoder { | |||
| 87 | const unsigned char *buf; | 106 | const unsigned char *buf; |
| 88 | size_t len; | 107 | size_t len; |
| 89 | bool return_compression; | 108 | bool return_compression; |
| 109 | bool branch_enable; | ||
| 90 | bool mtc_insn; | 110 | bool mtc_insn; |
| 91 | bool pge; | 111 | bool pge; |
| 92 | bool have_tma; | 112 | bool have_tma; |
| 93 | bool have_cyc; | 113 | bool have_cyc; |
| 94 | bool fixup_last_mtc; | 114 | bool fixup_last_mtc; |
| 115 | bool have_last_ip; | ||
| 95 | uint64_t pos; | 116 | uint64_t pos; |
| 96 | uint64_t last_ip; | 117 | uint64_t last_ip; |
| 97 | uint64_t ip; | 118 | uint64_t ip; |
| @@ -99,6 +120,7 @@ struct intel_pt_decoder { | |||
| 99 | uint64_t timestamp; | 120 | uint64_t timestamp; |
| 100 | uint64_t tsc_timestamp; | 121 | uint64_t tsc_timestamp; |
| 101 | uint64_t ref_timestamp; | 122 | uint64_t ref_timestamp; |
| 123 | uint64_t sample_timestamp; | ||
| 102 | uint64_t ret_addr; | 124 | uint64_t ret_addr; |
| 103 | uint64_t ctc_timestamp; | 125 | uint64_t ctc_timestamp; |
| 104 | uint64_t ctc_delta; | 126 | uint64_t ctc_delta; |
| @@ -119,6 +141,7 @@ struct intel_pt_decoder { | |||
| 119 | int pkt_len; | 141 | int pkt_len; |
| 120 | int last_packet_type; | 142 | int last_packet_type; |
| 121 | unsigned int cbr; | 143 | unsigned int cbr; |
| 144 | unsigned int cbr_seen; | ||
| 122 | unsigned int max_non_turbo_ratio; | 145 | unsigned int max_non_turbo_ratio; |
| 123 | double max_non_turbo_ratio_fp; | 146 | double max_non_turbo_ratio_fp; |
| 124 | double cbr_cyc_to_tsc; | 147 | double cbr_cyc_to_tsc; |
| @@ -136,9 +159,18 @@ struct intel_pt_decoder { | |||
| 136 | bool continuous_period; | 159 | bool continuous_period; |
| 137 | bool overflow; | 160 | bool overflow; |
| 138 | bool set_fup_tx_flags; | 161 | bool set_fup_tx_flags; |
| 162 | bool set_fup_ptw; | ||
| 163 | bool set_fup_mwait; | ||
| 164 | bool set_fup_pwre; | ||
| 165 | bool set_fup_exstop; | ||
| 139 | unsigned int fup_tx_flags; | 166 | unsigned int fup_tx_flags; |
| 140 | unsigned int tx_flags; | 167 | unsigned int tx_flags; |
| 168 | uint64_t fup_ptw_payload; | ||
| 169 | uint64_t fup_mwait_payload; | ||
| 170 | uint64_t fup_pwre_payload; | ||
| 171 | uint64_t cbr_payload; | ||
| 141 | uint64_t timestamp_insn_cnt; | 172 | uint64_t timestamp_insn_cnt; |
| 173 | uint64_t sample_insn_cnt; | ||
| 142 | uint64_t stuck_ip; | 174 | uint64_t stuck_ip; |
| 143 | int no_progress; | 175 | int no_progress; |
| 144 | int stuck_ip_prd; | 176 | int stuck_ip_prd; |
| @@ -192,6 +224,7 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params) | |||
| 192 | decoder->pgd_ip = params->pgd_ip; | 224 | decoder->pgd_ip = params->pgd_ip; |
| 193 | decoder->data = params->data; | 225 | decoder->data = params->data; |
| 194 | decoder->return_compression = params->return_compression; | 226 | decoder->return_compression = params->return_compression; |
| 227 | decoder->branch_enable = params->branch_enable; | ||
| 195 | 228 | ||
| 196 | decoder->period = params->period; | 229 | decoder->period = params->period; |
| 197 | decoder->period_type = params->period_type; | 230 | decoder->period_type = params->period_type; |
| @@ -398,6 +431,7 @@ static uint64_t intel_pt_calc_ip(const struct intel_pt_pkt *packet, | |||
| 398 | static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder) | 431 | static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder) |
| 399 | { | 432 | { |
| 400 | decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip); | 433 | decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip); |
| 434 | decoder->have_last_ip = true; | ||
| 401 | } | 435 | } |
| 402 | 436 | ||
| 403 | static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder) | 437 | static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder) |
| @@ -635,6 +669,8 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) | |||
| 635 | case INTEL_PT_PAD: | 669 | case INTEL_PT_PAD: |
| 636 | case INTEL_PT_VMCS: | 670 | case INTEL_PT_VMCS: |
| 637 | case INTEL_PT_MNT: | 671 | case INTEL_PT_MNT: |
| 672 | case INTEL_PT_PTWRITE: | ||
| 673 | case INTEL_PT_PTWRITE_IP: | ||
| 638 | return 0; | 674 | return 0; |
| 639 | 675 | ||
| 640 | case INTEL_PT_MTC: | 676 | case INTEL_PT_MTC: |
| @@ -675,6 +711,12 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) | |||
| 675 | break; | 711 | break; |
| 676 | 712 | ||
| 677 | case INTEL_PT_TSC: | 713 | case INTEL_PT_TSC: |
| 714 | /* | ||
| 715 | * For now, do not support using TSC packets - refer | ||
| 716 | * intel_pt_calc_cyc_to_tsc(). | ||
| 717 | */ | ||
| 718 | if (data->from_mtc) | ||
| 719 | return 1; | ||
| 678 | timestamp = pkt_info->packet.payload | | 720 | timestamp = pkt_info->packet.payload | |
| 679 | (data->timestamp & (0xffULL << 56)); | 721 | (data->timestamp & (0xffULL << 56)); |
| 680 | if (data->from_mtc && timestamp < data->timestamp && | 722 | if (data->from_mtc && timestamp < data->timestamp && |
| @@ -733,6 +775,11 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) | |||
| 733 | 775 | ||
| 734 | case INTEL_PT_TIP_PGD: | 776 | case INTEL_PT_TIP_PGD: |
| 735 | case INTEL_PT_TRACESTOP: | 777 | case INTEL_PT_TRACESTOP: |
| 778 | case INTEL_PT_EXSTOP: | ||
| 779 | case INTEL_PT_EXSTOP_IP: | ||
| 780 | case INTEL_PT_MWAIT: | ||
| 781 | case INTEL_PT_PWRE: | ||
| 782 | case INTEL_PT_PWRX: | ||
| 736 | case INTEL_PT_OVF: | 783 | case INTEL_PT_OVF: |
| 737 | case INTEL_PT_BAD: /* Does not happen */ | 784 | case INTEL_PT_BAD: /* Does not happen */ |
| 738 | default: | 785 | default: |
| @@ -787,6 +834,14 @@ static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder, | |||
| 787 | .cbr_cyc_to_tsc = 0, | 834 | .cbr_cyc_to_tsc = 0, |
| 788 | }; | 835 | }; |
| 789 | 836 | ||
| 837 | /* | ||
| 838 | * For now, do not support using TSC packets for at least the reasons: | ||
| 839 | * 1) timing might have stopped | ||
| 840 | * 2) TSC packets within PSB+ can slip against CYC packets | ||
| 841 | */ | ||
| 842 | if (!from_mtc) | ||
| 843 | return; | ||
| 844 | |||
| 790 | intel_pt_pkt_lookahead(decoder, intel_pt_calc_cyc_cb, &data); | 845 | intel_pt_pkt_lookahead(decoder, intel_pt_calc_cyc_cb, &data); |
| 791 | } | 846 | } |
| 792 | 847 | ||
| @@ -898,6 +953,7 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder, | |||
| 898 | 953 | ||
| 899 | decoder->tot_insn_cnt += insn_cnt; | 954 | decoder->tot_insn_cnt += insn_cnt; |
| 900 | decoder->timestamp_insn_cnt += insn_cnt; | 955 | decoder->timestamp_insn_cnt += insn_cnt; |
| 956 | decoder->sample_insn_cnt += insn_cnt; | ||
| 901 | decoder->period_insn_cnt += insn_cnt; | 957 | decoder->period_insn_cnt += insn_cnt; |
| 902 | 958 | ||
| 903 | if (err) { | 959 | if (err) { |
| @@ -990,6 +1046,57 @@ out_no_progress: | |||
| 990 | return err; | 1046 | return err; |
| 991 | } | 1047 | } |
| 992 | 1048 | ||
| 1049 | static bool intel_pt_fup_event(struct intel_pt_decoder *decoder) | ||
| 1050 | { | ||
| 1051 | bool ret = false; | ||
| 1052 | |||
| 1053 | if (decoder->set_fup_tx_flags) { | ||
| 1054 | decoder->set_fup_tx_flags = false; | ||
| 1055 | decoder->tx_flags = decoder->fup_tx_flags; | ||
| 1056 | decoder->state.type = INTEL_PT_TRANSACTION; | ||
| 1057 | decoder->state.from_ip = decoder->ip; | ||
| 1058 | decoder->state.to_ip = 0; | ||
| 1059 | decoder->state.flags = decoder->fup_tx_flags; | ||
| 1060 | return true; | ||
| 1061 | } | ||
| 1062 | if (decoder->set_fup_ptw) { | ||
| 1063 | decoder->set_fup_ptw = false; | ||
| 1064 | decoder->state.type = INTEL_PT_PTW; | ||
| 1065 | decoder->state.flags |= INTEL_PT_FUP_IP; | ||
| 1066 | decoder->state.from_ip = decoder->ip; | ||
| 1067 | decoder->state.to_ip = 0; | ||
| 1068 | decoder->state.ptw_payload = decoder->fup_ptw_payload; | ||
| 1069 | return true; | ||
| 1070 | } | ||
| 1071 | if (decoder->set_fup_mwait) { | ||
| 1072 | decoder->set_fup_mwait = false; | ||
| 1073 | decoder->state.type = INTEL_PT_MWAIT_OP; | ||
| 1074 | decoder->state.from_ip = decoder->ip; | ||
| 1075 | decoder->state.to_ip = 0; | ||
| 1076 | decoder->state.mwait_payload = decoder->fup_mwait_payload; | ||
| 1077 | ret = true; | ||
| 1078 | } | ||
| 1079 | if (decoder->set_fup_pwre) { | ||
| 1080 | decoder->set_fup_pwre = false; | ||
| 1081 | decoder->state.type |= INTEL_PT_PWR_ENTRY; | ||
| 1082 | decoder->state.type &= ~INTEL_PT_BRANCH; | ||
| 1083 | decoder->state.from_ip = decoder->ip; | ||
| 1084 | decoder->state.to_ip = 0; | ||
| 1085 | decoder->state.pwre_payload = decoder->fup_pwre_payload; | ||
| 1086 | ret = true; | ||
| 1087 | } | ||
| 1088 | if (decoder->set_fup_exstop) { | ||
| 1089 | decoder->set_fup_exstop = false; | ||
| 1090 | decoder->state.type |= INTEL_PT_EX_STOP; | ||
| 1091 | decoder->state.type &= ~INTEL_PT_BRANCH; | ||
| 1092 | decoder->state.flags |= INTEL_PT_FUP_IP; | ||
| 1093 | decoder->state.from_ip = decoder->ip; | ||
| 1094 | decoder->state.to_ip = 0; | ||
| 1095 | ret = true; | ||
| 1096 | } | ||
| 1097 | return ret; | ||
| 1098 | } | ||
| 1099 | |||
| 993 | static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) | 1100 | static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) |
| 994 | { | 1101 | { |
| 995 | struct intel_pt_insn intel_pt_insn; | 1102 | struct intel_pt_insn intel_pt_insn; |
| @@ -1003,15 +1110,8 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) | |||
| 1003 | if (err == INTEL_PT_RETURN) | 1110 | if (err == INTEL_PT_RETURN) |
| 1004 | return 0; | 1111 | return 0; |
| 1005 | if (err == -EAGAIN) { | 1112 | if (err == -EAGAIN) { |
| 1006 | if (decoder->set_fup_tx_flags) { | 1113 | if (intel_pt_fup_event(decoder)) |
| 1007 | decoder->set_fup_tx_flags = false; | ||
| 1008 | decoder->tx_flags = decoder->fup_tx_flags; | ||
| 1009 | decoder->state.type = INTEL_PT_TRANSACTION; | ||
| 1010 | decoder->state.from_ip = decoder->ip; | ||
| 1011 | decoder->state.to_ip = 0; | ||
| 1012 | decoder->state.flags = decoder->fup_tx_flags; | ||
| 1013 | return 0; | 1114 | return 0; |
| 1014 | } | ||
| 1015 | return err; | 1115 | return err; |
| 1016 | } | 1116 | } |
| 1017 | decoder->set_fup_tx_flags = false; | 1117 | decoder->set_fup_tx_flags = false; |
| @@ -1360,7 +1460,9 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder) | |||
| 1360 | 1460 | ||
| 1361 | static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder) | 1461 | static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder) |
| 1362 | { | 1462 | { |
| 1363 | unsigned int cbr = decoder->packet.payload; | 1463 | unsigned int cbr = decoder->packet.payload & 0xff; |
| 1464 | |||
| 1465 | decoder->cbr_payload = decoder->packet.payload; | ||
| 1364 | 1466 | ||
| 1365 | if (decoder->cbr == cbr) | 1467 | if (decoder->cbr == cbr) |
| 1366 | return; | 1468 | return; |
| @@ -1417,6 +1519,13 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder) | |||
| 1417 | case INTEL_PT_TRACESTOP: | 1519 | case INTEL_PT_TRACESTOP: |
| 1418 | case INTEL_PT_BAD: | 1520 | case INTEL_PT_BAD: |
| 1419 | case INTEL_PT_PSB: | 1521 | case INTEL_PT_PSB: |
| 1522 | case INTEL_PT_PTWRITE: | ||
| 1523 | case INTEL_PT_PTWRITE_IP: | ||
| 1524 | case INTEL_PT_EXSTOP: | ||
| 1525 | case INTEL_PT_EXSTOP_IP: | ||
| 1526 | case INTEL_PT_MWAIT: | ||
| 1527 | case INTEL_PT_PWRE: | ||
| 1528 | case INTEL_PT_PWRX: | ||
| 1420 | decoder->have_tma = false; | 1529 | decoder->have_tma = false; |
| 1421 | intel_pt_log("ERROR: Unexpected packet\n"); | 1530 | intel_pt_log("ERROR: Unexpected packet\n"); |
| 1422 | return -EAGAIN; | 1531 | return -EAGAIN; |
| @@ -1446,7 +1555,8 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder) | |||
| 1446 | 1555 | ||
| 1447 | case INTEL_PT_FUP: | 1556 | case INTEL_PT_FUP: |
| 1448 | decoder->pge = true; | 1557 | decoder->pge = true; |
| 1449 | intel_pt_set_last_ip(decoder); | 1558 | if (decoder->packet.count) |
| 1559 | intel_pt_set_last_ip(decoder); | ||
| 1450 | break; | 1560 | break; |
| 1451 | 1561 | ||
| 1452 | case INTEL_PT_MODE_TSX: | 1562 | case INTEL_PT_MODE_TSX: |
| @@ -1497,6 +1607,13 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder) | |||
| 1497 | case INTEL_PT_MODE_TSX: | 1607 | case INTEL_PT_MODE_TSX: |
| 1498 | case INTEL_PT_BAD: | 1608 | case INTEL_PT_BAD: |
| 1499 | case INTEL_PT_PSBEND: | 1609 | case INTEL_PT_PSBEND: |
| 1610 | case INTEL_PT_PTWRITE: | ||
| 1611 | case INTEL_PT_PTWRITE_IP: | ||
| 1612 | case INTEL_PT_EXSTOP: | ||
| 1613 | case INTEL_PT_EXSTOP_IP: | ||
| 1614 | case INTEL_PT_MWAIT: | ||
| 1615 | case INTEL_PT_PWRE: | ||
| 1616 | case INTEL_PT_PWRX: | ||
| 1500 | intel_pt_log("ERROR: Missing TIP after FUP\n"); | 1617 | intel_pt_log("ERROR: Missing TIP after FUP\n"); |
| 1501 | decoder->pkt_state = INTEL_PT_STATE_ERR3; | 1618 | decoder->pkt_state = INTEL_PT_STATE_ERR3; |
| 1502 | return -ENOENT; | 1619 | return -ENOENT; |
| @@ -1625,6 +1742,15 @@ next: | |||
| 1625 | break; | 1742 | break; |
| 1626 | } | 1743 | } |
| 1627 | intel_pt_set_last_ip(decoder); | 1744 | intel_pt_set_last_ip(decoder); |
| 1745 | if (!decoder->branch_enable) { | ||
| 1746 | decoder->ip = decoder->last_ip; | ||
| 1747 | if (intel_pt_fup_event(decoder)) | ||
| 1748 | return 0; | ||
| 1749 | no_tip = false; | ||
| 1750 | break; | ||
| 1751 | } | ||
| 1752 | if (decoder->set_fup_mwait) | ||
| 1753 | no_tip = true; | ||
| 1628 | err = intel_pt_walk_fup(decoder); | 1754 | err = intel_pt_walk_fup(decoder); |
| 1629 | if (err != -EAGAIN) { | 1755 | if (err != -EAGAIN) { |
| 1630 | if (err) | 1756 | if (err) |
| @@ -1650,6 +1776,8 @@ next: | |||
| 1650 | break; | 1776 | break; |
| 1651 | 1777 | ||
| 1652 | case INTEL_PT_PSB: | 1778 | case INTEL_PT_PSB: |
| 1779 | decoder->last_ip = 0; | ||
| 1780 | decoder->have_last_ip = true; | ||
| 1653 | intel_pt_clear_stack(&decoder->stack); | 1781 | intel_pt_clear_stack(&decoder->stack); |
| 1654 | err = intel_pt_walk_psbend(decoder); | 1782 | err = intel_pt_walk_psbend(decoder); |
| 1655 | if (err == -EAGAIN) | 1783 | if (err == -EAGAIN) |
| @@ -1696,6 +1824,16 @@ next: | |||
| 1696 | 1824 | ||
| 1697 | case INTEL_PT_CBR: | 1825 | case INTEL_PT_CBR: |
| 1698 | intel_pt_calc_cbr(decoder); | 1826 | intel_pt_calc_cbr(decoder); |
| 1827 | if (!decoder->branch_enable && | ||
| 1828 | decoder->cbr != decoder->cbr_seen) { | ||
| 1829 | decoder->cbr_seen = decoder->cbr; | ||
| 1830 | decoder->state.type = INTEL_PT_CBR_CHG; | ||
| 1831 | decoder->state.from_ip = decoder->ip; | ||
| 1832 | decoder->state.to_ip = 0; | ||
| 1833 | decoder->state.cbr_payload = | ||
| 1834 | decoder->packet.payload; | ||
| 1835 | return 0; | ||
| 1836 | } | ||
| 1699 | break; | 1837 | break; |
| 1700 | 1838 | ||
| 1701 | case INTEL_PT_MODE_EXEC: | 1839 | case INTEL_PT_MODE_EXEC: |
| @@ -1722,6 +1860,71 @@ next: | |||
| 1722 | case INTEL_PT_PAD: | 1860 | case INTEL_PT_PAD: |
| 1723 | break; | 1861 | break; |
| 1724 | 1862 | ||
| 1863 | case INTEL_PT_PTWRITE_IP: | ||
| 1864 | decoder->fup_ptw_payload = decoder->packet.payload; | ||
| 1865 | err = intel_pt_get_next_packet(decoder); | ||
| 1866 | if (err) | ||
| 1867 | return err; | ||
| 1868 | if (decoder->packet.type == INTEL_PT_FUP) { | ||
| 1869 | decoder->set_fup_ptw = true; | ||
| 1870 | no_tip = true; | ||
| 1871 | } else { | ||
| 1872 | intel_pt_log_at("ERROR: Missing FUP after PTWRITE", | ||
| 1873 | decoder->pos); | ||
| 1874 | } | ||
| 1875 | goto next; | ||
| 1876 | |||
| 1877 | case INTEL_PT_PTWRITE: | ||
| 1878 | decoder->state.type = INTEL_PT_PTW; | ||
| 1879 | decoder->state.from_ip = decoder->ip; | ||
| 1880 | decoder->state.to_ip = 0; | ||
| 1881 | decoder->state.ptw_payload = decoder->packet.payload; | ||
| 1882 | return 0; | ||
| 1883 | |||
| 1884 | case INTEL_PT_MWAIT: | ||
| 1885 | decoder->fup_mwait_payload = decoder->packet.payload; | ||
| 1886 | decoder->set_fup_mwait = true; | ||
| 1887 | break; | ||
| 1888 | |||
| 1889 | case INTEL_PT_PWRE: | ||
| 1890 | if (decoder->set_fup_mwait) { | ||
| 1891 | decoder->fup_pwre_payload = | ||
| 1892 | decoder->packet.payload; | ||
| 1893 | decoder->set_fup_pwre = true; | ||
| 1894 | break; | ||
| 1895 | } | ||
| 1896 | decoder->state.type = INTEL_PT_PWR_ENTRY; | ||
| 1897 | decoder->state.from_ip = decoder->ip; | ||
| 1898 | decoder->state.to_ip = 0; | ||
| 1899 | decoder->state.pwrx_payload = decoder->packet.payload; | ||
| 1900 | return 0; | ||
| 1901 | |||
| 1902 | case INTEL_PT_EXSTOP_IP: | ||
| 1903 | err = intel_pt_get_next_packet(decoder); | ||
| 1904 | if (err) | ||
| 1905 | return err; | ||
| 1906 | if (decoder->packet.type == INTEL_PT_FUP) { | ||
| 1907 | decoder->set_fup_exstop = true; | ||
| 1908 | no_tip = true; | ||
| 1909 | } else { | ||
| 1910 | intel_pt_log_at("ERROR: Missing FUP after EXSTOP", | ||
| 1911 | decoder->pos); | ||
| 1912 | } | ||
| 1913 | goto next; | ||
| 1914 | |||
| 1915 | case INTEL_PT_EXSTOP: | ||
| 1916 | decoder->state.type = INTEL_PT_EX_STOP; | ||
| 1917 | decoder->state.from_ip = decoder->ip; | ||
| 1918 | decoder->state.to_ip = 0; | ||
| 1919 | return 0; | ||
| 1920 | |||
| 1921 | case INTEL_PT_PWRX: | ||
| 1922 | decoder->state.type = INTEL_PT_PWR_EXIT; | ||
| 1923 | decoder->state.from_ip = decoder->ip; | ||
| 1924 | decoder->state.to_ip = 0; | ||
| 1925 | decoder->state.pwrx_payload = decoder->packet.payload; | ||
| 1926 | return 0; | ||
| 1927 | |||
| 1725 | default: | 1928 | default: |
| 1726 | return intel_pt_bug(decoder); | 1929 | return intel_pt_bug(decoder); |
| 1727 | } | 1930 | } |
| @@ -1730,8 +1933,9 @@ next: | |||
| 1730 | 1933 | ||
| 1731 | static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder) | 1934 | static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder) |
| 1732 | { | 1935 | { |
| 1733 | return decoder->last_ip || decoder->packet.count == 0 || | 1936 | return decoder->packet.count && |
| 1734 | decoder->packet.count == 3 || decoder->packet.count == 6; | 1937 | (decoder->have_last_ip || decoder->packet.count == 3 || |
| 1938 | decoder->packet.count == 6); | ||
| 1735 | } | 1939 | } |
| 1736 | 1940 | ||
| 1737 | /* Walk PSB+ packets to get in sync. */ | 1941 | /* Walk PSB+ packets to get in sync. */ |
| @@ -1750,6 +1954,13 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder) | |||
| 1750 | __fallthrough; | 1954 | __fallthrough; |
| 1751 | case INTEL_PT_TIP_PGE: | 1955 | case INTEL_PT_TIP_PGE: |
| 1752 | case INTEL_PT_TIP: | 1956 | case INTEL_PT_TIP: |
| 1957 | case INTEL_PT_PTWRITE: | ||
| 1958 | case INTEL_PT_PTWRITE_IP: | ||
| 1959 | case INTEL_PT_EXSTOP: | ||
| 1960 | case INTEL_PT_EXSTOP_IP: | ||
| 1961 | case INTEL_PT_MWAIT: | ||
| 1962 | case INTEL_PT_PWRE: | ||
| 1963 | case INTEL_PT_PWRX: | ||
| 1753 | intel_pt_log("ERROR: Unexpected packet\n"); | 1964 | intel_pt_log("ERROR: Unexpected packet\n"); |
| 1754 | return -ENOENT; | 1965 | return -ENOENT; |
| 1755 | 1966 | ||
| @@ -1854,14 +2065,10 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder) | |||
| 1854 | break; | 2065 | break; |
| 1855 | 2066 | ||
| 1856 | case INTEL_PT_FUP: | 2067 | case INTEL_PT_FUP: |
| 1857 | if (decoder->overflow) { | 2068 | if (intel_pt_have_ip(decoder)) |
| 1858 | if (intel_pt_have_ip(decoder)) | 2069 | intel_pt_set_ip(decoder); |
| 1859 | intel_pt_set_ip(decoder); | 2070 | if (decoder->ip) |
| 1860 | if (decoder->ip) | 2071 | return 0; |
| 1861 | return 0; | ||
| 1862 | } | ||
| 1863 | if (decoder->packet.count) | ||
| 1864 | intel_pt_set_last_ip(decoder); | ||
| 1865 | break; | 2072 | break; |
| 1866 | 2073 | ||
| 1867 | case INTEL_PT_MTC: | 2074 | case INTEL_PT_MTC: |
| @@ -1910,6 +2117,9 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder) | |||
| 1910 | break; | 2117 | break; |
| 1911 | 2118 | ||
| 1912 | case INTEL_PT_PSB: | 2119 | case INTEL_PT_PSB: |
| 2120 | decoder->last_ip = 0; | ||
| 2121 | decoder->have_last_ip = true; | ||
| 2122 | intel_pt_clear_stack(&decoder->stack); | ||
| 1913 | err = intel_pt_walk_psb(decoder); | 2123 | err = intel_pt_walk_psb(decoder); |
| 1914 | if (err) | 2124 | if (err) |
| 1915 | return err; | 2125 | return err; |
| @@ -1925,6 +2135,13 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder) | |||
| 1925 | case INTEL_PT_VMCS: | 2135 | case INTEL_PT_VMCS: |
| 1926 | case INTEL_PT_MNT: | 2136 | case INTEL_PT_MNT: |
| 1927 | case INTEL_PT_PAD: | 2137 | case INTEL_PT_PAD: |
| 2138 | case INTEL_PT_PTWRITE: | ||
| 2139 | case INTEL_PT_PTWRITE_IP: | ||
| 2140 | case INTEL_PT_EXSTOP: | ||
| 2141 | case INTEL_PT_EXSTOP_IP: | ||
| 2142 | case INTEL_PT_MWAIT: | ||
| 2143 | case INTEL_PT_PWRE: | ||
| 2144 | case INTEL_PT_PWRX: | ||
| 1928 | default: | 2145 | default: |
| 1929 | break; | 2146 | break; |
| 1930 | } | 2147 | } |
| @@ -1935,6 +2152,19 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder) | |||
| 1935 | { | 2152 | { |
| 1936 | int err; | 2153 | int err; |
| 1937 | 2154 | ||
| 2155 | decoder->set_fup_tx_flags = false; | ||
| 2156 | decoder->set_fup_ptw = false; | ||
| 2157 | decoder->set_fup_mwait = false; | ||
| 2158 | decoder->set_fup_pwre = false; | ||
| 2159 | decoder->set_fup_exstop = false; | ||
| 2160 | |||
| 2161 | if (!decoder->branch_enable) { | ||
| 2162 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; | ||
| 2163 | decoder->overflow = false; | ||
| 2164 | decoder->state.type = 0; /* Do not have a sample */ | ||
| 2165 | return 0; | ||
| 2166 | } | ||
| 2167 | |||
| 1938 | intel_pt_log("Scanning for full IP\n"); | 2168 | intel_pt_log("Scanning for full IP\n"); |
| 1939 | err = intel_pt_walk_to_ip(decoder); | 2169 | err = intel_pt_walk_to_ip(decoder); |
| 1940 | if (err) | 2170 | if (err) |
| @@ -2043,6 +2273,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder) | |||
| 2043 | 2273 | ||
| 2044 | decoder->pge = false; | 2274 | decoder->pge = false; |
| 2045 | decoder->continuous_period = false; | 2275 | decoder->continuous_period = false; |
| 2276 | decoder->have_last_ip = false; | ||
| 2046 | decoder->last_ip = 0; | 2277 | decoder->last_ip = 0; |
| 2047 | decoder->ip = 0; | 2278 | decoder->ip = 0; |
| 2048 | intel_pt_clear_stack(&decoder->stack); | 2279 | intel_pt_clear_stack(&decoder->stack); |
| @@ -2051,6 +2282,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder) | |||
| 2051 | if (err) | 2282 | if (err) |
| 2052 | return err; | 2283 | return err; |
| 2053 | 2284 | ||
| 2285 | decoder->have_last_ip = true; | ||
| 2054 | decoder->pkt_state = INTEL_PT_STATE_NO_IP; | 2286 | decoder->pkt_state = INTEL_PT_STATE_NO_IP; |
| 2055 | 2287 | ||
| 2056 | err = intel_pt_walk_psb(decoder); | 2288 | err = intel_pt_walk_psb(decoder); |
| @@ -2069,7 +2301,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder) | |||
| 2069 | 2301 | ||
| 2070 | static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder) | 2302 | static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder) |
| 2071 | { | 2303 | { |
| 2072 | uint64_t est = decoder->timestamp_insn_cnt << 1; | 2304 | uint64_t est = decoder->sample_insn_cnt << 1; |
| 2073 | 2305 | ||
| 2074 | if (!decoder->cbr || !decoder->max_non_turbo_ratio) | 2306 | if (!decoder->cbr || !decoder->max_non_turbo_ratio) |
| 2075 | goto out; | 2307 | goto out; |
| @@ -2077,7 +2309,7 @@ static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder) | |||
| 2077 | est *= decoder->max_non_turbo_ratio; | 2309 | est *= decoder->max_non_turbo_ratio; |
| 2078 | est /= decoder->cbr; | 2310 | est /= decoder->cbr; |
| 2079 | out: | 2311 | out: |
| 2080 | return decoder->timestamp + est; | 2312 | return decoder->sample_timestamp + est; |
| 2081 | } | 2313 | } |
| 2082 | 2314 | ||
| 2083 | const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) | 2315 | const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) |
| @@ -2093,8 +2325,10 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) | |||
| 2093 | err = intel_pt_sync(decoder); | 2325 | err = intel_pt_sync(decoder); |
| 2094 | break; | 2326 | break; |
| 2095 | case INTEL_PT_STATE_NO_IP: | 2327 | case INTEL_PT_STATE_NO_IP: |
| 2328 | decoder->have_last_ip = false; | ||
| 2096 | decoder->last_ip = 0; | 2329 | decoder->last_ip = 0; |
| 2097 | /* Fall through */ | 2330 | decoder->ip = 0; |
| 2331 | __fallthrough; | ||
| 2098 | case INTEL_PT_STATE_ERR_RESYNC: | 2332 | case INTEL_PT_STATE_ERR_RESYNC: |
| 2099 | err = intel_pt_sync_ip(decoder); | 2333 | err = intel_pt_sync_ip(decoder); |
| 2100 | break; | 2334 | break; |
| @@ -2130,15 +2364,29 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) | |||
| 2130 | } | 2364 | } |
| 2131 | } while (err == -ENOLINK); | 2365 | } while (err == -ENOLINK); |
| 2132 | 2366 | ||
| 2133 | decoder->state.err = err ? intel_pt_ext_err(err) : 0; | 2367 | if (err) { |
| 2134 | decoder->state.timestamp = decoder->timestamp; | 2368 | decoder->state.err = intel_pt_ext_err(err); |
| 2369 | decoder->state.from_ip = decoder->ip; | ||
| 2370 | decoder->sample_timestamp = decoder->timestamp; | ||
| 2371 | decoder->sample_insn_cnt = decoder->timestamp_insn_cnt; | ||
| 2372 | } else { | ||
| 2373 | decoder->state.err = 0; | ||
| 2374 | if (decoder->cbr != decoder->cbr_seen && decoder->state.type) { | ||
| 2375 | decoder->cbr_seen = decoder->cbr; | ||
| 2376 | decoder->state.type |= INTEL_PT_CBR_CHG; | ||
| 2377 | decoder->state.cbr_payload = decoder->cbr_payload; | ||
| 2378 | } | ||
| 2379 | if (intel_pt_sample_time(decoder->pkt_state)) { | ||
| 2380 | decoder->sample_timestamp = decoder->timestamp; | ||
| 2381 | decoder->sample_insn_cnt = decoder->timestamp_insn_cnt; | ||
| 2382 | } | ||
| 2383 | } | ||
| 2384 | |||
| 2385 | decoder->state.timestamp = decoder->sample_timestamp; | ||
| 2135 | decoder->state.est_timestamp = intel_pt_est_timestamp(decoder); | 2386 | decoder->state.est_timestamp = intel_pt_est_timestamp(decoder); |
| 2136 | decoder->state.cr3 = decoder->cr3; | 2387 | decoder->state.cr3 = decoder->cr3; |
| 2137 | decoder->state.tot_insn_cnt = decoder->tot_insn_cnt; | 2388 | decoder->state.tot_insn_cnt = decoder->tot_insn_cnt; |
| 2138 | 2389 | ||
| 2139 | if (err) | ||
| 2140 | decoder->state.from_ip = decoder->ip; | ||
| 2141 | |||
| 2142 | return &decoder->state; | 2390 | return &decoder->state; |
| 2143 | } | 2391 | } |
| 2144 | 2392 | ||
