diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2014-08-15 07:01:46 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-09-09 02:53:28 -0400 |
commit | 10dec7dbd50ab0be96dda085d625d54ce800e426 (patch) | |
tree | a293f2b0d4cc1e68cd09770dfcd284356d3bb932 | |
parent | 2481a87b0250bbf429fc8cdc78331efbc44a0221 (diff) |
s390/ftrace: add HAVE_DYNAMIC_FTRACE_WITH_REGS support
This code is based on a patch from Vojtech Pavlik.
http://marc.info/?l=linux-s390&m=140438885114413&w=2
The actual implementation now differs significantly:
Instead of adding a second function "ftrace_regs_caller" which would be nearly
identical to the existing ftrace_caller function, the current ftrace_caller
function is now an alias to ftrace_regs_caller and always passes the needed
pt_regs structure and function_trace_op parameters unconditionally.
Besides that also use asm offsets to correctly allocate and access the new
struct pt_regs on the stack.
While at it we can make use of new instruction to get rid of some indirect
loads if compiled for new machines.
The passed struct pt_regs can be changed by the called function and it's new
contents will replace the current contents.
Note: to change the return address the embedded psw member of the pt_regs
structure must be changed. The psw member is right now incomplete, since
the mask part is missing. For all current use cases this should be sufficent.
Providing and restoring a sane mask would mean we need to add an epsw/lpswe
pair to the mcount code. Only these two instruction would cost us ~120 cycles
which currently seems not necessary.
Cc: Vojtech Pavlik <vojtech@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/Kconfig | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/ftrace.h | 4 | ||||
-rw-r--r-- | arch/s390/kernel/ftrace.c | 7 | ||||
-rw-r--r-- | arch/s390/kernel/mcount64.S | 43 |
4 files changed, 43 insertions, 12 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 05c78bb5f570..3f845fc02ac4 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -114,6 +114,7 @@ config S390 | |||
114 | select HAVE_C_RECORDMCOUNT | 114 | select HAVE_C_RECORDMCOUNT |
115 | select HAVE_DEBUG_KMEMLEAK | 115 | select HAVE_DEBUG_KMEMLEAK |
116 | select HAVE_DYNAMIC_FTRACE | 116 | select HAVE_DYNAMIC_FTRACE |
117 | select HAVE_DYNAMIC_FTRACE_WITH_REGS if 64BIT | ||
117 | select HAVE_FTRACE_MCOUNT_RECORD | 118 | select HAVE_FTRACE_MCOUNT_RECORD |
118 | select HAVE_FUNCTION_GRAPH_TRACER | 119 | select HAVE_FUNCTION_GRAPH_TRACER |
119 | select HAVE_FUNCTION_TRACER | 120 | select HAVE_FUNCTION_TRACER |
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index 7b8e456d76c9..1759d73fb95b 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h | |||
@@ -24,4 +24,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) | |||
24 | #define MCOUNT_INSN_SIZE 22 | 24 | #define MCOUNT_INSN_SIZE 22 |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_64BIT | ||
28 | #define ARCH_SUPPORTS_FTRACE_OPS 1 | ||
29 | #endif | ||
30 | |||
27 | #endif /* _ASM_S390_FTRACE_H */ | 31 | #endif /* _ASM_S390_FTRACE_H */ |
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index de55efa5b64e..14b61954d5a8 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
@@ -107,6 +107,13 @@ asm( | |||
107 | 107 | ||
108 | #endif /* CONFIG_64BIT */ | 108 | #endif /* CONFIG_64BIT */ |
109 | 109 | ||
110 | #ifdef CONFIG_64BIT | ||
111 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, | ||
112 | unsigned long addr) | ||
113 | { | ||
114 | return 0; | ||
115 | } | ||
116 | #endif | ||
110 | 117 | ||
111 | int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, | 118 | int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, |
112 | unsigned long addr) | 119 | unsigned long addr) |
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S index 5b33c83adde9..4a65dabae851 100644 --- a/arch/s390/kernel/mcount64.S +++ b/arch/s390/kernel/mcount64.S | |||
@@ -8,28 +8,47 @@ | |||
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 | #include <asm/ftrace.h> |
11 | #include <asm/ptrace.h> | ||
11 | 12 | ||
12 | .section .kprobes.text, "ax" | 13 | .section .kprobes.text, "ax" |
13 | 14 | ||
14 | ENTRY(ftrace_stub) | 15 | ENTRY(ftrace_stub) |
15 | br %r14 | 16 | br %r14 |
16 | 17 | ||
18 | #define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
19 | #define STACK_PARENT_IP (STACK_FRAME_SIZE + 8) | ||
20 | #define STACK_PTREGS (STACK_FRAME_OVERHEAD) | ||
21 | #define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS) | ||
22 | #define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW) | ||
23 | |||
17 | ENTRY(_mcount) | 24 | ENTRY(_mcount) |
18 | #ifdef CONFIG_DYNAMIC_FTRACE | 25 | #ifdef CONFIG_DYNAMIC_FTRACE |
19 | br %r14 | 26 | br %r14 |
20 | 27 | ||
21 | ENTRY(ftrace_caller) | 28 | ENTRY(ftrace_caller) |
29 | .globl ftrace_regs_caller | ||
30 | .set ftrace_regs_caller,ftrace_caller | ||
22 | #endif | 31 | #endif |
23 | stmg %r2,%r5,32(%r15) | ||
24 | stg %r14,112(%r15) | ||
25 | lgr %r1,%r15 | 32 | lgr %r1,%r15 |
26 | aghi %r15,-160 | 33 | aghi %r15,-STACK_FRAME_SIZE |
27 | stg %r1,__SF_BACKCHAIN(%r15) | 34 | stg %r1,__SF_BACKCHAIN(%r15) |
35 | stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) | ||
36 | stmg %r0,%r13,STACK_PTREGS_GPRS(%r15) | ||
37 | stg %r14,(STACK_PTREGS_PSW+8)(%r15) | ||
38 | #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES | ||
39 | aghik %r2,%r14,-MCOUNT_INSN_SIZE | ||
40 | lgrl %r4,function_trace_op | ||
41 | lgrl %r14,ftrace_trace_function | ||
42 | #else | ||
28 | lgr %r2,%r14 | 43 | lgr %r2,%r14 |
29 | lg %r3,168(%r15) | ||
30 | aghi %r2,-MCOUNT_INSN_SIZE | 44 | aghi %r2,-MCOUNT_INSN_SIZE |
45 | larl %r4,function_trace_op | ||
46 | lg %r4,0(%r4) | ||
31 | larl %r14,ftrace_trace_function | 47 | larl %r14,ftrace_trace_function |
32 | lg %r14,0(%r14) | 48 | lg %r14,0(%r14) |
49 | #endif | ||
50 | lg %r3,STACK_PARENT_IP(%r15) | ||
51 | la %r5,STACK_PTREGS(%r15) | ||
33 | basr %r14,%r14 | 52 | basr %r14,%r14 |
34 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 53 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
35 | # The j instruction gets runtime patched to a nop instruction. | 54 | # The j instruction gets runtime patched to a nop instruction. |
@@ -37,16 +56,16 @@ ENTRY(ftrace_caller) | |||
37 | # j .+4 | 56 | # j .+4 |
38 | ENTRY(ftrace_graph_caller) | 57 | ENTRY(ftrace_graph_caller) |
39 | j ftrace_graph_caller_end | 58 | j ftrace_graph_caller_end |
40 | lg %r2,168(%r15) | 59 | lg %r2,STACK_PARENT_IP(%r15) |
41 | lg %r3,272(%r15) | 60 | lg %r3,(STACK_PTREGS_PSW+8)(%r15) |
42 | brasl %r14,prepare_ftrace_return | 61 | brasl %r14,prepare_ftrace_return |
43 | stg %r2,168(%r15) | 62 | stg %r2,STACK_PARENT_IP(%r15) |
44 | ftrace_graph_caller_end: | 63 | ftrace_graph_caller_end: |
45 | .globl ftrace_graph_caller_end | 64 | .globl ftrace_graph_caller_end |
46 | #endif | 65 | #endif |
47 | aghi %r15,160 | 66 | lmg %r0,%r13,STACK_PTREGS_GPRS(%r15) |
48 | lmg %r2,%r5,32(%r15) | 67 | lg %r14,(STACK_PTREGS_PSW+8)(%r15) |
49 | lg %r14,112(%r15) | 68 | aghi %r15,STACK_FRAME_SIZE |
50 | br %r14 | 69 | br %r14 |
51 | 70 | ||
52 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 71 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
@@ -54,10 +73,10 @@ ftrace_graph_caller_end: | |||
54 | ENTRY(return_to_handler) | 73 | ENTRY(return_to_handler) |
55 | stmg %r2,%r5,32(%r15) | 74 | stmg %r2,%r5,32(%r15) |
56 | lgr %r1,%r15 | 75 | lgr %r1,%r15 |
57 | aghi %r15,-160 | 76 | aghi %r15,-STACK_FRAME_OVERHEAD |
58 | stg %r1,__SF_BACKCHAIN(%r15) | 77 | stg %r1,__SF_BACKCHAIN(%r15) |
59 | brasl %r14,ftrace_return_to_handler | 78 | brasl %r14,ftrace_return_to_handler |
60 | aghi %r15,160 | 79 | aghi %r15,STACK_FRAME_OVERHEAD |
61 | lgr %r14,%r2 | 80 | lgr %r14,%r2 |
62 | lmg %r2,%r5,32(%r15) | 81 | lmg %r2,%r5,32(%r15) |
63 | br %r14 | 82 | br %r14 |