blob: 836c56290499b84c0dad7785e9aa5979d68ed0bf [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 Carstens7eed2e02014-11-24 14:30:32 +010015#define ftrace_return_address(n) __builtin_return_address(n)
16
Heiko Carstensc9331462014-10-15 12:17:38 +020017void _mcount(void);
18void ftrace_caller(void);
19
Heiko Carstens2481a872014-08-15 12:33:46 +020020extern char ftrace_graph_caller_end;
Heiko Carstensc9331462014-10-15 12:17:38 +020021extern unsigned long ftrace_plt;
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020022
23struct dyn_arch_ftrace { };
24
Heiko Carstensc9331462014-10-15 12:17:38 +020025#define MCOUNT_ADDR ((unsigned long)_mcount)
26#define FTRACE_ADDR ((unsigned long)ftrace_caller)
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020027
Heiko Carstensc9331462014-10-15 12:17:38 +020028#define KPROBE_ON_FTRACE_NOP 0
29#define KPROBE_ON_FTRACE_CALL 1
Heiko Carstens5d360a72008-12-25 13:38:56 +010030
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020031static inline unsigned long ftrace_call_adjust(unsigned long addr)
32{
Martin Schwidefskyf2963882011-05-10 10:10:43 +020033 return addr;
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020034}
35
Heiko Carstensc9331462014-10-15 12:17:38 +020036struct ftrace_insn {
37 u16 opc;
38 s32 disp;
39} __packed;
40
41static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn)
42{
43#ifdef CONFIG_FUNCTION_TRACER
Heiko Carstense6d60b32015-01-09 13:08:28 +010044#ifdef CC_USING_HOTPATCH
45 /* brcl 0,0 */
46 insn->opc = 0xc004;
47 insn->disp = 0;
48#else
Heiko Carstensc9331462014-10-15 12:17:38 +020049 /* jg .+24 */
50 insn->opc = 0xc0f4;
51 insn->disp = MCOUNT_INSN_SIZE / 2;
52#endif
Heiko Carstense6d60b32015-01-09 13:08:28 +010053#endif
Heiko Carstensc9331462014-10-15 12:17:38 +020054}
55
56static inline int is_ftrace_nop(struct ftrace_insn *insn)
57{
58#ifdef CONFIG_FUNCTION_TRACER
Heiko Carstense6d60b32015-01-09 13:08:28 +010059#ifdef CC_USING_HOTPATCH
60 if (insn->disp == 0)
61 return 1;
62#else
Heiko Carstensc9331462014-10-15 12:17:38 +020063 if (insn->disp == MCOUNT_INSN_SIZE / 2)
64 return 1;
65#endif
Heiko Carstense6d60b32015-01-09 13:08:28 +010066#endif
Heiko Carstensc9331462014-10-15 12:17:38 +020067 return 0;
68}
69
70static inline void ftrace_generate_call_insn(struct ftrace_insn *insn,
71 unsigned long ip)
72{
73#ifdef CONFIG_FUNCTION_TRACER
74 unsigned long target;
75
76 /* brasl r0,ftrace_caller */
77 target = is_module_addr((void *) ip) ? ftrace_plt : FTRACE_ADDR;
78 insn->opc = 0xc005;
79 insn->disp = (target - ip) / 2;
80#endif
81}
82
Heiko Carstensdfd9f7a2009-06-12 10:26:44 +020083#endif /* __ASSEMBLY__ */
Heiko Carstens5d360a72008-12-25 13:38:56 +010084#endif /* _ASM_S390_FTRACE_H */