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/rcupdate.h> 9 #include <linux/refcount.h> 10 #include <linux/slab.h> 11 12 struct fprobe; 13 typedef int (*fprobe_entry_cb)(struct fprobe *fp, unsigned long entry_ip, 14 unsigned long ret_ip, struct ftrace_regs *regs, 15 void *entry_data); 16 17 typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip, 18 unsigned long ret_ip, struct ftrace_regs *regs, 19 void *entry_data); 20 21 /** 22 * struct fprobe_hlist_node - address based hash list node for fprobe. 23 * 24 * @hlist: The hlist node for address search hash table. 25 * @addr: One of the probing address of @fp. 26 * @fp: The fprobe which owns this. 27 */ 28 struct fprobe_hlist_node { 29 struct hlist_node hlist; 30 unsigned long addr; 31 struct fprobe *fp; 32 }; 33 34 /** 35 * struct fprobe_hlist - hash list nodes for fprobe. 36 * 37 * @hlist: The hlist node for existence checking hash table. 38 * @rcu: rcu_head for RCU deferred release. 39 * @fp: The fprobe which owns this fprobe_hlist. 40 * @size: The size of @array. 41 * @array: The fprobe_hlist_node for each address to probe. 42 */ 43 struct fprobe_hlist { 44 struct hlist_node hlist; 45 struct rcu_head rcu; 46 struct fprobe *fp; 47 int size; 48 struct fprobe_hlist_node array[] __counted_by(size); 49 }; 50 51 /** 52 * struct fprobe - ftrace based probe. 53 * 54 * @nmissed: The counter for missing events. 55 * @flags: The status flag. 56 * @entry_data_size: The private data storage size. 57 * @nr_maxactive: The max number of active functions. (*deprecated) 58 * @entry_handler: The callback function for function entry. 59 * @exit_handler: The callback function for function exit. 60 * @hlist_array: The fprobe_hlist for fprobe search from IP hash table. 61 */ 62 struct fprobe { 63 unsigned long nmissed; 64 unsigned int flags; 65 size_t entry_data_size; 66 int nr_maxactive; 67 68 fprobe_entry_cb entry_handler; 69 fprobe_exit_cb exit_handler; 70 71 struct fprobe_hlist *hlist_array; 72 }; 73 74 /* This fprobe is soft-disabled. */ 75 #define FPROBE_FL_DISABLED 1 76 77 /* 78 * This fprobe handler will be shared with kprobes. 79 * This flag must be set before registering. 80 */ 81 #define FPROBE_FL_KPROBE_SHARED 2 82 83 static inline bool fprobe_disabled(struct fprobe *fp) 84 { 85 return (fp) ? fp->flags & FPROBE_FL_DISABLED : false; 86 } 87 88 static inline bool fprobe_shared_with_kprobes(struct fprobe *fp) 89 { 90 return (fp) ? fp->flags & FPROBE_FL_KPROBE_SHARED : false; 91 } 92 93 #ifdef CONFIG_FPROBE 94 int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter); 95 int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num); 96 int register_fprobe_syms(struct fprobe *fp, const char **syms, int num); 97 int unregister_fprobe(struct fprobe *fp); 98 bool fprobe_is_registered(struct fprobe *fp); 99 #else 100 static inline int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter) 101 { 102 return -EOPNOTSUPP; 103 } 104 static inline int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num) 105 { 106 return -EOPNOTSUPP; 107 } 108 static inline int register_fprobe_syms(struct fprobe *fp, const char **syms, int num) 109 { 110 return -EOPNOTSUPP; 111 } 112 static inline int unregister_fprobe(struct fprobe *fp) 113 { 114 return -EOPNOTSUPP; 115 } 116 static inline bool fprobe_is_registered(struct fprobe *fp) 117 { 118 return false; 119 } 120 #endif 121 122 /** 123 * disable_fprobe() - Disable fprobe 124 * @fp: The fprobe to be disabled. 125 * 126 * This will soft-disable @fp. Note that this doesn't remove the ftrace 127 * hooks from the function entry. 128 */ 129 static inline void disable_fprobe(struct fprobe *fp) 130 { 131 if (fp) 132 fp->flags |= FPROBE_FL_DISABLED; 133 } 134 135 /** 136 * enable_fprobe() - Enable fprobe 137 * @fp: The fprobe to be enabled. 138 * 139 * This will soft-enable @fp. 140 */ 141 static inline void enable_fprobe(struct fprobe *fp) 142 { 143 if (fp) 144 fp->flags &= ~FPROBE_FL_DISABLED; 145 } 146 147 /* The entry data size is 4 bits (=16) * sizeof(long) in maximum */ 148 #define FPROBE_DATA_SIZE_BITS 4 149 #define MAX_FPROBE_DATA_SIZE_WORD ((1L << FPROBE_DATA_SIZE_BITS) - 1) 150 #define MAX_FPROBE_DATA_SIZE (MAX_FPROBE_DATA_SIZE_WORD * sizeof(long)) 151 152 #endif 153