162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#undef TRACE_SYSTEM_VAR
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifdef CONFIG_BPF_EVENTS
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include "stages/stage6_event_callback.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#undef __perf_count
1062306a36Sopenharmony_ci#define __perf_count(c)	(c)
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#undef __perf_task
1362306a36Sopenharmony_ci#define __perf_task(t)	(t)
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/args.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* cast any integer, pointer, or small struct to u64 */
1862306a36Sopenharmony_ci#define UINTTYPE(size) \
1962306a36Sopenharmony_ci	__typeof__(__builtin_choose_expr(size == 1,  (u8)1, \
2062306a36Sopenharmony_ci		   __builtin_choose_expr(size == 2, (u16)2, \
2162306a36Sopenharmony_ci		   __builtin_choose_expr(size == 4, (u32)3, \
2262306a36Sopenharmony_ci		   __builtin_choose_expr(size == 8, (u64)4, \
2362306a36Sopenharmony_ci					 (void)5)))))
2462306a36Sopenharmony_ci#define __CAST_TO_U64(x) ({ \
2562306a36Sopenharmony_ci	typeof(x) __src = (x); \
2662306a36Sopenharmony_ci	UINTTYPE(sizeof(x)) __dst; \
2762306a36Sopenharmony_ci	memcpy(&__dst, &__src, sizeof(__dst)); \
2862306a36Sopenharmony_ci	(u64)__dst; })
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#define __CAST1(a,...) __CAST_TO_U64(a)
3162306a36Sopenharmony_ci#define __CAST2(a,...) __CAST_TO_U64(a), __CAST1(__VA_ARGS__)
3262306a36Sopenharmony_ci#define __CAST3(a,...) __CAST_TO_U64(a), __CAST2(__VA_ARGS__)
3362306a36Sopenharmony_ci#define __CAST4(a,...) __CAST_TO_U64(a), __CAST3(__VA_ARGS__)
3462306a36Sopenharmony_ci#define __CAST5(a,...) __CAST_TO_U64(a), __CAST4(__VA_ARGS__)
3562306a36Sopenharmony_ci#define __CAST6(a,...) __CAST_TO_U64(a), __CAST5(__VA_ARGS__)
3662306a36Sopenharmony_ci#define __CAST7(a,...) __CAST_TO_U64(a), __CAST6(__VA_ARGS__)
3762306a36Sopenharmony_ci#define __CAST8(a,...) __CAST_TO_U64(a), __CAST7(__VA_ARGS__)
3862306a36Sopenharmony_ci#define __CAST9(a,...) __CAST_TO_U64(a), __CAST8(__VA_ARGS__)
3962306a36Sopenharmony_ci#define __CAST10(a,...) __CAST_TO_U64(a), __CAST9(__VA_ARGS__)
4062306a36Sopenharmony_ci#define __CAST11(a,...) __CAST_TO_U64(a), __CAST10(__VA_ARGS__)
4162306a36Sopenharmony_ci#define __CAST12(a,...) __CAST_TO_U64(a), __CAST11(__VA_ARGS__)
4262306a36Sopenharmony_ci/* tracepoints with more than 12 arguments will hit build error */
4362306a36Sopenharmony_ci#define CAST_TO_U64(...) CONCATENATE(__CAST, COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__)
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define __BPF_DECLARE_TRACE(call, proto, args)				\
4662306a36Sopenharmony_cistatic notrace void							\
4762306a36Sopenharmony_ci__bpf_trace_##call(void *__data, proto)					\
4862306a36Sopenharmony_ci{									\
4962306a36Sopenharmony_ci	struct bpf_prog *prog = __data;					\
5062306a36Sopenharmony_ci	CONCATENATE(bpf_trace_run, COUNT_ARGS(args))(prog, CAST_TO_U64(args));	\
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
5462306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
5562306a36Sopenharmony_ci	__BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args))
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/*
5862306a36Sopenharmony_ci * This part is compiled out, it is only here as a build time check
5962306a36Sopenharmony_ci * to make sure that if the tracepoint handling changes, the
6062306a36Sopenharmony_ci * bpf probe will fail to compile unless it too is updated.
6162306a36Sopenharmony_ci */
6262306a36Sopenharmony_ci#define __DEFINE_EVENT(template, call, proto, args, size)		\
6362306a36Sopenharmony_cistatic inline void bpf_test_probe_##call(void)				\
6462306a36Sopenharmony_ci{									\
6562306a36Sopenharmony_ci	check_trace_callback_type_##call(__bpf_trace_##template);	\
6662306a36Sopenharmony_ci}									\
6762306a36Sopenharmony_citypedef void (*btf_trace_##call)(void *__data, proto);			\
6862306a36Sopenharmony_cistatic union {								\
6962306a36Sopenharmony_ci	struct bpf_raw_event_map event;					\
7062306a36Sopenharmony_ci	btf_trace_##call handler;					\
7162306a36Sopenharmony_ci} __bpf_trace_tp_map_##call __used					\
7262306a36Sopenharmony_ci__section("__bpf_raw_tp_map") = {					\
7362306a36Sopenharmony_ci	.event = {							\
7462306a36Sopenharmony_ci		.tp		= &__tracepoint_##call,			\
7562306a36Sopenharmony_ci		.bpf_func	= __bpf_trace_##template,		\
7662306a36Sopenharmony_ci		.num_args	= COUNT_ARGS(args),			\
7762306a36Sopenharmony_ci		.writable_size	= size,					\
7862306a36Sopenharmony_ci	},								\
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#define FIRST(x, ...) x
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci#define __CHECK_WRITABLE_BUF_SIZE(call, proto, args, size)		\
8462306a36Sopenharmony_cistatic inline void bpf_test_buffer_##call(void)				\
8562306a36Sopenharmony_ci{									\
8662306a36Sopenharmony_ci	/* BUILD_BUG_ON() is ignored if the code is completely eliminated, but \
8762306a36Sopenharmony_ci	 * BUILD_BUG_ON_ZERO() uses a different mechanism that is not	\
8862306a36Sopenharmony_ci	 * dead-code-eliminated.					\
8962306a36Sopenharmony_ci	 */								\
9062306a36Sopenharmony_ci	FIRST(proto);							\
9162306a36Sopenharmony_ci	(void)BUILD_BUG_ON_ZERO(size != sizeof(*FIRST(args)));		\
9262306a36Sopenharmony_ci}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci#undef DEFINE_EVENT_WRITABLE
9562306a36Sopenharmony_ci#define DEFINE_EVENT_WRITABLE(template, call, proto, args, size) \
9662306a36Sopenharmony_ci	__CHECK_WRITABLE_BUF_SIZE(call, PARAMS(proto), PARAMS(args), size) \
9762306a36Sopenharmony_ci	__DEFINE_EVENT(template, call, PARAMS(proto), PARAMS(args), size)
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#undef DEFINE_EVENT
10062306a36Sopenharmony_ci#define DEFINE_EVENT(template, call, proto, args)			\
10162306a36Sopenharmony_ci	__DEFINE_EVENT(template, call, PARAMS(proto), PARAMS(args), 0)
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT
10462306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, name, proto, args, print)	\
10562306a36Sopenharmony_ci	DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci#undef DECLARE_TRACE
10862306a36Sopenharmony_ci#define DECLARE_TRACE(call, proto, args)				\
10962306a36Sopenharmony_ci	__BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args))		\
11062306a36Sopenharmony_ci	__DEFINE_EVENT(call, call, PARAMS(proto), PARAMS(args), 0)
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci#undef DECLARE_TRACE_WRITABLE
11362306a36Sopenharmony_ci#define DECLARE_TRACE_WRITABLE(call, proto, args, size) \
11462306a36Sopenharmony_ci	__CHECK_WRITABLE_BUF_SIZE(call, PARAMS(proto), PARAMS(args), size) \
11562306a36Sopenharmony_ci	__BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args)) \
11662306a36Sopenharmony_ci	__DEFINE_EVENT(call, call, PARAMS(proto), PARAMS(args), size)
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#undef DECLARE_TRACE_WRITABLE
12162306a36Sopenharmony_ci#undef DEFINE_EVENT_WRITABLE
12262306a36Sopenharmony_ci#undef __CHECK_WRITABLE_BUF_SIZE
12362306a36Sopenharmony_ci#undef __DEFINE_EVENT
12462306a36Sopenharmony_ci#undef FIRST
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#endif /* CONFIG_BPF_EVENTS */
127