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

perf.h (4757B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef LINUX_POWERPC_PERF_REQ_GEN_PERF_H_
      3#define LINUX_POWERPC_PERF_REQ_GEN_PERF_H_
      4
      5#include <linux/perf_event.h>
      6#include <linux/stringify.h>
      7
      8#ifndef REQUEST_FILE
      9#error "REQUEST_FILE must be defined before including"
     10#endif
     11
     12#ifndef NAME_LOWER
     13#error "NAME_LOWER must be defined before including"
     14#endif
     15
     16#ifndef NAME_UPPER
     17#error "NAME_UPPER must be defined before including"
     18#endif
     19
     20#define BE_TYPE_b1 __u8
     21#define BE_TYPE_b2 __be16
     22#define BE_TYPE_b4 __be32
     23#define BE_TYPE_b8 __be64
     24
     25#define BYTES_TO_BE_TYPE(bytes) \
     26		BE_TYPE_b##bytes
     27
     28#define CAT2_(a, b) a ## b
     29#define CAT2(a, b) CAT2_(a, b)
     30#define CAT3_(a, b, c) a ## b ## c
     31#define CAT3(a, b, c) CAT3_(a, b, c)
     32
     33/*
     34 * enumerate the request values as
     35 * <NAME_UPPER>_<request name> = <request value>
     36 */
     37#define REQUEST_VALUE__(name_upper, r_name) name_upper ## _ ## r_name
     38#define REQUEST_VALUE_(name_upper, r_name) REQUEST_VALUE__(name_upper, r_name)
     39#define REQUEST_VALUE(r_name) REQUEST_VALUE_(NAME_UPPER, r_name)
     40
     41#include "_clear.h"
     42#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \
     43	REQUEST_VALUE(r_name) = r_value,
     44enum CAT2(NAME_LOWER, _requests) {
     45#include REQUEST_FILE
     46};
     47
     48/*
     49 * For each request:
     50 * struct <NAME_LOWER>_<request name> {
     51 *	r_fields
     52 * };
     53 */
     54#include "_clear.h"
     55#define STRUCT_NAME__(name_lower, r_name) name_lower ## _ ## r_name
     56#define STRUCT_NAME_(name_lower, r_name) STRUCT_NAME__(name_lower, r_name)
     57#define STRUCT_NAME(r_name) STRUCT_NAME_(NAME_LOWER, r_name)
     58#define REQUEST_(r_name, r_value, r_idx_1, r_fields)	\
     59struct STRUCT_NAME(r_name) {				\
     60	r_fields					\
     61};
     62#define __field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \
     63	BYTES_TO_BE_TYPE(f_bytes) f_name;
     64#define __count_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \
     65	__field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name)
     66#define __array_(r_name, r_value, r_idx_1, a_offset, a_bytes, a_name) \
     67	__u8 a_name[a_bytes];
     68
     69#include REQUEST_FILE
     70
     71/*
     72 * Generate a check of the field offsets
     73 * <NAME_LOWER>_assert_offsets_correct()
     74 */
     75#include "_clear.h"
     76#define REQUEST_(r_name, r_value, index, r_fields)			\
     77r_fields
     78#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) \
     79	BUILD_BUG_ON(offsetof(struct STRUCT_NAME(r_name), f_name) != f_offset);
     80#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \
     81	__field_(r_name, r_value, r_idx_1, c_offset, c_size, c_name)
     82#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) \
     83	__field_(r_name, r_value, r_idx_1, a_offset, a_size, a_name)
     84
     85static inline void CAT2(NAME_LOWER, _assert_offsets_correct)(void)
     86{
     87#include REQUEST_FILE
     88}
     89
     90/*
     91 * Generate event attributes:
     92 * PMU_EVENT_ATTR_STRING(<request name>_<field name>,
     93 *	<NAME_LOWER>_event_attr_<request name>_<field name>,
     94 *		"request=<request value>"
     95 *		"starting_index=<starting index type>"
     96 *		"counter_info_version=CURRENT_COUNTER_INFO_VERSION"
     97 *		"length=<f_size>"
     98 *		"offset=<f_offset>")
     99 *
    100 *	TODO: counter_info_version may need to vary, we should interperate the
    101 *	value to some extent
    102 */
    103#define EVENT_ATTR_NAME__(name, r_name, c_name) \
    104	name ## _event_attr_ ## r_name ## _ ## c_name
    105#define EVENT_ATTR_NAME_(name, r_name, c_name) \
    106	EVENT_ATTR_NAME__(name, r_name, c_name)
    107#define EVENT_ATTR_NAME(r_name, c_name) \
    108	EVENT_ATTR_NAME_(NAME_LOWER, r_name, c_name)
    109
    110#include "_clear.h"
    111#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name)
    112#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name)
    113#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name)	\
    114PMU_EVENT_ATTR_STRING(							\
    115		CAT3(r_name, _, c_name),				\
    116		EVENT_ATTR_NAME(r_name, c_name),			\
    117		"request=" __stringify(r_value) ","			\
    118		r_idx_1 ","						\
    119		"counter_info_version="					\
    120			__stringify(COUNTER_INFO_VERSION_CURRENT) ","	\
    121		"length=" #c_size ","					\
    122		"offset=" #c_offset)
    123#define REQUEST_(r_name, r_value, r_idx_1, r_fields)			\
    124	r_fields
    125
    126#include REQUEST_FILE
    127
    128/*
    129 * Define event attribute array
    130 * static struct attribute *hv_gpci_event_attrs[] = {
    131 *	&<NAME_LOWER>_event_attr_<request name>_<field name>.attr,
    132 * };
    133 */
    134#include "_clear.h"
    135#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name)
    136#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name)	\
    137	&EVENT_ATTR_NAME(r_name, c_name).attr.attr,
    138#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name)
    139#define REQUEST_(r_name, r_value, r_idx_1, r_fields)			\
    140	r_fields
    141
    142static __maybe_unused struct attribute *hv_gpci_event_attrs[] = {
    143#include REQUEST_FILE
    144	NULL
    145};
    146
    147/* cleanup */
    148#include "_clear.h"
    149#undef EVENT_ATTR_NAME
    150#undef EVENT_ATTR_NAME_
    151#undef BIT_NAME
    152#undef BIT_NAME_
    153#undef STRUCT_NAME
    154#undef REQUEST_VALUE
    155#undef REQUEST_VALUE_
    156
    157#endif