perf intel-pt: Fix "Unexpected indirect branch" error
Some Atom CPUs can produce FUP packets that contain NLIP (next linear instruction pointer) instead of CLIP (current linear instruction pointer). That will result in "Unexpected indirect branch" errors. Fix by comparing IP to NLIP in that case. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1527762225-26024-5-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
dd27b87ab5
commit
9fb523363f
@@ -113,6 +113,7 @@ struct intel_pt_decoder {
|
||||
bool have_cyc;
|
||||
bool fixup_last_mtc;
|
||||
bool have_last_ip;
|
||||
enum intel_pt_param_flags flags;
|
||||
uint64_t pos;
|
||||
uint64_t last_ip;
|
||||
uint64_t ip;
|
||||
@@ -226,6 +227,8 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
|
||||
decoder->return_compression = params->return_compression;
|
||||
decoder->branch_enable = params->branch_enable;
|
||||
|
||||
decoder->flags = params->flags;
|
||||
|
||||
decoder->period = params->period;
|
||||
decoder->period_type = params->period_type;
|
||||
|
||||
@@ -1097,6 +1100,15 @@ static bool intel_pt_fup_event(struct intel_pt_decoder *decoder)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool intel_pt_fup_with_nlip(struct intel_pt_decoder *decoder,
|
||||
struct intel_pt_insn *intel_pt_insn,
|
||||
uint64_t ip, int err)
|
||||
{
|
||||
return decoder->flags & INTEL_PT_FUP_WITH_NLIP && !err &&
|
||||
intel_pt_insn->branch == INTEL_PT_BR_INDIRECT &&
|
||||
ip == decoder->ip + intel_pt_insn->length;
|
||||
}
|
||||
|
||||
static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
|
||||
{
|
||||
struct intel_pt_insn intel_pt_insn;
|
||||
@@ -1109,10 +1121,11 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
|
||||
err = intel_pt_walk_insn(decoder, &intel_pt_insn, ip);
|
||||
if (err == INTEL_PT_RETURN)
|
||||
return 0;
|
||||
if (err == -EAGAIN) {
|
||||
if (err == -EAGAIN ||
|
||||
intel_pt_fup_with_nlip(decoder, &intel_pt_insn, ip, err)) {
|
||||
if (intel_pt_fup_event(decoder))
|
||||
return 0;
|
||||
return err;
|
||||
return -EAGAIN;
|
||||
}
|
||||
decoder->set_fup_tx_flags = false;
|
||||
if (err)
|
||||
|
Reference in New Issue
Block a user