diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 7ca44534f863..961597b927b1 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -398,6 +398,7 @@ CONFIG_GENERIC_PHY=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_ANDROID_BINDERFS=y +CONFIG_ANDROID_VENDOR_HOOKS=y CONFIG_LIBNVDIMM=y # CONFIG_ND_BLK is not set CONFIG_INTERCONNECT=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index fb93ef7f709d..77fdd259b5f1 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -339,6 +339,7 @@ CONFIG_IIO_TRIGGER=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_ANDROID_BINDERFS=y +CONFIG_ANDROID_VENDOR_HOOKS=y CONFIG_LIBNVDIMM=y # CONFIG_ND_BLK is not set CONFIG_INTERCONNECT=y diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig index 6fdf2abe4598..392564cfe6c3 100644 --- a/drivers/android/Kconfig +++ b/drivers/android/Kconfig @@ -54,6 +54,15 @@ config ANDROID_BINDER_IPC_SELFTEST exhaustively with combinations of various buffer sizes and alignments. +config ANDROID_VENDOR_HOOKS + bool "Android Vendor Hooks" + depends on TRACEPOINTS + ---help--- + Enable vendor hooks implemented as tracepoints + + Allow vendor modules to attach to tracepoint "hooks" defined via + DECLARE_HOOK or DECLARE_RESTRICTED_HOOK. + endif # if ANDROID endmenu diff --git a/drivers/android/Makefile b/drivers/android/Makefile index c9d3d0c99c25..d488047415a0 100644 --- a/drivers/android/Makefile +++ b/drivers/android/Makefile @@ -4,3 +4,4 @@ ccflags-y += -I$(src) # needed for trace events obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o +obj-$(CONFIG_ANDROID_VENDOR_HOOKS) += vendor_hooks.o diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c new file mode 100644 index 000000000000..4a403a81eed3 --- /dev/null +++ b/drivers/android/vendor_hooks.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* vendor_hook.c + * + * Android Vendor Hook Support + * + * Copyright (C) 2020 Google, Inc. + */ + +#define CREATE_TRACE_POINTS +#include + +/* + * Export tracepoints that act as a bare tracehook (ie: have no trace event + * associated with them) to allow external modules to probe them. + */ + diff --git a/include/trace/hooks/vendor_hooks.h b/include/trace/hooks/vendor_hooks.h new file mode 100644 index 000000000000..9d9ae21895dd --- /dev/null +++ b/include/trace/hooks/vendor_hooks.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#if !defined(_TRACE_VENDOR_HOOKS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_VENDOR_HOOKS_H + +#include + +#define DECLARE_HOOK DECLARE_TRACE + +#ifdef TRACE_HEADER_MULTI_READ + +#undef DECLARE_RESTRICTED_HOOK +#define DECLARE_RESTRICTED_HOOK(name, proto, args, cond) \ + DEFINE_TRACE(name) + +/* prevent additional recursion */ +#undef TRACE_HEADER_MULTI_READ +#else /* TRACE_HEADER_MULTI_READ */ + +#define DO_HOOK(tp, proto, args, cond) \ + do { \ + struct tracepoint_func *it_func_ptr; \ + void *it_func; \ + void *__data; \ + \ + if (!(cond)) \ + return; \ + \ + it_func_ptr = (tp)->funcs; \ + if (it_func_ptr) { \ + it_func = (it_func_ptr)->func; \ + __data = (it_func_ptr)->data; \ + ((void(*)(proto))(it_func))(args); \ + WARN_ON(((++it_func_ptr)->func)); \ + } \ + } while (0) + +#define __DECLARE_HOOK(name, proto, args, cond, data_proto, data_args) \ + extern struct tracepoint __tracepoint_##name; \ + static inline void trace_##name(proto) \ + { \ + if (static_key_false(&__tracepoint_##name.key)) \ + DO_HOOK(&__tracepoint_##name, \ + TP_PROTO(data_proto), \ + TP_ARGS(data_args), \ + TP_CONDITION(cond)); \ + } \ + static inline bool \ + trace_##name##_enabled(void) \ + { \ + return static_key_false(&__tracepoint_##name.key); \ + } \ + static inline int \ + register_trace_##name(void (*probe)(data_proto), void *data) \ + { \ + /* only allow a single attachment */ \ + if (trace_##name##_enabled()) \ + return -EBUSY; \ + return tracepoint_probe_register(&__tracepoint_##name, \ + (void *)probe, data); \ + } \ + /* vendor hooks cannot be unregistered */ \ + +#define DECLARE_RESTRICTED_HOOK(name, proto, args, cond) \ + __DECLARE_HOOK(name, PARAMS(proto), PARAMS(args), \ + cond, \ + PARAMS(void *__data, proto), \ + PARAMS(__data, args)) + +#endif /* TRACE_HEADER_MULTI_READ */ + +#endif /* _TRACE_VENDOR_HOOKS_H */