diff options
-rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 17 | ||||
-rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-decoder.h | 9 | ||||
-rw-r--r-- | tools/perf/util/intel-pt.c | 4 |
3 files changed, 28 insertions, 2 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 881d7c5e5e2a..d404bed7003a 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | |||
@@ -113,6 +113,7 @@ struct intel_pt_decoder { | |||
113 | bool have_cyc; | 113 | bool have_cyc; |
114 | bool fixup_last_mtc; | 114 | bool fixup_last_mtc; |
115 | bool have_last_ip; | 115 | bool have_last_ip; |
116 | enum intel_pt_param_flags flags; | ||
116 | uint64_t pos; | 117 | uint64_t pos; |
117 | uint64_t last_ip; | 118 | uint64_t last_ip; |
118 | uint64_t ip; | 119 | uint64_t ip; |
@@ -226,6 +227,8 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params) | |||
226 | decoder->return_compression = params->return_compression; | 227 | decoder->return_compression = params->return_compression; |
227 | decoder->branch_enable = params->branch_enable; | 228 | decoder->branch_enable = params->branch_enable; |
228 | 229 | ||
230 | decoder->flags = params->flags; | ||
231 | |||
229 | decoder->period = params->period; | 232 | decoder->period = params->period; |
230 | decoder->period_type = params->period_type; | 233 | decoder->period_type = params->period_type; |
231 | 234 | ||
@@ -1097,6 +1100,15 @@ static bool intel_pt_fup_event(struct intel_pt_decoder *decoder) | |||
1097 | return ret; | 1100 | return ret; |
1098 | } | 1101 | } |
1099 | 1102 | ||
1103 | static inline bool intel_pt_fup_with_nlip(struct intel_pt_decoder *decoder, | ||
1104 | struct intel_pt_insn *intel_pt_insn, | ||
1105 | uint64_t ip, int err) | ||
1106 | { | ||
1107 | return decoder->flags & INTEL_PT_FUP_WITH_NLIP && !err && | ||
1108 | intel_pt_insn->branch == INTEL_PT_BR_INDIRECT && | ||
1109 | ip == decoder->ip + intel_pt_insn->length; | ||
1110 | } | ||
1111 | |||
1100 | static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) | 1112 | static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) |
1101 | { | 1113 | { |
1102 | struct intel_pt_insn intel_pt_insn; | 1114 | struct intel_pt_insn intel_pt_insn; |
@@ -1109,10 +1121,11 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) | |||
1109 | err = intel_pt_walk_insn(decoder, &intel_pt_insn, ip); | 1121 | err = intel_pt_walk_insn(decoder, &intel_pt_insn, ip); |
1110 | if (err == INTEL_PT_RETURN) | 1122 | if (err == INTEL_PT_RETURN) |
1111 | return 0; | 1123 | return 0; |
1112 | if (err == -EAGAIN) { | 1124 | if (err == -EAGAIN || |
1125 | intel_pt_fup_with_nlip(decoder, &intel_pt_insn, ip, err)) { | ||
1113 | if (intel_pt_fup_event(decoder)) | 1126 | if (intel_pt_fup_event(decoder)) |
1114 | return 0; | 1127 | return 0; |
1115 | return err; | 1128 | return -EAGAIN; |
1116 | } | 1129 | } |
1117 | decoder->set_fup_tx_flags = false; | 1130 | decoder->set_fup_tx_flags = false; |
1118 | if (err) | 1131 | if (err) |
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h index fc1752d50019..51c18d67f4ca 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h | |||
@@ -60,6 +60,14 @@ enum { | |||
60 | INTEL_PT_ERR_MAX, | 60 | INTEL_PT_ERR_MAX, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | enum intel_pt_param_flags { | ||
64 | /* | ||
65 | * FUP packet can contain next linear instruction pointer instead of | ||
66 | * current linear instruction pointer. | ||
67 | */ | ||
68 | INTEL_PT_FUP_WITH_NLIP = 1 << 0, | ||
69 | }; | ||
70 | |||
63 | struct intel_pt_state { | 71 | struct intel_pt_state { |
64 | enum intel_pt_sample_type type; | 72 | enum intel_pt_sample_type type; |
65 | int err; | 73 | int err; |
@@ -106,6 +114,7 @@ struct intel_pt_params { | |||
106 | unsigned int mtc_period; | 114 | unsigned int mtc_period; |
107 | uint32_t tsc_ctc_ratio_n; | 115 | uint32_t tsc_ctc_ratio_n; |
108 | uint32_t tsc_ctc_ratio_d; | 116 | uint32_t tsc_ctc_ratio_d; |
117 | enum intel_pt_param_flags flags; | ||
109 | }; | 118 | }; |
110 | 119 | ||
111 | struct intel_pt_decoder; | 120 | struct intel_pt_decoder; |
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 3db7f0ee52a8..aec68908d604 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
@@ -749,6 +749,7 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt, | |||
749 | unsigned int queue_nr) | 749 | unsigned int queue_nr) |
750 | { | 750 | { |
751 | struct intel_pt_params params = { .get_trace = 0, }; | 751 | struct intel_pt_params params = { .get_trace = 0, }; |
752 | struct perf_env *env = pt->machine->env; | ||
752 | struct intel_pt_queue *ptq; | 753 | struct intel_pt_queue *ptq; |
753 | 754 | ||
754 | ptq = zalloc(sizeof(struct intel_pt_queue)); | 755 | ptq = zalloc(sizeof(struct intel_pt_queue)); |
@@ -830,6 +831,9 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt, | |||
830 | } | 831 | } |
831 | } | 832 | } |
832 | 833 | ||
834 | if (env->cpuid && !strncmp(env->cpuid, "GenuineIntel,6,92,", 18)) | ||
835 | params.flags |= INTEL_PT_FUP_WITH_NLIP; | ||
836 | |||
833 | ptq->decoder = intel_pt_decoder_new(¶ms); | 837 | ptq->decoder = intel_pt_decoder_new(¶ms); |
834 | if (!ptq->decoder) | 838 | if (!ptq->decoder) |
835 | goto out_free; | 839 | goto out_free; |