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

dynamic_debug.h (6762B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _DYNAMIC_DEBUG_H
      3#define _DYNAMIC_DEBUG_H
      4
      5#if defined(CONFIG_JUMP_LABEL)
      6#include <linux/jump_label.h>
      7#endif
      8
      9/*
     10 * An instance of this structure is created in a special
     11 * ELF section at every dynamic debug callsite.  At runtime,
     12 * the special section is treated as an array of these.
     13 */
     14struct _ddebug {
     15	/*
     16	 * These fields are used to drive the user interface
     17	 * for selecting and displaying debug callsites.
     18	 */
     19	const char *modname;
     20	const char *function;
     21	const char *filename;
     22	const char *format;
     23	unsigned int lineno:18;
     24	/*
     25	 * The flags field controls the behaviour at the callsite.
     26	 * The bits here are changed dynamically when the user
     27	 * writes commands to <debugfs>/dynamic_debug/control
     28	 */
     29#define _DPRINTK_FLAGS_NONE	0
     30#define _DPRINTK_FLAGS_PRINT	(1<<0) /* printk() a message using the format */
     31#define _DPRINTK_FLAGS_INCL_MODNAME	(1<<1)
     32#define _DPRINTK_FLAGS_INCL_FUNCNAME	(1<<2)
     33#define _DPRINTK_FLAGS_INCL_LINENO	(1<<3)
     34#define _DPRINTK_FLAGS_INCL_TID		(1<<4)
     35
     36#define _DPRINTK_FLAGS_INCL_ANY		\
     37	(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
     38	 _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
     39
     40#if defined DEBUG
     41#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
     42#else
     43#define _DPRINTK_FLAGS_DEFAULT 0
     44#endif
     45	unsigned int flags:8;
     46#ifdef CONFIG_JUMP_LABEL
     47	union {
     48		struct static_key_true dd_key_true;
     49		struct static_key_false dd_key_false;
     50	} key;
     51#endif
     52} __attribute__((aligned(8)));
     53
     54
     55
     56#if defined(CONFIG_DYNAMIC_DEBUG_CORE)
     57
     58/* exported for module authors to exercise >control */
     59int dynamic_debug_exec_queries(const char *query, const char *modname);
     60
     61int ddebug_add_module(struct _ddebug *tab, unsigned int n,
     62				const char *modname);
     63extern int ddebug_remove_module(const char *mod_name);
     64extern __printf(2, 3)
     65void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
     66
     67extern int ddebug_dyndbg_module_param_cb(char *param, char *val,
     68					const char *modname);
     69
     70struct device;
     71
     72extern __printf(3, 4)
     73void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev,
     74		       const char *fmt, ...);
     75
     76struct net_device;
     77
     78extern __printf(3, 4)
     79void __dynamic_netdev_dbg(struct _ddebug *descriptor,
     80			  const struct net_device *dev,
     81			  const char *fmt, ...);
     82
     83struct ib_device;
     84
     85extern __printf(3, 4)
     86void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
     87			 const struct ib_device *ibdev,
     88			 const char *fmt, ...);
     89
     90#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)		\
     91	static struct _ddebug  __aligned(8)			\
     92	__section("__dyndbg") name = {				\
     93		.modname = KBUILD_MODNAME,			\
     94		.function = __func__,				\
     95		.filename = __FILE__,				\
     96		.format = (fmt),				\
     97		.lineno = __LINE__,				\
     98		.flags = _DPRINTK_FLAGS_DEFAULT,		\
     99		_DPRINTK_KEY_INIT				\
    100	}
    101
    102#ifdef CONFIG_JUMP_LABEL
    103
    104#ifdef DEBUG
    105
    106#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)
    107
    108#define DYNAMIC_DEBUG_BRANCH(descriptor) \
    109	static_branch_likely(&descriptor.key.dd_key_true)
    110#else
    111#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)
    112
    113#define DYNAMIC_DEBUG_BRANCH(descriptor) \
    114	static_branch_unlikely(&descriptor.key.dd_key_false)
    115#endif
    116
    117#else /* !CONFIG_JUMP_LABEL */
    118
    119#define _DPRINTK_KEY_INIT
    120
    121#ifdef DEBUG
    122#define DYNAMIC_DEBUG_BRANCH(descriptor) \
    123	likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
    124#else
    125#define DYNAMIC_DEBUG_BRANCH(descriptor) \
    126	unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
    127#endif
    128
    129#endif /* CONFIG_JUMP_LABEL */
    130
    131#define __dynamic_func_call(id, fmt, func, ...) do {	\
    132	DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt);		\
    133	if (DYNAMIC_DEBUG_BRANCH(id))			\
    134		func(&id, ##__VA_ARGS__);		\
    135} while (0)
    136
    137#define __dynamic_func_call_no_desc(id, fmt, func, ...) do {	\
    138	DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt);			\
    139	if (DYNAMIC_DEBUG_BRANCH(id))				\
    140		func(__VA_ARGS__);				\
    141} while (0)
    142
    143/*
    144 * "Factory macro" for generating a call to func, guarded by a
    145 * DYNAMIC_DEBUG_BRANCH. The dynamic debug descriptor will be
    146 * initialized using the fmt argument. The function will be called with
    147 * the address of the descriptor as first argument, followed by all
    148 * the varargs. Note that fmt is repeated in invocations of this
    149 * macro.
    150 */
    151#define _dynamic_func_call(fmt, func, ...)				\
    152	__dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
    153/*
    154 * A variant that does the same, except that the descriptor is not
    155 * passed as the first argument to the function; it is only called
    156 * with precisely the macro's varargs.
    157 */
    158#define _dynamic_func_call_no_desc(fmt, func, ...)	\
    159	__dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
    160
    161#define dynamic_pr_debug(fmt, ...)				\
    162	_dynamic_func_call(fmt,	__dynamic_pr_debug,		\
    163			   pr_fmt(fmt), ##__VA_ARGS__)
    164
    165#define dynamic_dev_dbg(dev, fmt, ...)				\
    166	_dynamic_func_call(fmt,__dynamic_dev_dbg, 		\
    167			   dev, fmt, ##__VA_ARGS__)
    168
    169#define dynamic_netdev_dbg(dev, fmt, ...)			\
    170	_dynamic_func_call(fmt, __dynamic_netdev_dbg,		\
    171			   dev, fmt, ##__VA_ARGS__)
    172
    173#define dynamic_ibdev_dbg(dev, fmt, ...)			\
    174	_dynamic_func_call(fmt, __dynamic_ibdev_dbg,		\
    175			   dev, fmt, ##__VA_ARGS__)
    176
    177#define dynamic_hex_dump(prefix_str, prefix_type, rowsize,		\
    178			 groupsize, buf, len, ascii)			\
    179	_dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
    180				   print_hex_dump,			\
    181				   KERN_DEBUG, prefix_str, prefix_type,	\
    182				   rowsize, groupsize, buf, len, ascii)
    183
    184#else /* !CONFIG_DYNAMIC_DEBUG_CORE */
    185
    186#include <linux/string.h>
    187#include <linux/errno.h>
    188#include <linux/printk.h>
    189
    190static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
    191				    const char *modname)
    192{
    193	return 0;
    194}
    195
    196static inline int ddebug_remove_module(const char *mod)
    197{
    198	return 0;
    199}
    200
    201static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
    202						const char *modname)
    203{
    204	if (strstr(param, "dyndbg")) {
    205		/* avoid pr_warn(), which wants pr_fmt() fully defined */
    206		printk(KERN_WARNING "dyndbg param is supported only in "
    207			"CONFIG_DYNAMIC_DEBUG builds\n");
    208		return 0; /* allow and ignore */
    209	}
    210	return -EINVAL;
    211}
    212
    213#define dynamic_pr_debug(fmt, ...)					\
    214	do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
    215#define dynamic_dev_dbg(dev, fmt, ...)					\
    216	do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0)
    217#define dynamic_hex_dump(prefix_str, prefix_type, rowsize,		\
    218			 groupsize, buf, len, ascii)			\
    219	do { if (0)							\
    220		print_hex_dump(KERN_DEBUG, prefix_str, prefix_type,	\
    221				rowsize, groupsize, buf, len, ascii);	\
    222	} while (0)
    223
    224static inline int dynamic_debug_exec_queries(const char *query, const char *modname)
    225{
    226	pr_warn("kernel not built with CONFIG_DYNAMIC_DEBUG_CORE\n");
    227	return 0;
    228}
    229
    230#endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
    231
    232#endif