Skip to content

Commit 53cd885

Browse files
liu-song-6borkmann
authored andcommitted
ftrace: Allow IPMODIFY and DIRECT ops on the same function
IPMODIFY (livepatch) and DIRECT (bpf trampoline) ops are both important users of ftrace. It is necessary to allow them work on the same function at the same time. First, DIRECT ops no longer specify IPMODIFY flag. Instead, DIRECT flag is handled together with IPMODIFY flag in __ftrace_hash_update_ipmodify(). Then, a callback function, ops_func, is added to ftrace_ops. This is used by ftrace core code to understand whether the DIRECT ops can share with an IPMODIFY ops. To share with IPMODIFY ops, the DIRECT ops need to implement the callback function and adjust the direct trampoline accordingly. If DIRECT ops is attached before the IPMODIFY ops, ftrace core code calls ENABLE_SHARE_IPMODIFY_PEER on the DIRECT ops before registering the IPMODIFY ops. If IPMODIFY ops is attached before the DIRECT ops, ftrace core code calls ENABLE_SHARE_IPMODIFY_SELF in __ftrace_hash_update_ipmodify. Owner of the DIRECT ops may return 0 if the DIRECT trampoline can share with IPMODIFY, so error code otherwise. The error code is propagated to register_ftrace_direct_multi so that onwer of the DIRECT trampoline can handle it properly. For more details, please refer to comment before enum ftrace_ops_cmd. Signed-off-by: Song Liu <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Reviewed-by: Steven Rostedt (Google) <[email protected]> Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/bpf/[email protected]
1 parent f96f644 commit 53cd885

File tree

2 files changed

+254
-26
lines changed

2 files changed

+254
-26
lines changed

include/linux/ftrace.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,43 @@ enum {
208208
FTRACE_OPS_FL_DIRECT = BIT(17),
209209
};
210210

211+
/*
212+
* FTRACE_OPS_CMD_* commands allow the ftrace core logic to request changes
213+
* to a ftrace_ops. Note, the requests may fail.
214+
*
215+
* ENABLE_SHARE_IPMODIFY_SELF - enable a DIRECT ops to work on the same
216+
* function as an ops with IPMODIFY. Called
217+
* when the DIRECT ops is being registered.
218+
* This is called with both direct_mutex and
219+
* ftrace_lock are locked.
220+
*
221+
* ENABLE_SHARE_IPMODIFY_PEER - enable a DIRECT ops to work on the same
222+
* function as an ops with IPMODIFY. Called
223+
* when the other ops (the one with IPMODIFY)
224+
* is being registered.
225+
* This is called with direct_mutex locked.
226+
*
227+
* DISABLE_SHARE_IPMODIFY_PEER - disable a DIRECT ops to work on the same
228+
* function as an ops with IPMODIFY. Called
229+
* when the other ops (the one with IPMODIFY)
230+
* is being unregistered.
231+
* This is called with direct_mutex locked.
232+
*/
233+
enum ftrace_ops_cmd {
234+
FTRACE_OPS_CMD_ENABLE_SHARE_IPMODIFY_SELF,
235+
FTRACE_OPS_CMD_ENABLE_SHARE_IPMODIFY_PEER,
236+
FTRACE_OPS_CMD_DISABLE_SHARE_IPMODIFY_PEER,
237+
};
238+
239+
/*
240+
* For most ftrace_ops_cmd,
241+
* Returns:
242+
* 0 - Success.
243+
* Negative on failure. The return value is dependent on the
244+
* callback.
245+
*/
246+
typedef int (*ftrace_ops_func_t)(struct ftrace_ops *op, enum ftrace_ops_cmd cmd);
247+
211248
#ifdef CONFIG_DYNAMIC_FTRACE
212249
/* The hash used to know what functions callbacks trace */
213250
struct ftrace_ops_hash {
@@ -250,6 +287,7 @@ struct ftrace_ops {
250287
unsigned long trampoline;
251288
unsigned long trampoline_size;
252289
struct list_head list;
290+
ftrace_ops_func_t ops_func;
253291
#endif
254292
};
255293

0 commit comments

Comments
 (0)