cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

trace_custom_events.h (7228B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * This is similar to the trace_events.h file, but is to only
      4 * create custom trace events to be attached to existing tracepoints.
      5 * Where as the TRACE_EVENT() macro (from trace_events.h) will create
      6 * both the trace event and the tracepoint it will attach the event to,
      7 * TRACE_CUSTOM_EVENT() is to create only a custom version of an existing
      8 * trace event (created by TRACE_EVENT() or DEFINE_EVENT()), and will
      9 * be placed in the "custom" system.
     10 */
     11
     12#include <linux/trace_events.h>
     13
     14/* All custom events are placed in the custom group */
     15#undef TRACE_SYSTEM
     16#define TRACE_SYSTEM custom
     17
     18#ifndef TRACE_SYSTEM_VAR
     19#define TRACE_SYSTEM_VAR TRACE_SYSTEM
     20#endif
     21
     22/* The init stage creates the system string and enum mappings */
     23
     24#include "stages/init.h"
     25
     26#undef TRACE_CUSTOM_EVENT
     27#define TRACE_CUSTOM_EVENT(name, proto, args, tstruct, assign, print) \
     28	DECLARE_CUSTOM_EVENT_CLASS(name,			      \
     29			     PARAMS(proto),		       \
     30			     PARAMS(args),		       \
     31			     PARAMS(tstruct),		       \
     32			     PARAMS(assign),		       \
     33			     PARAMS(print));		       \
     34	DEFINE_CUSTOM_EVENT(name, name, PARAMS(proto), PARAMS(args));
     35
     36/* Stage 1 creates the structure of the recorded event layout */
     37
     38#include "stages/stage1_struct_define.h"
     39
     40#undef DECLARE_CUSTOM_EVENT_CLASS
     41#define DECLARE_CUSTOM_EVENT_CLASS(name, proto, args, tstruct, assign, print) \
     42	struct trace_custom_event_raw_##name {				\
     43		struct trace_entry	ent;				\
     44		tstruct							\
     45		char			__data[];			\
     46	};								\
     47									\
     48	static struct trace_event_class custom_event_class_##name;
     49
     50#undef DEFINE_CUSTOM_EVENT
     51#define DEFINE_CUSTOM_EVENT(template, name, proto, args)	\
     52	static struct trace_event_call	__used			\
     53	__attribute__((__aligned__(4))) custom_event_##name
     54
     55#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
     56
     57/* Stage 2 creates the custom class */
     58
     59#include "stages/stage2_data_offsets.h"
     60
     61#undef DECLARE_CUSTOM_EVENT_CLASS
     62#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
     63	struct trace_custom_event_data_offsets_##call {			\
     64		tstruct;						\
     65	};
     66
     67#undef DEFINE_CUSTOM_EVENT
     68#define DEFINE_CUSTOM_EVENT(template, name, proto, args)
     69
     70#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
     71
     72/* Stage 3 create the way to print the custom event */
     73
     74#include "stages/stage3_trace_output.h"
     75
     76#undef DECLARE_CUSTOM_EVENT_CLASS
     77#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
     78static notrace enum print_line_t					\
     79trace_custom_raw_output_##call(struct trace_iterator *iter, int flags,	\
     80			struct trace_event *trace_event)		\
     81{									\
     82	struct trace_seq *s = &iter->seq;				\
     83	struct trace_seq __maybe_unused *p = &iter->tmp_seq;		\
     84	struct trace_custom_event_raw_##call *field;			\
     85	int ret;							\
     86									\
     87	field = (typeof(field))iter->ent;				\
     88									\
     89	ret = trace_raw_output_prep(iter, trace_event);			\
     90	if (ret != TRACE_TYPE_HANDLED)					\
     91		return ret;						\
     92									\
     93	trace_event_printf(iter, print);				\
     94									\
     95	return trace_handle_return(s);					\
     96}									\
     97static struct trace_event_functions trace_custom_event_type_funcs_##call = { \
     98	.trace			= trace_custom_raw_output_##call,	\
     99};
    100
    101#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
    102
    103/* Stage 4 creates the offset layout for the fields */
    104
    105#include "stages/stage4_event_fields.h"
    106
    107#undef DECLARE_CUSTOM_EVENT_CLASS
    108#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, func, print)	\
    109static struct trace_event_fields trace_custom_event_fields_##call[] = {	\
    110	tstruct								\
    111	{} };
    112
    113#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
    114
    115/* Stage 5 creates the helper function for dynamic fields */
    116
    117#include "stages/stage5_get_offsets.h"
    118
    119#undef DECLARE_CUSTOM_EVENT_CLASS
    120#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
    121static inline notrace int trace_custom_event_get_offsets_##call(	\
    122	struct trace_custom_event_data_offsets_##call *__data_offsets, proto) \
    123{									\
    124	int __data_size = 0;						\
    125	int __maybe_unused __item_length;				\
    126	struct trace_custom_event_raw_##call __maybe_unused *entry;	\
    127									\
    128	tstruct;							\
    129									\
    130	return __data_size;						\
    131}
    132
    133#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
    134
    135/* Stage 6 creates the probe function that records the event */
    136
    137#include "stages/stage6_event_callback.h"
    138
    139#undef DECLARE_CUSTOM_EVENT_CLASS
    140#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
    141									\
    142static notrace void							\
    143trace_custom_event_raw_event_##call(void *__data, proto)		\
    144{									\
    145	struct trace_event_file *trace_file = __data;			\
    146	struct trace_custom_event_data_offsets_##call __maybe_unused __data_offsets; \
    147	struct trace_event_buffer fbuffer;				\
    148	struct trace_custom_event_raw_##call *entry;			\
    149	int __data_size;						\
    150									\
    151	if (trace_trigger_soft_disabled(trace_file))			\
    152		return;							\
    153									\
    154	__data_size = trace_custom_event_get_offsets_##call(&__data_offsets, args); \
    155									\
    156	entry = trace_event_buffer_reserve(&fbuffer, trace_file,	\
    157				 sizeof(*entry) + __data_size);		\
    158									\
    159	if (!entry)							\
    160		return;							\
    161									\
    162	tstruct								\
    163									\
    164	{ assign; }							\
    165									\
    166	trace_event_buffer_commit(&fbuffer);				\
    167}
    168/*
    169 * The ftrace_test_custom_probe is compiled out, it is only here as a build time check
    170 * to make sure that if the tracepoint handling changes, the ftrace probe will
    171 * fail to compile unless it too is updated.
    172 */
    173
    174#undef DEFINE_CUSTOM_EVENT
    175#define DEFINE_CUSTOM_EVENT(template, call, proto, args)		\
    176static inline void ftrace_test_custom_probe_##call(void)		\
    177{									\
    178	check_trace_callback_type_##call(trace_custom_event_raw_event_##template); \
    179}
    180
    181#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
    182
    183/* Stage 7 creates the actual class and event structure for the custom event */
    184
    185#include "stages/stage7_class_define.h"
    186
    187#undef DECLARE_CUSTOM_EVENT_CLASS
    188#define DECLARE_CUSTOM_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
    189static char custom_print_fmt_##call[] = print;					\
    190static struct trace_event_class __used __refdata custom_event_class_##call = { \
    191	.system			= TRACE_SYSTEM_STRING,			\
    192	.fields_array		= trace_custom_event_fields_##call,		\
    193	.fields			= LIST_HEAD_INIT(custom_event_class_##call.fields),\
    194	.raw_init		= trace_event_raw_init,			\
    195	.probe			= trace_custom_event_raw_event_##call,	\
    196	.reg			= trace_event_reg,			\
    197};
    198
    199#undef DEFINE_CUSTOM_EVENT
    200#define DEFINE_CUSTOM_EVENT(template, call, proto, args)		\
    201									\
    202static struct trace_event_call __used custom_event_##call = {		\
    203	.name			= #call,				\
    204	.class			= &custom_event_class_##template,	\
    205	.event.funcs		= &trace_custom_event_type_funcs_##template, \
    206	.print_fmt		= custom_print_fmt_##template,		\
    207	.flags			= TRACE_EVENT_FL_CUSTOM,		\
    208};									\
    209static inline int trace_custom_event_##call##_update(struct tracepoint *tp) \
    210{									\
    211	if (tp->name && strcmp(tp->name, #call) == 0) {			\
    212		custom_event_##call.tp = tp;				\
    213		custom_event_##call.flags = TRACE_EVENT_FL_TRACEPOINT;	\
    214		return 1;						\
    215	}								\
    216	return 0;							\
    217}									\
    218static struct trace_event_call __used					\
    219__section("_ftrace_events") *__custom_event_##call = &custom_event_##call
    220
    221#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)