xref: /OK3568_Linux_fs/kernel/include/trace/hooks/vendor_hooks.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun /*
4*4882a593Smuzhiyun  * Note: we intentionally omit include file ifdef protection
5*4882a593Smuzhiyun  *  This is due to the way trace events work. If a file includes two
6*4882a593Smuzhiyun  *  trace event headers under one "CREATE_TRACE_POINTS" the first include
7*4882a593Smuzhiyun  *  will override the DECLARE_RESTRICTED_HOOK and break the second include.
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifndef __GENKSYMS__
11*4882a593Smuzhiyun #include <linux/tracepoint.h>
12*4882a593Smuzhiyun #endif
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS)
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define DECLARE_HOOK DECLARE_TRACE
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun int android_rvh_probe_register(struct tracepoint *tp, void *probe, void *data);
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #ifdef TRACE_HEADER_MULTI_READ
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define DEFINE_HOOK_FN(_name, _reg, _unreg, proto, args)		\
23*4882a593Smuzhiyun 	static const char __tpstrtab_##_name[]				\
24*4882a593Smuzhiyun 	__section("__tracepoints_strings") = #_name;			\
25*4882a593Smuzhiyun 	extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name);	\
26*4882a593Smuzhiyun 	int __traceiter_##_name(void *__data, proto);			\
27*4882a593Smuzhiyun 	struct tracepoint __tracepoint_##_name	__used			\
28*4882a593Smuzhiyun 	__section("__tracepoints") = {					\
29*4882a593Smuzhiyun 		.name = __tpstrtab_##_name,				\
30*4882a593Smuzhiyun 		.key = STATIC_KEY_INIT_FALSE,				\
31*4882a593Smuzhiyun 		.static_call_key = &STATIC_CALL_KEY(tp_func_##_name),	\
32*4882a593Smuzhiyun 		.static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \
33*4882a593Smuzhiyun 		.iterator = &__traceiter_##_name,			\
34*4882a593Smuzhiyun 		.regfunc = _reg,					\
35*4882a593Smuzhiyun 		.unregfunc = _unreg,					\
36*4882a593Smuzhiyun 		.funcs = NULL };					\
37*4882a593Smuzhiyun 	__TRACEPOINT_ENTRY(_name);					\
38*4882a593Smuzhiyun 	int __nocfi __traceiter_##_name(void *__data, proto)			\
39*4882a593Smuzhiyun 	{								\
40*4882a593Smuzhiyun 		struct tracepoint_func *it_func_ptr;			\
41*4882a593Smuzhiyun 		void *it_func;						\
42*4882a593Smuzhiyun 									\
43*4882a593Smuzhiyun 		it_func_ptr = (&__tracepoint_##_name)->funcs;		\
44*4882a593Smuzhiyun 		it_func = (it_func_ptr)->func;				\
45*4882a593Smuzhiyun 		do {							\
46*4882a593Smuzhiyun 			__data = (it_func_ptr)->data;			\
47*4882a593Smuzhiyun 			((void(*)(void *, proto))(it_func))(__data, args); \
48*4882a593Smuzhiyun 			it_func = READ_ONCE((++it_func_ptr)->func);	\
49*4882a593Smuzhiyun 		} while (it_func);					\
50*4882a593Smuzhiyun 		return 0;						\
51*4882a593Smuzhiyun 	}								\
52*4882a593Smuzhiyun 	DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #undef DECLARE_RESTRICTED_HOOK
55*4882a593Smuzhiyun #define DECLARE_RESTRICTED_HOOK(name, proto, args, cond) \
56*4882a593Smuzhiyun 	DEFINE_HOOK_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args))
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /* prevent additional recursion */
59*4882a593Smuzhiyun #undef TRACE_HEADER_MULTI_READ
60*4882a593Smuzhiyun #else /* TRACE_HEADER_MULTI_READ */
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define DO_HOOK(name, proto, args, cond)				\
63*4882a593Smuzhiyun 	do {								\
64*4882a593Smuzhiyun 		struct tracepoint_func *it_func_ptr;			\
65*4882a593Smuzhiyun 		void *__data;						\
66*4882a593Smuzhiyun 									\
67*4882a593Smuzhiyun 		if (!(cond))						\
68*4882a593Smuzhiyun 			return;						\
69*4882a593Smuzhiyun 									\
70*4882a593Smuzhiyun 		it_func_ptr = (&__tracepoint_##name)->funcs;		\
71*4882a593Smuzhiyun 		if (it_func_ptr) {					\
72*4882a593Smuzhiyun 			__data = (it_func_ptr)->data;			\
73*4882a593Smuzhiyun 			__DO_TRACE_CALL(name)(args);			\
74*4882a593Smuzhiyun 		}							\
75*4882a593Smuzhiyun 	} while (0)
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun #define __DECLARE_HOOK(name, proto, args, cond, data_proto, data_args)	\
78*4882a593Smuzhiyun 	extern int __traceiter_##name(data_proto);			\
79*4882a593Smuzhiyun 	DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name);	\
80*4882a593Smuzhiyun 	extern struct tracepoint __tracepoint_##name;			\
81*4882a593Smuzhiyun 	static inline void __nocfi trace_##name(proto)			\
82*4882a593Smuzhiyun 	{								\
83*4882a593Smuzhiyun 		if (static_key_false(&__tracepoint_##name.key))		\
84*4882a593Smuzhiyun 			DO_HOOK(name,					\
85*4882a593Smuzhiyun 				TP_PROTO(data_proto),			\
86*4882a593Smuzhiyun 				TP_ARGS(data_args),			\
87*4882a593Smuzhiyun 				TP_CONDITION(cond));			\
88*4882a593Smuzhiyun 	}								\
89*4882a593Smuzhiyun 	static inline bool						\
90*4882a593Smuzhiyun 	trace_##name##_enabled(void)					\
91*4882a593Smuzhiyun 	{								\
92*4882a593Smuzhiyun 		return static_key_false(&__tracepoint_##name.key);	\
93*4882a593Smuzhiyun 	}								\
94*4882a593Smuzhiyun 	static inline int						\
95*4882a593Smuzhiyun 	register_trace_##name(void (*probe)(data_proto), void *data) 	\
96*4882a593Smuzhiyun 	{								\
97*4882a593Smuzhiyun 		return android_rvh_probe_register(&__tracepoint_##name,	\
98*4882a593Smuzhiyun 						  (void *)probe, data);	\
99*4882a593Smuzhiyun 	}								\
100*4882a593Smuzhiyun 	/* vendor hooks cannot be unregistered */			\
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun #undef DECLARE_RESTRICTED_HOOK
103*4882a593Smuzhiyun #define DECLARE_RESTRICTED_HOOK(name, proto, args, cond)		\
104*4882a593Smuzhiyun 	__DECLARE_HOOK(name, PARAMS(proto), PARAMS(args),		\
105*4882a593Smuzhiyun 			cond,						\
106*4882a593Smuzhiyun 			PARAMS(void *__data, proto),			\
107*4882a593Smuzhiyun 			PARAMS(__data, args))
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun #endif /* TRACE_HEADER_MULTI_READ */
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun #else /* !CONFIG_TRACEPOINTS || !CONFIG_ANDROID_VENDOR_HOOKS */
112*4882a593Smuzhiyun /* suppress trace hooks */
113*4882a593Smuzhiyun #define DECLARE_HOOK DECLARE_EVENT_NOP
114*4882a593Smuzhiyun #define DECLARE_RESTRICTED_HOOK(name, proto, args, cond)		\
115*4882a593Smuzhiyun 	DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
116*4882a593Smuzhiyun #endif
117