aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2016-09-23 10:38:47 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-09-29 10:17:06 -0400
commit9f1d122b528ef3ffcef1bdcf6a3dddf9450a864e (patch)
treeeaefe95cfc75ea62b7d9b8c35387831d746ddfd5 /tools
parent2b9e32c47fd3edb0373067de7a151775b0e005c2 (diff)
perf intel-pt: Enable decoder to handle TIP.PGD with missing IP
When address filters are used, the decoder must detect the end of a filter region (or a branch into a tracestop region) by matching Packet Generation Disabled (TIP.PGD) packets against the object code using the IP given in the packet. However, due to errata SKL014 "Intel PT TIP.PGD May Not Have Target IP Payload", that IP may not be present. Enable the decoder to handle that by adding a new callback function 'pgd_ip()' which indicates whether the IP is not traced, in which case that is the point where the trace was disabled. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Poirier <mathieu.poirier@linaro.org> Link: http://lkml.kernel.org/r/1474641528-18776-16-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c30
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.h1
2 files changed, 31 insertions, 0 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 8ff6c6a61291..7591a0c37473 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -80,6 +80,7 @@ struct intel_pt_decoder {
80 int (*walk_insn)(struct intel_pt_insn *intel_pt_insn, 80 int (*walk_insn)(struct intel_pt_insn *intel_pt_insn,
81 uint64_t *insn_cnt_ptr, uint64_t *ip, uint64_t to_ip, 81 uint64_t *insn_cnt_ptr, uint64_t *ip, uint64_t to_ip,
82 uint64_t max_insn_cnt, void *data); 82 uint64_t max_insn_cnt, void *data);
83 bool (*pgd_ip)(uint64_t ip, void *data);
83 void *data; 84 void *data;
84 struct intel_pt_state state; 85 struct intel_pt_state state;
85 const unsigned char *buf; 86 const unsigned char *buf;
@@ -186,6 +187,7 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
186 187
187 decoder->get_trace = params->get_trace; 188 decoder->get_trace = params->get_trace;
188 decoder->walk_insn = params->walk_insn; 189 decoder->walk_insn = params->walk_insn;
190 decoder->pgd_ip = params->pgd_ip;
189 decoder->data = params->data; 191 decoder->data = params->data;
190 decoder->return_compression = params->return_compression; 192 decoder->return_compression = params->return_compression;
191 193
@@ -1008,6 +1010,19 @@ static int intel_pt_walk_tip(struct intel_pt_decoder *decoder)
1008 int err; 1010 int err;
1009 1011
1010 err = intel_pt_walk_insn(decoder, &intel_pt_insn, 0); 1012 err = intel_pt_walk_insn(decoder, &intel_pt_insn, 0);
1013 if (err == INTEL_PT_RETURN &&
1014 decoder->pgd_ip &&
1015 decoder->pkt_state == INTEL_PT_STATE_TIP_PGD &&
1016 (decoder->state.type & INTEL_PT_BRANCH) &&
1017 decoder->pgd_ip(decoder->state.to_ip, decoder->data)) {
1018 /* Unconditional branch leaving filter region */
1019 decoder->no_progress = 0;
1020 decoder->pge = false;
1021 decoder->continuous_period = false;
1022 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1023 decoder->state.to_ip = 0;
1024 return 0;
1025 }
1011 if (err == INTEL_PT_RETURN) 1026 if (err == INTEL_PT_RETURN)
1012 return 0; 1027 return 0;
1013 if (err) 1028 if (err)
@@ -1036,6 +1051,21 @@ static int intel_pt_walk_tip(struct intel_pt_decoder *decoder)
1036 } 1051 }
1037 1052
1038 if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) { 1053 if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) {
1054 uint64_t to_ip = decoder->ip + intel_pt_insn.length +
1055 intel_pt_insn.rel;
1056
1057 if (decoder->pgd_ip &&
1058 decoder->pkt_state == INTEL_PT_STATE_TIP_PGD &&
1059 decoder->pgd_ip(to_ip, decoder->data)) {
1060 /* Conditional branch leaving filter region */
1061 decoder->pge = false;
1062 decoder->continuous_period = false;
1063 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1064 decoder->ip = to_ip;
1065 decoder->state.from_ip = decoder->ip;
1066 decoder->state.to_ip = 0;
1067 return 0;
1068 }
1039 intel_pt_log_at("ERROR: Conditional branch when expecting indirect branch", 1069 intel_pt_log_at("ERROR: Conditional branch when expecting indirect branch",
1040 decoder->ip); 1070 decoder->ip);
1041 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC; 1071 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
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 02c38fec1c37..89399985fa4d 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
@@ -83,6 +83,7 @@ struct intel_pt_params {
83 int (*walk_insn)(struct intel_pt_insn *intel_pt_insn, 83 int (*walk_insn)(struct intel_pt_insn *intel_pt_insn,
84 uint64_t *insn_cnt_ptr, uint64_t *ip, uint64_t to_ip, 84 uint64_t *insn_cnt_ptr, uint64_t *ip, uint64_t to_ip,
85 uint64_t max_insn_cnt, void *data); 85 uint64_t max_insn_cnt, void *data);
86 bool (*pgd_ip)(uint64_t ip, void *data);
86 void *data; 87 void *data;
87 bool return_compression; 88 bool return_compression;
88 uint64_t period; 89 uint64_t period;