diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index 62c1c93aa1c6..4b20673a3395 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -286,9 +286,9 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL) RET 1: - testb $1, %al - jz 2f - andq $0xfffffffffffffffe, %rax + /* See ftrace_jmp_set(), jmp to the trampoline */ + btsq $63, %rax + jc 2f movq %rax, MCOUNT_REG_SIZE+8(%rsp) restore_mcount_regs /* Restore flags */ diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b041d9142d2b..1c2056a1a68b 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -618,19 +618,21 @@ static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ #ifdef CONFIG_DYNAMIC_FTRACE_WITH_JMP +#define FTRACE_JMP_BIT BIT(BITS_PER_LONG - 1) + static inline bool ftrace_is_jmp(unsigned long addr) { - return addr & 1; + return !(addr & FTRACE_JMP_BIT); } static inline unsigned long ftrace_jmp_set(unsigned long addr) { - return addr | 1UL; + return addr & ~FTRACE_JMP_BIT; } static inline unsigned long ftrace_jmp_get(unsigned long addr) { - return addr & ~1UL; + return addr | FTRACE_JMP_BIT; } #else static inline bool ftrace_is_jmp(unsigned long addr)