Blame kmod/patch/kpatch-macros.h

Packit Service ac8aad
#ifndef __KPATCH_MACROS_H_
Packit Service ac8aad
#define __KPATCH_MACROS_H_
Packit Service ac8aad
Packit Service ac8aad
#include <linux/compiler.h>
Packit Service ac8aad
#include <linux/jiffies.h>
Packit Service ac8aad
#include <linux/version.h>
Packit Service ac8aad
Packit Service ac8aad
/*
Packit Service ac8aad
 * KPATCH_IGNORE_SECTION macro
Packit Service ac8aad
 *
Packit Service ac8aad
 * This macro is for ignoring sections that may change as a side effect of
Packit Service ac8aad
 * another change or might be a non-bundlable section; that is one that does
Packit Service ac8aad
 * not honor -ffunction-section and create a one-to-one relation from function
Packit Service ac8aad
 * symbol to section.
Packit Service ac8aad
 */
Packit Service ac8aad
#define KPATCH_IGNORE_SECTION(_sec) \
Packit Service ac8aad
	char *__UNIQUE_ID(kpatch_ignore_section_) __section(.kpatch.ignore.sections) = _sec;
Packit Service ac8aad
Packit Service ac8aad
/*
Packit Service ac8aad
 * KPATCH_IGNORE_FUNCTION macro
Packit Service ac8aad
 *
Packit Service ac8aad
 * This macro is for ignoring functions that may change as a side effect of a
Packit Service ac8aad
 * change in another function.  The WARN class of macros, for example, embed
Packit Service ac8aad
 * the line number in an instruction, which will cause the function to be
Packit Service ac8aad
 * detected as changed when, in fact, there has been no functional change.
Packit Service ac8aad
 */
Packit Service ac8aad
#define KPATCH_IGNORE_FUNCTION(_fn) \
Packit Service ac8aad
	void *__kpatch_ignore_func_##_fn __section(.kpatch.ignore.functions) = _fn;
Packit Service ac8aad
Packit Service ac8aad
Packit Service ac8aad
/* Support for livepatch callbacks */
Packit Service ac8aad
#if IS_ENABLED(CONFIG_LIVEPATCH)
Packit Service ac8aad
# ifdef RHEL_RELEASE_CODE
Packit Service ac8aad
#  if RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 5)
Packit Service ac8aad
#   define HAS_LIVEPATCH_CALLBACKS
Packit Service ac8aad
#  endif
Packit Service ac8aad
# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
Packit Service ac8aad
#  define HAS_LIVEPATCH_CALLBACKS
Packit Service ac8aad
# endif
Packit Service ac8aad
#endif
Packit Service ac8aad
Packit Service ac8aad
#ifdef HAS_LIVEPATCH_CALLBACKS
Packit Service ac8aad
# include <linux/livepatch.h>
Packit Service ac8aad
typedef struct klp_object patch_object;
Packit Service ac8aad
#else
Packit Service ac8aad
# include "kpatch.h"
Packit Service ac8aad
typedef struct kpatch_object patch_object;
Packit Service ac8aad
#endif /* HAS_LIVEPATCH_CALLBACKS */
Packit Service ac8aad
Packit Service ac8aad
typedef int (*kpatch_pre_patch_call_t)(patch_object *obj);
Packit Service ac8aad
typedef void (*kpatch_post_patch_call_t)(patch_object *obj);
Packit Service ac8aad
typedef void (*kpatch_pre_unpatch_call_t)(patch_object *obj);
Packit Service ac8aad
typedef void (*kpatch_post_unpatch_call_t)(patch_object *obj);
Packit Service ac8aad
Packit Service ac8aad
struct kpatch_pre_patch_callback {
Packit Service ac8aad
	kpatch_pre_patch_call_t fn;
Packit Service ac8aad
	char *objname; /* filled in by create-diff-object */
Packit Service ac8aad
};
Packit Service ac8aad
Packit Service ac8aad
struct kpatch_post_patch_callback {
Packit Service ac8aad
	kpatch_post_patch_call_t fn;
Packit Service ac8aad
	char *objname; /* filled in by create-diff-object */
Packit Service ac8aad
};
Packit Service ac8aad
Packit Service ac8aad
struct kpatch_pre_unpatch_callback {
Packit Service ac8aad
	kpatch_pre_unpatch_call_t fn;
Packit Service ac8aad
	char *objname; /* filled in by create-diff-object */
Packit Service ac8aad
};
Packit Service ac8aad
Packit Service ac8aad
struct kpatch_post_unpatch_callback {
Packit Service ac8aad
	kpatch_post_unpatch_call_t fn;
Packit Service ac8aad
	char *objname; /* filled in by create-diff-object */
Packit Service ac8aad
};
Packit Service ac8aad
Packit Service ac8aad
Packit Service ac8aad
#define KPATCH_PRE_PATCH_CALLBACK(_fn) \
Packit Service ac8aad
	static inline kpatch_pre_patch_call_t __pre_patchtest(void) { return _fn; } \
Packit Service ac8aad
	static struct kpatch_pre_patch_callback kpatch_pre_patch_data __section(.kpatch.callbacks.pre_patch) __used = { \
Packit Service ac8aad
		.fn = _fn, \
Packit Service ac8aad
		.objname = NULL \
Packit Service ac8aad
	};
Packit Service ac8aad
#define KPATCH_POST_PATCH_CALLBACK(_fn) \
Packit Service ac8aad
	static inline kpatch_post_patch_call_t __post_patchtest(void) { return _fn; } \
Packit Service ac8aad
	static struct kpatch_post_patch_callback kpatch_post_patch_data __section(.kpatch.callbacks.post_patch) __used = { \
Packit Service ac8aad
		.fn = _fn, \
Packit Service ac8aad
		.objname = NULL \
Packit Service ac8aad
	};
Packit Service ac8aad
#define KPATCH_PRE_UNPATCH_CALLBACK(_fn) \
Packit Service ac8aad
	static inline kpatch_pre_unpatch_call_t __pre_unpatchtest(void) { return _fn; } \
Packit Service ac8aad
	static struct kpatch_pre_unpatch_callback kpatch_pre_unpatch_data __section(.kpatch.callbacks.pre_unpatch) __used = { \
Packit Service ac8aad
		.fn = _fn, \
Packit Service ac8aad
		.objname = NULL \
Packit Service ac8aad
	};
Packit Service ac8aad
#define KPATCH_POST_UNPATCH_CALLBACK(_fn) \
Packit Service ac8aad
	static inline kpatch_post_unpatch_call_t __post_unpatchtest(void) { return _fn; } \
Packit Service ac8aad
	static struct kpatch_post_unpatch_callback kpatch_post_unpatch_data __section(.kpatch.callbacks.post_unpatch) __used = { \
Packit Service ac8aad
		.fn = _fn, \
Packit Service ac8aad
		.objname = NULL \
Packit Service ac8aad
	};
Packit Service ac8aad
Packit Service ac8aad
/*
Packit Service ac8aad
 * KPATCH_FORCE_UNSAFE macro
Packit Service ac8aad
 *
Packit Service ac8aad
 * USE WITH EXTREME CAUTION!
Packit Service ac8aad
 *
Packit Service ac8aad
 * Allows patch authors to bypass the activeness safety check at patch load
Packit Service ac8aad
 * time. Do this ONLY IF 1) the patch application will always/likely fail due
Packit Service ac8aad
 * to the function being on the stack of at least one thread at all times and
Packit Service ac8aad
 * 2) it is safe for both the original and patched versions of the function to
Packit Service ac8aad
 * run concurrently.
Packit Service ac8aad
 */
Packit Service ac8aad
#define KPATCH_FORCE_UNSAFE(_fn) \
Packit Service ac8aad
	void *__kpatch_force_func_##_fn __section(.kpatch.force) = _fn;
Packit Service ac8aad
Packit Service ac8aad
/*
Packit Service ac8aad
 * KPATCH_PRINTK macro
Packit Service ac8aad
 *
Packit Service ac8aad
 * Use this instead of calling printk to avoid unwanted compiler optimizations
Packit Service ac8aad
 * which cause kpatch-build errors.
Packit Service ac8aad
 *
Packit Service ac8aad
 * The printk function is annotated with the __cold attribute, which tells gcc
Packit Service ac8aad
 * that the function is unlikely to be called.  A side effect of this is that
Packit Service ac8aad
 * code paths containing calls to printk might also be marked cold, leading to
Packit Service ac8aad
 * other functions called in those code paths getting moved into .text.unlikely
Packit Service ac8aad
 * or being uninlined.
Packit Service ac8aad
 *
Packit Service ac8aad
 * This macro places printk in its own code path so as not to make the
Packit Service ac8aad
 * surrounding code path cold.
Packit Service ac8aad
 */
Packit Service ac8aad
#define KPATCH_PRINTK(_fmt, ...) \
Packit Service ac8aad
({ \
Packit Service ac8aad
	if (jiffies) \
Packit Service ac8aad
		printk(_fmt, ## __VA_ARGS__); \
Packit Service ac8aad
})
Packit Service ac8aad
Packit Service ac8aad
#endif /* __KPATCH_MACROS_H_ */