blob: 64053d9ac3f23b7cb1bf23aa42aa435b9f2ae0f8 [file] [log] [blame]
Heiko Carstens5d360a72008-12-25 13:38:56 +01001#ifndef _ASM_S390_FTRACE_H
2#define _ASM_S390_FTRACE_H
3
Heiko Carstensc9331462014-10-15 12:17:38 +02004#define ARCH_SUPPORTS_FTRACE_OPS 1
5
Heiko Carstense6d60b32015-01-09 13:08:28 +01006#ifdef CC_USING_HOTPATCH
7#define MCOUNT_INSN_SIZE 6
8#else
Heiko Carstensc9331462014-10-15 12:17:38 +02009#define MCOUNT_INSN_SIZE 24
10#define MCOUNT_RETURN_FIXUP 18
Heiko Carstense6d60b32015-01-09 13:08:28 +010011#endif
Heiko Carstensc9331462014-10-15 12:17:38 +020012
Heiko Carstens5d360a72008-12-25 13:38:56 +010013#ifndef __ASSEMBLY__
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020014
Heiko Carstens56063302016-05-02 14:38:29 +020015unsigned long return_address(int depth);
16
17#define ftrace_return_address(n) return_address(n)
Heiko Carstens7eed2e02014-11-24 14:30:32 +010018
Heiko Carstensc9331462014-10-15 12:17:38 +020019void _mcount(void);
20void ftrace_caller(void);
21
Heiko Carstens2481a872014-08-15 12:33:46 +020022extern char ftrace_graph_caller_end;
Heiko Carstensc9331462014-10-15 12:17:38 +020023extern unsigned long ftrace_plt;
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020024
25struct dyn_arch_ftrace { };
26
Heiko Carstensc9331462014-10-15 12:17:38 +020027#define MCOUNT_ADDR ((unsigned long)_mcount)
28#define FTRACE_ADDR ((unsigned long)ftrace_caller)
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020029
Heiko Carstensc9331462014-10-15 12:17:38 +020030#define KPROBE_ON_FTRACE_NOP 0
31#define KPROBE_ON_FTRACE_CALL 1
Heiko Carstens5d360a72008-12-25 13:38:56 +010032
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020033static inline unsigned long ftrace_call_adjust(unsigned long addr)
34{
Martin Schwidefskyf2963882011-05-10 10:10:43 +020035 return addr;
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020036}
37
Heiko Carstensc9331462014-10-15 12:17:38 +020038struct ftrace_insn {
39 u16 opc;
40 s32 disp;
41} __packed;
42
43static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn)
44{
45#ifdef CONFIG_FUNCTION_TRACER
Heiko Carstense6d60b32015-01-09 13:08:28 +010046#ifdef CC_USING_HOTPATCH
47 /* brcl 0,0 */
48 insn->opc = 0xc004;
49 insn->disp = 0;
50#else
Heiko Carstensc9331462014-10-15 12:17:38 +020051 /* jg .+24 */
52 insn->opc = 0xc0f4;
53 insn->disp = MCOUNT_INSN_SIZE / 2;
54#endif
Heiko Carstense6d60b32015-01-09 13:08:28 +010055#endif
Heiko Carstensc9331462014-10-15 12:17:38 +020056}
57
58static inline int is_ftrace_nop(struct ftrace_insn *insn)
59{
60#ifdef CONFIG_FUNCTION_TRACER
Heiko Carstense6d60b32015-01-09 13:08:28 +010061#ifdef CC_USING_HOTPATCH
62 if (insn->disp == 0)
63 return 1;
64#else
Heiko Carstensc9331462014-10-15 12:17:38 +020065 if (insn->disp == MCOUNT_INSN_SIZE / 2)
66 return 1;
67#endif
Heiko Carstense6d60b32015-01-09 13:08:28 +010068#endif
Heiko Carstensc9331462014-10-15 12:17:38 +020069 return 0;
70}
71
72static inline void ftrace_generate_call_insn(struct ftrace_insn *insn,
73 unsigned long ip)
74{
75#ifdef CONFIG_FUNCTION_TRACER
76 unsigned long target;
77
78 /* brasl r0,ftrace_caller */
79 target = is_module_addr((void *) ip) ? ftrace_plt : FTRACE_ADDR;
80 insn->opc = 0xc005;
81 insn->disp = (target - ip) / 2;
82#endif
83}
84
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020085#endif /* __ASSEMBLY__ */
Heiko Carstens5d360a72008-12-25 13:38:56 +010086#endif /* _ASM_S390_FTRACE_H */