diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 05c78bb5f57024bf220e778af99888a1df6e6bbc..3f845fc02ac4855dcb2e315d5b529f5285f20bef 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -114,6 +114,7 @@ config S390 select HAVE_C_RECORDMCOUNT select HAVE_DEBUG_KMEMLEAK select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_REGS if 64BIT select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index 7b8e456d76c9ee05004b1bbf722394d17aad346e..1759d73fb95b20ca9889c961ebc06ea57581e683 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) #define MCOUNT_INSN_SIZE 22 #endif +#ifdef CONFIG_64BIT +#define ARCH_SUPPORTS_FTRACE_OPS 1 +#endif + #endif /* _ASM_S390_FTRACE_H */ diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index de55efa5b64e255914c1c9e9c95629eb8680f768..14b61954d5a85c62b3c39f6e294d03298c37e1a0 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -107,6 +107,13 @@ asm( #endif /* CONFIG_64BIT */ +#ifdef CONFIG_64BIT +int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, + unsigned long addr) +{ + return 0; +} +#endif int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S index 5b33c83adde9d2ea78ccb8d174e3d85ab56a632b..4a65dabae8511dbc5ef4237925e79fc0157a93fa 100644 --- a/arch/s390/kernel/mcount64.S +++ b/arch/s390/kernel/mcount64.S @@ -8,28 +8,47 @@ #include #include #include +#include .section .kprobes.text, "ax" ENTRY(ftrace_stub) br %r14 +#define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE) +#define STACK_PARENT_IP (STACK_FRAME_SIZE + 8) +#define STACK_PTREGS (STACK_FRAME_OVERHEAD) +#define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS) +#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW) + ENTRY(_mcount) #ifdef CONFIG_DYNAMIC_FTRACE br %r14 ENTRY(ftrace_caller) + .globl ftrace_regs_caller + .set ftrace_regs_caller,ftrace_caller #endif - stmg %r2,%r5,32(%r15) - stg %r14,112(%r15) lgr %r1,%r15 - aghi %r15,-160 + aghi %r15,-STACK_FRAME_SIZE stg %r1,__SF_BACKCHAIN(%r15) + stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) + stmg %r0,%r13,STACK_PTREGS_GPRS(%r15) + stg %r14,(STACK_PTREGS_PSW+8)(%r15) +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + aghik %r2,%r14,-MCOUNT_INSN_SIZE + lgrl %r4,function_trace_op + lgrl %r14,ftrace_trace_function +#else lgr %r2,%r14 - lg %r3,168(%r15) aghi %r2,-MCOUNT_INSN_SIZE + larl %r4,function_trace_op + lg %r4,0(%r4) larl %r14,ftrace_trace_function lg %r14,0(%r14) +#endif + lg %r3,STACK_PARENT_IP(%r15) + la %r5,STACK_PTREGS(%r15) basr %r14,%r14 #ifdef CONFIG_FUNCTION_GRAPH_TRACER # The j instruction gets runtime patched to a nop instruction. @@ -37,16 +56,16 @@ ENTRY(ftrace_caller) # j .+4 ENTRY(ftrace_graph_caller) j ftrace_graph_caller_end - lg %r2,168(%r15) - lg %r3,272(%r15) + lg %r2,STACK_PARENT_IP(%r15) + lg %r3,(STACK_PTREGS_PSW+8)(%r15) brasl %r14,prepare_ftrace_return - stg %r2,168(%r15) + stg %r2,STACK_PARENT_IP(%r15) ftrace_graph_caller_end: .globl ftrace_graph_caller_end #endif - aghi %r15,160 - lmg %r2,%r5,32(%r15) - lg %r14,112(%r15) + lmg %r0,%r13,STACK_PTREGS_GPRS(%r15) + lg %r14,(STACK_PTREGS_PSW+8)(%r15) + aghi %r15,STACK_FRAME_SIZE br %r14 #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -54,10 +73,10 @@ ftrace_graph_caller_end: ENTRY(return_to_handler) stmg %r2,%r5,32(%r15) lgr %r1,%r15 - aghi %r15,-160 + aghi %r15,-STACK_FRAME_OVERHEAD stg %r1,__SF_BACKCHAIN(%r15) brasl %r14,ftrace_return_to_handler - aghi %r15,160 + aghi %r15,STACK_FRAME_OVERHEAD lgr %r14,%r2 lmg %r2,%r5,32(%r15) br %r14