mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 17:41:44 +00:00
s390/ftrace: fix mcount adjustment
Tony Jones reported that the ftrace self tests on s390 do not work: <6>Testing dynamic ftrace ops #1: (0 0 0 0 0) FAILED! <6>Testing tracer irqsoff: <3>failed to start irqsoff tracer <4>.. no entries found ..FAILED! <6>Testing tracer wakeup: <3>failed to start wakeup tracer <4>.. no entries found ..FAILED! <6>Testing tracer function_graph: <4>Failed to init function_graph tracer, init returned -19 <4>FAILED! This happens because we forgot to adjust the instruction pointer that gets passed to the ftrace trace function by MCOUNT_INSN_SIZE. In addition change MCOUNT_INSN_SIZE to the correct value on 31 bit. It only worked so far because the to be patched instruction was identical. Reported-by: Tony Jones <tonyj@suse.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
bb4b42ce0c
commit
aca9120977
@ -9,11 +9,6 @@ struct dyn_arch_ftrace { };
|
||||
|
||||
#define MCOUNT_ADDR ((long)_mcount)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define MCOUNT_INSN_SIZE 12
|
||||
#else
|
||||
#define MCOUNT_INSN_SIZE 20
|
||||
#endif
|
||||
|
||||
static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
||||
{
|
||||
@ -21,4 +16,11 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define MCOUNT_INSN_SIZE 12
|
||||
#else
|
||||
#define MCOUNT_INSN_SIZE 22
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_S390_FTRACE_H */
|
||||
|
@ -16,12 +16,6 @@
|
||||
#include <trace/syscall.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define MCOUNT_OFFSET_RET 12
|
||||
#else
|
||||
#define MCOUNT_OFFSET_RET 22
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
|
||||
void ftrace_disable_code(void);
|
||||
@ -155,9 +149,10 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent,
|
||||
|
||||
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
|
||||
goto out;
|
||||
ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE;
|
||||
if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
|
||||
goto out;
|
||||
trace.func = (ip & PSW_ADDR_INSN) - MCOUNT_OFFSET_RET;
|
||||
trace.func = ip;
|
||||
/* Only trace if the calling function expects to. */
|
||||
if (!ftrace_graph_entry(&trace)) {
|
||||
current->curr_ret_stack--;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
.section .kprobes.text, "ax"
|
||||
|
||||
@ -33,6 +34,7 @@ ENTRY(ftrace_caller)
|
||||
la %r2,0(%r14)
|
||||
st %r0,__SF_BACKCHAIN(%r15)
|
||||
la %r3,0(%r3)
|
||||
ahi %r2,-MCOUNT_INSN_SIZE
|
||||
l %r14,0b-0b(%r1)
|
||||
l %r14,0(%r14)
|
||||
basr %r14,%r14
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
.section .kprobes.text, "ax"
|
||||
|
||||
@ -29,6 +30,7 @@ ENTRY(ftrace_caller)
|
||||
stg %r1,__SF_BACKCHAIN(%r15)
|
||||
lgr %r2,%r14
|
||||
lg %r3,168(%r15)
|
||||
aghi %r2,-MCOUNT_INSN_SIZE
|
||||
larl %r14,ftrace_trace_function
|
||||
lg %r14,0(%r14)
|
||||
basr %r14,%r14
|
||||
|
Loading…
Reference in New Issue
Block a user