aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c17
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.h9
-rw-r--r--tools/perf/util/intel-pt.c4
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
1103static 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
1100static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) 1112static 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
63enum 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
63struct intel_pt_state { 71struct 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
111struct intel_pt_decoder; 120struct 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(&params); 837 ptq->decoder = intel_pt_decoder_new(&params);
834 if (!ptq->decoder) 838 if (!ptq->decoder)
835 goto out_free; 839 goto out_free;