1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Simple ftrace probe wrapper */ 3 #ifndef _LINUX_FPROBE_H 4 #define _LINUX_FPROBE_H 5 6 #include <linux/compiler.h> 7 #include <linux/ftrace.h> 8 #include <linux/rethook.h> 9 10 /** 11 * struct fprobe - ftrace based probe. 12 * @ops: The ftrace_ops. 13 * @nmissed: The counter for missing events. 14 * @flags: The status flag. 15 * @rethook: The rethook data structure. (internal data) 16 * @entry_data_size: The private data storage size. 17 * @nr_maxactive: The max number of active functions. 18 * @entry_handler: The callback function for function entry. 19 * @exit_handler: The callback function for function exit. 20 */ 21 struct fprobe { 22 #ifdef CONFIG_FUNCTION_TRACER 23 /* 24 * If CONFIG_FUNCTION_TRACER is not set, CONFIG_FPROBE is disabled too. 25 * But user of fprobe may keep embedding the struct fprobe on their own 26 * code. To avoid build error, this will keep the fprobe data structure 27 * defined here, but remove ftrace_ops data structure. 28 */ 29 struct ftrace_ops ops; 30 #endif 31 unsigned long nmissed; 32 unsigned int flags; 33 struct rethook *rethook; 34 size_t entry_data_size; 35 int nr_maxactive; 36 37 int (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, 38 unsigned long ret_ip, struct pt_regs *regs, 39 void *entry_data); 40 void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip, 41 unsigned long ret_ip, struct pt_regs *regs, 42 void *entry_data); 43 }; 44 45 /* This fprobe is soft-disabled. */ 46 #define FPROBE_FL_DISABLED 1 47 48 /* 49 * This fprobe handler will be shared with kprobes. 50 * This flag must be set before registering. 51 */ 52 #define FPROBE_FL_KPROBE_SHARED 2 53 54 static inline bool fprobe_disabled(struct fprobe *fp) 55 { 56 return (fp) ? fp->flags & FPROBE_FL_DISABLED : false; 57 } 58 59 static inline bool fprobe_shared_with_kprobes(struct fprobe *fp) 60 { 61 return (fp) ? fp->flags & FPROBE_FL_KPROBE_SHARED : false; 62 } 63 64 #ifdef CONFIG_FPROBE 65 int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter); 66 int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num); 67 int register_fprobe_syms(struct fprobe *fp, const char **syms, int num); 68 int unregister_fprobe(struct fprobe *fp); 69 bool fprobe_is_registered(struct fprobe *fp); 70 #else 71 static inline int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter) 72 { 73 return -EOPNOTSUPP; 74 } 75 static inline int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num) 76 { 77 return -EOPNOTSUPP; 78 } 79 static inline int register_fprobe_syms(struct fprobe *fp, const char **syms, int num) 80 { 81 return -EOPNOTSUPP; 82 } 83 static inline int unregister_fprobe(struct fprobe *fp) 84 { 85 return -EOPNOTSUPP; 86 } 87 static inline bool fprobe_is_registered(struct fprobe *fp) 88 { 89 return false; 90 } 91 #endif 92 93 /** 94 * disable_fprobe() - Disable fprobe 95 * @fp: The fprobe to be disabled. 96 * 97 * This will soft-disable @fp. Note that this doesn't remove the ftrace 98 * hooks from the function entry. 99 */ 100 static inline void disable_fprobe(struct fprobe *fp) 101 { 102 if (fp) 103 fp->flags |= FPROBE_FL_DISABLED; 104 } 105 106 /** 107 * enable_fprobe() - Enable fprobe 108 * @fp: The fprobe to be enabled. 109 * 110 * This will soft-enable @fp. 111 */ 112 static inline void enable_fprobe(struct fprobe *fp) 113 { 114 if (fp) 115 fp->flags &= ~FPROBE_FL_DISABLED; 116 } 117 118 #endif 119