xref: /linux-6.15/include/linux/fprobe.h (revision a2224559)
1cad9931fSMasami Hiramatsu /* SPDX-License-Identifier: GPL-2.0 */
2cad9931fSMasami Hiramatsu /* Simple ftrace probe wrapper */
3cad9931fSMasami Hiramatsu #ifndef _LINUX_FPROBE_H
4cad9931fSMasami Hiramatsu #define _LINUX_FPROBE_H
5cad9931fSMasami Hiramatsu 
6cad9931fSMasami Hiramatsu #include <linux/compiler.h>
7cad9931fSMasami Hiramatsu #include <linux/ftrace.h>
8*4346ba16SMasami Hiramatsu (Google) #include <linux/rcupdate.h>
9*4346ba16SMasami Hiramatsu (Google) #include <linux/refcount.h>
10*4346ba16SMasami Hiramatsu (Google) #include <linux/slab.h>
11cad9931fSMasami Hiramatsu 
1273142cabSJiri Olsa struct fprobe;
1373142cabSJiri Olsa typedef int (*fprobe_entry_cb)(struct fprobe *fp, unsigned long entry_ip,
1446bc0823SMasami Hiramatsu (Google) 			       unsigned long ret_ip, struct ftrace_regs *regs,
1573142cabSJiri Olsa 			       void *entry_data);
1673142cabSJiri Olsa 
1773142cabSJiri Olsa typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip,
18762abbc0SMasami Hiramatsu (Google) 			       unsigned long ret_ip, struct ftrace_regs *regs,
1973142cabSJiri Olsa 			       void *entry_data);
2073142cabSJiri Olsa 
21cad9931fSMasami Hiramatsu /**
22*4346ba16SMasami Hiramatsu (Google)  * struct fprobe_hlist_node - address based hash list node for fprobe.
23*4346ba16SMasami Hiramatsu (Google)  *
24*4346ba16SMasami Hiramatsu (Google)  * @hlist: The hlist node for address search hash table.
25*4346ba16SMasami Hiramatsu (Google)  * @addr: One of the probing address of @fp.
26*4346ba16SMasami Hiramatsu (Google)  * @fp: The fprobe which owns this.
27*4346ba16SMasami Hiramatsu (Google)  */
28*4346ba16SMasami Hiramatsu (Google) struct fprobe_hlist_node {
29*4346ba16SMasami Hiramatsu (Google) 	struct hlist_node	hlist;
30*4346ba16SMasami Hiramatsu (Google) 	unsigned long		addr;
31*4346ba16SMasami Hiramatsu (Google) 	struct fprobe		*fp;
32*4346ba16SMasami Hiramatsu (Google) };
33*4346ba16SMasami Hiramatsu (Google) 
34*4346ba16SMasami Hiramatsu (Google) /**
35*4346ba16SMasami Hiramatsu (Google)  * struct fprobe_hlist - hash list nodes for fprobe.
36*4346ba16SMasami Hiramatsu (Google)  *
37*4346ba16SMasami Hiramatsu (Google)  * @hlist: The hlist node for existence checking hash table.
38*4346ba16SMasami Hiramatsu (Google)  * @rcu: rcu_head for RCU deferred release.
39*4346ba16SMasami Hiramatsu (Google)  * @fp: The fprobe which owns this fprobe_hlist.
40*4346ba16SMasami Hiramatsu (Google)  * @size: The size of @array.
41*4346ba16SMasami Hiramatsu (Google)  * @array: The fprobe_hlist_node for each address to probe.
42*4346ba16SMasami Hiramatsu (Google)  */
43*4346ba16SMasami Hiramatsu (Google) struct fprobe_hlist {
44*4346ba16SMasami Hiramatsu (Google) 	struct hlist_node		hlist;
45*4346ba16SMasami Hiramatsu (Google) 	struct rcu_head			rcu;
46*4346ba16SMasami Hiramatsu (Google) 	struct fprobe			*fp;
47*4346ba16SMasami Hiramatsu (Google) 	int				size;
48*4346ba16SMasami Hiramatsu (Google) 	struct fprobe_hlist_node	array[] __counted_by(size);
49*4346ba16SMasami Hiramatsu (Google) };
50*4346ba16SMasami Hiramatsu (Google) 
51*4346ba16SMasami Hiramatsu (Google) /**
52cad9931fSMasami Hiramatsu  * struct fprobe - ftrace based probe.
53*4346ba16SMasami Hiramatsu (Google)  *
54cad9931fSMasami Hiramatsu  * @nmissed: The counter for missing events.
55cad9931fSMasami Hiramatsu  * @flags: The status flag.
5676d0de57SMasami Hiramatsu (Google)  * @entry_data_size: The private data storage size.
57cad9931fSMasami Hiramatsu  * @entry_handler: The callback function for function entry.
585b0ab789SMasami Hiramatsu  * @exit_handler: The callback function for function exit.
59*4346ba16SMasami Hiramatsu (Google)  * @hlist_array: The fprobe_hlist for fprobe search from IP hash table.
60cad9931fSMasami Hiramatsu  */
61cad9931fSMasami Hiramatsu struct fprobe {
62cad9931fSMasami Hiramatsu 	unsigned long		nmissed;
63cad9931fSMasami Hiramatsu 	unsigned int		flags;
6476d0de57SMasami Hiramatsu (Google) 	size_t			entry_data_size;
655b0ab789SMasami Hiramatsu 
6673142cabSJiri Olsa 	fprobe_entry_cb entry_handler;
6773142cabSJiri Olsa 	fprobe_exit_cb  exit_handler;
68*4346ba16SMasami Hiramatsu (Google) 
69*4346ba16SMasami Hiramatsu (Google) 	struct fprobe_hlist	*hlist_array;
70cad9931fSMasami Hiramatsu };
71cad9931fSMasami Hiramatsu 
72ab51e15dSMasami Hiramatsu /* This fprobe is soft-disabled. */
73cad9931fSMasami Hiramatsu #define FPROBE_FL_DISABLED	1
74cad9931fSMasami Hiramatsu 
75ab51e15dSMasami Hiramatsu /*
76ab51e15dSMasami Hiramatsu  * This fprobe handler will be shared with kprobes.
77ab51e15dSMasami Hiramatsu  * This flag must be set before registering.
78ab51e15dSMasami Hiramatsu  */
79ab51e15dSMasami Hiramatsu #define FPROBE_FL_KPROBE_SHARED	2
80ab51e15dSMasami Hiramatsu 
fprobe_disabled(struct fprobe * fp)81cad9931fSMasami Hiramatsu static inline bool fprobe_disabled(struct fprobe *fp)
82cad9931fSMasami Hiramatsu {
83cad9931fSMasami Hiramatsu 	return (fp) ? fp->flags & FPROBE_FL_DISABLED : false;
84cad9931fSMasami Hiramatsu }
85cad9931fSMasami Hiramatsu 
fprobe_shared_with_kprobes(struct fprobe * fp)86ab51e15dSMasami Hiramatsu static inline bool fprobe_shared_with_kprobes(struct fprobe *fp)
87ab51e15dSMasami Hiramatsu {
88ab51e15dSMasami Hiramatsu 	return (fp) ? fp->flags & FPROBE_FL_KPROBE_SHARED : false;
89ab51e15dSMasami Hiramatsu }
90ab51e15dSMasami Hiramatsu 
91cad9931fSMasami Hiramatsu #ifdef CONFIG_FPROBE
92cad9931fSMasami Hiramatsu int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter);
93cad9931fSMasami Hiramatsu int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num);
94cad9931fSMasami Hiramatsu int register_fprobe_syms(struct fprobe *fp, const char **syms, int num);
95cad9931fSMasami Hiramatsu int unregister_fprobe(struct fprobe *fp);
96334e5519SMasami Hiramatsu (Google) bool fprobe_is_registered(struct fprobe *fp);
97cad9931fSMasami Hiramatsu #else
register_fprobe(struct fprobe * fp,const char * filter,const char * notfilter)98cad9931fSMasami Hiramatsu static inline int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter)
99cad9931fSMasami Hiramatsu {
100cad9931fSMasami Hiramatsu 	return -EOPNOTSUPP;
101cad9931fSMasami Hiramatsu }
register_fprobe_ips(struct fprobe * fp,unsigned long * addrs,int num)102cad9931fSMasami Hiramatsu static inline int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num)
103cad9931fSMasami Hiramatsu {
104cad9931fSMasami Hiramatsu 	return -EOPNOTSUPP;
105cad9931fSMasami Hiramatsu }
register_fprobe_syms(struct fprobe * fp,const char ** syms,int num)106cad9931fSMasami Hiramatsu static inline int register_fprobe_syms(struct fprobe *fp, const char **syms, int num)
107cad9931fSMasami Hiramatsu {
108cad9931fSMasami Hiramatsu 	return -EOPNOTSUPP;
109cad9931fSMasami Hiramatsu }
unregister_fprobe(struct fprobe * fp)110cad9931fSMasami Hiramatsu static inline int unregister_fprobe(struct fprobe *fp)
111cad9931fSMasami Hiramatsu {
112cad9931fSMasami Hiramatsu 	return -EOPNOTSUPP;
113cad9931fSMasami Hiramatsu }
fprobe_is_registered(struct fprobe * fp)114334e5519SMasami Hiramatsu (Google) static inline bool fprobe_is_registered(struct fprobe *fp)
115334e5519SMasami Hiramatsu (Google) {
116334e5519SMasami Hiramatsu (Google) 	return false;
117334e5519SMasami Hiramatsu (Google) }
118cad9931fSMasami Hiramatsu #endif
119cad9931fSMasami Hiramatsu 
120cad9931fSMasami Hiramatsu /**
121cad9931fSMasami Hiramatsu  * disable_fprobe() - Disable fprobe
122cad9931fSMasami Hiramatsu  * @fp: The fprobe to be disabled.
123cad9931fSMasami Hiramatsu  *
124cad9931fSMasami Hiramatsu  * This will soft-disable @fp. Note that this doesn't remove the ftrace
125cad9931fSMasami Hiramatsu  * hooks from the function entry.
126cad9931fSMasami Hiramatsu  */
disable_fprobe(struct fprobe * fp)127cad9931fSMasami Hiramatsu static inline void disable_fprobe(struct fprobe *fp)
128cad9931fSMasami Hiramatsu {
129cad9931fSMasami Hiramatsu 	if (fp)
130cad9931fSMasami Hiramatsu 		fp->flags |= FPROBE_FL_DISABLED;
131cad9931fSMasami Hiramatsu }
132cad9931fSMasami Hiramatsu 
133cad9931fSMasami Hiramatsu /**
134cad9931fSMasami Hiramatsu  * enable_fprobe() - Enable fprobe
135cad9931fSMasami Hiramatsu  * @fp: The fprobe to be enabled.
136cad9931fSMasami Hiramatsu  *
137cad9931fSMasami Hiramatsu  * This will soft-enable @fp.
138cad9931fSMasami Hiramatsu  */
enable_fprobe(struct fprobe * fp)139cad9931fSMasami Hiramatsu static inline void enable_fprobe(struct fprobe *fp)
140cad9931fSMasami Hiramatsu {
141cad9931fSMasami Hiramatsu 	if (fp)
142cad9931fSMasami Hiramatsu 		fp->flags &= ~FPROBE_FL_DISABLED;
143cad9931fSMasami Hiramatsu }
144cad9931fSMasami Hiramatsu 
145*4346ba16SMasami Hiramatsu (Google) /* The entry data size is 4 bits (=16) * sizeof(long) in maximum */
146*4346ba16SMasami Hiramatsu (Google) #define FPROBE_DATA_SIZE_BITS		4
147*4346ba16SMasami Hiramatsu (Google) #define MAX_FPROBE_DATA_SIZE_WORD	((1L << FPROBE_DATA_SIZE_BITS) - 1)
148*4346ba16SMasami Hiramatsu (Google) #define MAX_FPROBE_DATA_SIZE		(MAX_FPROBE_DATA_SIZE_WORD * sizeof(long))
149*4346ba16SMasami Hiramatsu (Google) 
150cad9931fSMasami Hiramatsu #endif
151