perf/x86/intel: Discard zero length call entries in LBR call stack
"Zero length call" uses the attribute of the call instruction to push the immediate instruction pointer on to the stack and then pops off that address into a register. This is accomplished without any matching return instruction. It confuses the hardware and make the recorded call stack incorrect. We can partially resolve this issue by: decode call instructions and discard any zero length call entry in the LBR stack. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Signed-off-by: Kan Liang <kan.liang@intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul Mackerras <paulus@samba.org> Cc: eranian@google.com Cc: jolsa@redhat.com Link: http://lkml.kernel.org/r/1415156173-10035-16-git-send-email-kan.liang@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
2c70d0086e
commit
aa54ae9b87
@ -94,7 +94,8 @@ enum {
|
||||
X86_BR_ABORT = 1 << 12,/* transaction abort */
|
||||
X86_BR_IN_TX = 1 << 13,/* in transaction */
|
||||
X86_BR_NO_TX = 1 << 14,/* not in transaction */
|
||||
X86_BR_CALL_STACK = 1 << 15,/* call stack */
|
||||
X86_BR_ZERO_CALL = 1 << 15,/* zero length call */
|
||||
X86_BR_CALL_STACK = 1 << 16,/* call stack */
|
||||
};
|
||||
|
||||
#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
|
||||
@ -111,13 +112,15 @@ enum {
|
||||
X86_BR_JMP |\
|
||||
X86_BR_IRQ |\
|
||||
X86_BR_ABORT |\
|
||||
X86_BR_IND_CALL)
|
||||
X86_BR_IND_CALL |\
|
||||
X86_BR_ZERO_CALL)
|
||||
|
||||
#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
|
||||
|
||||
#define X86_BR_ANY_CALL \
|
||||
(X86_BR_CALL |\
|
||||
X86_BR_IND_CALL |\
|
||||
X86_BR_ZERO_CALL |\
|
||||
X86_BR_SYSCALL |\
|
||||
X86_BR_IRQ |\
|
||||
X86_BR_INT)
|
||||
@ -702,6 +705,12 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
|
||||
ret = X86_BR_INT;
|
||||
break;
|
||||
case 0xe8: /* call near rel */
|
||||
insn_get_immediate(&insn);
|
||||
if (insn.immediate1.value == 0) {
|
||||
/* zero length call */
|
||||
ret = X86_BR_ZERO_CALL;
|
||||
break;
|
||||
}
|
||||
case 0x9a: /* call far absolute */
|
||||
ret = X86_BR_CALL;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user