57
57
58
58
unsigned long ftrace_plt ;
59
59
60
+ static inline void ftrace_generate_orig_insn (struct ftrace_insn * insn )
61
+ {
62
+ #ifdef CC_USING_HOTPATCH
63
+ /* brcl 0,0 */
64
+ insn -> opc = 0xc004 ;
65
+ insn -> disp = 0 ;
66
+ #else
67
+ /* stg r14,8(r15) */
68
+ insn -> opc = 0xe3e0 ;
69
+ insn -> disp = 0xf0080024 ;
70
+ #endif
71
+ }
72
+
73
+ static inline int is_kprobe_on_ftrace (struct ftrace_insn * insn )
74
+ {
75
+ #ifdef CONFIG_KPROBES
76
+ if (insn -> opc == BREAKPOINT_INSTRUCTION )
77
+ return 1 ;
78
+ #endif
79
+ return 0 ;
80
+ }
81
+
82
+ static inline void ftrace_generate_kprobe_nop_insn (struct ftrace_insn * insn )
83
+ {
84
+ #ifdef CONFIG_KPROBES
85
+ insn -> opc = BREAKPOINT_INSTRUCTION ;
86
+ insn -> disp = KPROBE_ON_FTRACE_NOP ;
87
+ #endif
88
+ }
89
+
90
+ static inline void ftrace_generate_kprobe_call_insn (struct ftrace_insn * insn )
91
+ {
92
+ #ifdef CONFIG_KPROBES
93
+ insn -> opc = BREAKPOINT_INSTRUCTION ;
94
+ insn -> disp = KPROBE_ON_FTRACE_CALL ;
95
+ #endif
96
+ }
97
+
60
98
int ftrace_modify_call (struct dyn_ftrace * rec , unsigned long old_addr ,
61
99
unsigned long addr )
62
100
{
@@ -72,26 +110,18 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
72
110
return - EFAULT ;
73
111
if (addr == MCOUNT_ADDR ) {
74
112
/* Initial code replacement */
75
- #ifdef CC_USING_HOTPATCH
76
- /* We expect to see brcl 0,0 */
77
- ftrace_generate_nop_insn (& orig );
78
- #else
79
- /* We expect to see stg r14,8(r15) */
80
- orig .opc = 0xe3e0 ;
81
- orig .disp = 0xf0080024 ;
82
- #endif
113
+ ftrace_generate_orig_insn (& orig );
83
114
ftrace_generate_nop_insn (& new );
84
- } else if (old . opc == BREAKPOINT_INSTRUCTION ) {
115
+ } else if (is_kprobe_on_ftrace ( & old ) ) {
85
116
/*
86
117
* If we find a breakpoint instruction, a kprobe has been
87
118
* placed at the beginning of the function. We write the
88
119
* constant KPROBE_ON_FTRACE_NOP into the remaining four
89
120
* bytes of the original instruction so that the kprobes
90
121
* handler can execute a nop, if it reaches this breakpoint.
91
122
*/
92
- new .opc = orig .opc = BREAKPOINT_INSTRUCTION ;
93
- orig .disp = KPROBE_ON_FTRACE_CALL ;
94
- new .disp = KPROBE_ON_FTRACE_NOP ;
123
+ ftrace_generate_kprobe_call_insn (& orig );
124
+ ftrace_generate_kprobe_nop_insn (& new );
95
125
} else {
96
126
/* Replace ftrace call with a nop. */
97
127
ftrace_generate_call_insn (& orig , rec -> ip );
@@ -111,17 +141,16 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
111
141
112
142
if (probe_kernel_read (& old , (void * ) rec -> ip , sizeof (old )))
113
143
return - EFAULT ;
114
- if (old . opc == BREAKPOINT_INSTRUCTION ) {
144
+ if (is_kprobe_on_ftrace ( & old ) ) {
115
145
/*
116
146
* If we find a breakpoint instruction, a kprobe has been
117
147
* placed at the beginning of the function. We write the
118
148
* constant KPROBE_ON_FTRACE_CALL into the remaining four
119
149
* bytes of the original instruction so that the kprobes
120
150
* handler can execute a brasl if it reaches this breakpoint.
121
151
*/
122
- new .opc = orig .opc = BREAKPOINT_INSTRUCTION ;
123
- orig .disp = KPROBE_ON_FTRACE_NOP ;
124
- new .disp = KPROBE_ON_FTRACE_CALL ;
152
+ ftrace_generate_kprobe_nop_insn (& orig );
153
+ ftrace_generate_kprobe_call_insn (& new );
125
154
} else {
126
155
/* Replace nop with an ftrace call. */
127
156
ftrace_generate_nop_insn (& orig );
0 commit comments