diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-05-13 08:48:52 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-05-15 07:09:09 -0400 |
commit | aca91209775514b5a335e7ef11f1d636618590c7 (patch) | |
tree | d2bc7248e2a4451e0a68c1680106770ad64874eb /arch | |
parent | bb4b42ce0ca36af8c113587ab64b138b3cf5459c (diff) |
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/include/asm/ftrace.h | 12 | ||||
-rw-r--r-- | arch/s390/kernel/ftrace.c | 9 | ||||
-rw-r--r-- | arch/s390/kernel/mcount.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/mcount64.S | 2 |
4 files changed, 13 insertions, 12 deletions
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index b7931faaef6d..bf246dae1367 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h | |||
@@ -9,11 +9,6 @@ struct dyn_arch_ftrace { }; | |||
9 | 9 | ||
10 | #define MCOUNT_ADDR ((long)_mcount) | 10 | #define MCOUNT_ADDR ((long)_mcount) |
11 | 11 | ||
12 | #ifdef CONFIG_64BIT | ||
13 | #define MCOUNT_INSN_SIZE 12 | ||
14 | #else | ||
15 | #define MCOUNT_INSN_SIZE 20 | ||
16 | #endif | ||
17 | 12 | ||
18 | static inline unsigned long ftrace_call_adjust(unsigned long addr) | 13 | static inline unsigned long ftrace_call_adjust(unsigned long addr) |
19 | { | 14 | { |
@@ -21,4 +16,11 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) | |||
21 | } | 16 | } |
22 | 17 | ||
23 | #endif /* __ASSEMBLY__ */ | 18 | #endif /* __ASSEMBLY__ */ |
19 | |||
20 | #ifdef CONFIG_64BIT | ||
21 | #define MCOUNT_INSN_SIZE 12 | ||
22 | #else | ||
23 | #define MCOUNT_INSN_SIZE 22 | ||
24 | #endif | ||
25 | |||
24 | #endif /* _ASM_S390_FTRACE_H */ | 26 | #endif /* _ASM_S390_FTRACE_H */ |
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 78bdf0e5dff7..e3043aef87a9 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
@@ -16,12 +16,6 @@ | |||
16 | #include <trace/syscall.h> | 16 | #include <trace/syscall.h> |
17 | #include <asm/asm-offsets.h> | 17 | #include <asm/asm-offsets.h> |
18 | 18 | ||
19 | #ifdef CONFIG_64BIT | ||
20 | #define MCOUNT_OFFSET_RET 12 | ||
21 | #else | ||
22 | #define MCOUNT_OFFSET_RET 22 | ||
23 | #endif | ||
24 | |||
25 | #ifdef CONFIG_DYNAMIC_FTRACE | 19 | #ifdef CONFIG_DYNAMIC_FTRACE |
26 | 20 | ||
27 | void ftrace_disable_code(void); | 21 | void ftrace_disable_code(void); |
@@ -155,9 +149,10 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent, | |||
155 | 149 | ||
156 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | 150 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) |
157 | goto out; | 151 | goto out; |
152 | ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE; | ||
158 | if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) | 153 | if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) |
159 | goto out; | 154 | goto out; |
160 | trace.func = (ip & PSW_ADDR_INSN) - MCOUNT_OFFSET_RET; | 155 | trace.func = ip; |
161 | /* Only trace if the calling function expects to. */ | 156 | /* Only trace if the calling function expects to. */ |
162 | if (!ftrace_graph_entry(&trace)) { | 157 | if (!ftrace_graph_entry(&trace)) { |
163 | current->curr_ret_stack--; | 158 | current->curr_ret_stack--; |
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 4567ce20d900..08dcf21cb8df 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | #include <asm/asm-offsets.h> | 9 | #include <asm/asm-offsets.h> |
10 | #include <asm/ftrace.h> | ||
10 | 11 | ||
11 | .section .kprobes.text, "ax" | 12 | .section .kprobes.text, "ax" |
12 | 13 | ||
@@ -33,6 +34,7 @@ ENTRY(ftrace_caller) | |||
33 | la %r2,0(%r14) | 34 | la %r2,0(%r14) |
34 | st %r0,__SF_BACKCHAIN(%r15) | 35 | st %r0,__SF_BACKCHAIN(%r15) |
35 | la %r3,0(%r3) | 36 | la %r3,0(%r3) |
37 | ahi %r2,-MCOUNT_INSN_SIZE | ||
36 | l %r14,0b-0b(%r1) | 38 | l %r14,0b-0b(%r1) |
37 | l %r14,0(%r14) | 39 | l %r14,0(%r14) |
38 | basr %r14,%r14 | 40 | basr %r14,%r14 |
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S index 11332193db30..1c52eae3396a 100644 --- a/arch/s390/kernel/mcount64.S +++ b/arch/s390/kernel/mcount64.S | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | #include <asm/asm-offsets.h> | 9 | #include <asm/asm-offsets.h> |
10 | #include <asm/ftrace.h> | ||
10 | 11 | ||
11 | .section .kprobes.text, "ax" | 12 | .section .kprobes.text, "ax" |
12 | 13 | ||
@@ -29,6 +30,7 @@ ENTRY(ftrace_caller) | |||
29 | stg %r1,__SF_BACKCHAIN(%r15) | 30 | stg %r1,__SF_BACKCHAIN(%r15) |
30 | lgr %r2,%r14 | 31 | lgr %r2,%r14 |
31 | lg %r3,168(%r15) | 32 | lg %r3,168(%r15) |
33 | aghi %r2,-MCOUNT_INSN_SIZE | ||
32 | larl %r14,ftrace_trace_function | 34 | larl %r14,ftrace_trace_function |
33 | lg %r14,0(%r14) | 35 | lg %r14,0(%r14) |
34 | basr %r14,%r14 | 36 | basr %r14,%r14 |