a192cd0413
When the function tracer starts modifying the code via breakpoints it sets a variable (modifying_ftrace_code) to inform the breakpoint handler to call the ftrace int3 code. But there's no synchronization between setting this code and the handler, thus it is possible for the handler to be called on another CPU before it sees the variable. This will cause a kernel crash as the int3 handler will not know what to do with it. I originally added smp_mb()'s to force the visibility of the variable but H. Peter Anvin suggested that I just make it atomic. [ Added comments as suggested by Peter Zijlstra ] Suggested-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
60 lines
1.2 KiB
C
60 lines
1.2 KiB
C
#ifndef _ASM_X86_FTRACE_H
|
|
#define _ASM_X86_FTRACE_H
|
|
|
|
#ifdef __ASSEMBLY__
|
|
|
|
.macro MCOUNT_SAVE_FRAME
|
|
/* taken from glibc */
|
|
subq $0x38, %rsp
|
|
movq %rax, (%rsp)
|
|
movq %rcx, 8(%rsp)
|
|
movq %rdx, 16(%rsp)
|
|
movq %rsi, 24(%rsp)
|
|
movq %rdi, 32(%rsp)
|
|
movq %r8, 40(%rsp)
|
|
movq %r9, 48(%rsp)
|
|
.endm
|
|
|
|
.macro MCOUNT_RESTORE_FRAME
|
|
movq 48(%rsp), %r9
|
|
movq 40(%rsp), %r8
|
|
movq 32(%rsp), %rdi
|
|
movq 24(%rsp), %rsi
|
|
movq 16(%rsp), %rdx
|
|
movq 8(%rsp), %rcx
|
|
movq (%rsp), %rax
|
|
addq $0x38, %rsp
|
|
.endm
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_FUNCTION_TRACER
|
|
#define MCOUNT_ADDR ((long)(mcount))
|
|
#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */
|
|
|
|
#ifndef __ASSEMBLY__
|
|
extern void mcount(void);
|
|
extern atomic_t modifying_ftrace_code;
|
|
|
|
static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
|
{
|
|
/*
|
|
* addr is the address of the mcount call instruction.
|
|
* recordmcount does the necessary offset calculation.
|
|
*/
|
|
return addr;
|
|
}
|
|
|
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
|
|
|
struct dyn_arch_ftrace {
|
|
/* No extra data needed for x86 */
|
|
};
|
|
|
|
int ftrace_int3_handler(struct pt_regs *regs);
|
|
|
|
#endif /* CONFIG_DYNAMIC_FTRACE */
|
|
#endif /* __ASSEMBLY__ */
|
|
#endif /* CONFIG_FUNCTION_TRACER */
|
|
|
|
#endif /* _ASM_X86_FTRACE_H */
|