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