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>
#define MCOUNT_ADDR ((long)_mcount)
#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)
{
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
}
#endif /* __ASSEMBLY__ */
}
#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_64BIT
+#define MCOUNT_INSN_SIZE 12
+#else
+#define MCOUNT_INSN_SIZE 22
+#endif
+
#endif /* _ASM_S390_FTRACE_H */
#endif /* _ASM_S390_FTRACE_H */
#include <trace/syscall.h>
#include <asm/asm-offsets.h>
#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);
#ifdef CONFIG_DYNAMIC_FTRACE
void ftrace_disable_code(void);
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
goto out;
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;
if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
goto out;
- trace.func = (ip & PSW_ADDR_INSN) - MCOUNT_OFFSET_RET;
/* Only trace if the calling function expects to. */
if (!ftrace_graph_entry(&trace)) {
current->curr_ret_stack--;
/* Only trace if the calling function expects to. */
if (!ftrace_graph_entry(&trace)) {
current->curr_ret_stack--;
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
.section .kprobes.text, "ax"
.section .kprobes.text, "ax"
la %r2,0(%r14)
st %r0,__SF_BACKCHAIN(%r15)
la %r3,0(%r3)
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
l %r14,0b-0b(%r1)
l %r14,0(%r14)
basr %r14,%r14
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
.section .kprobes.text, "ax"
.section .kprobes.text, "ax"
stg %r1,__SF_BACKCHAIN(%r15)
lgr %r2,%r14
lg %r3,168(%r15)
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
larl %r14,ftrace_trace_function
lg %r14,0(%r14)
basr %r14,%r14