aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
diff options
context:
space:
mode:
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.c30
1 files changed, 30 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;