1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#ifndef __KPATCH_MACROS_H_
#define __KPATCH_MACROS_H_
#include <linux/compiler.h>
#include <linux/jiffies.h>
#include <linux/version.h>
#include "kpatch-syscall.h"
/* upstream 33def8498fdd "treewide: Convert macro and uses of __section(foo) to __section("foo")" */
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
# define __kpatch_section(section) __section(section)
#else
# define __kpatch_section(section) __section(#section)
#endif
/*
* KPATCH_IGNORE_SECTION macro
*
* This macro is for ignoring sections that may change as a side effect of
* another change or might be a non-bundlable section; that is one that does
* not honor -ffunction-section and create a one-to-one relation from function
* symbol to section.
*/
#define KPATCH_IGNORE_SECTION(_sec) \
char *__UNIQUE_ID(kpatch_ignore_section_) __kpatch_section(.kpatch.ignore.sections) = _sec;
/*
* KPATCH_IGNORE_FUNCTION macro
*
* This macro is for ignoring functions that may change as a side effect of a
* change in another function. The WARN class of macros, for example, embed
* the line number in an instruction, which will cause the function to be
* detected as changed when, in fact, there has been no functional change.
*/
#define KPATCH_IGNORE_FUNCTION(_fn) \
void *__kpatch_ignore_func_##_fn __kpatch_section(.kpatch.ignore.functions) = _fn;
/* Support for livepatch callbacks */
#if IS_ENABLED(CONFIG_LIVEPATCH)
# ifdef RHEL_RELEASE_CODE
# if RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 5)
# define HAS_LIVEPATCH_CALLBACKS
# endif
# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
# define HAS_LIVEPATCH_CALLBACKS
# endif
#endif
#ifdef HAS_LIVEPATCH_CALLBACKS
# include <linux/livepatch.h>
typedef struct klp_object patch_object;
#else
# include "kpatch.h"
typedef struct kpatch_object patch_object;
#endif /* HAS_LIVEPATCH_CALLBACKS */
typedef int (*kpatch_pre_patch_call_t)(patch_object *obj);
typedef void (*kpatch_post_patch_call_t)(patch_object *obj);
typedef void (*kpatch_pre_unpatch_call_t)(patch_object *obj);
typedef void (*kpatch_post_unpatch_call_t)(patch_object *obj);
struct kpatch_pre_patch_callback {
kpatch_pre_patch_call_t fn;
char *objname; /* filled in by create-diff-object */
};
struct kpatch_post_patch_callback {
kpatch_post_patch_call_t fn;
char *objname; /* filled in by create-diff-object */
};
struct kpatch_pre_unpatch_callback {
kpatch_pre_unpatch_call_t fn;
char *objname; /* filled in by create-diff-object */
};
struct kpatch_post_unpatch_callback {
kpatch_post_unpatch_call_t fn;
char *objname; /* filled in by create-diff-object */
};
#define KPATCH_PRE_PATCH_CALLBACK(_fn) \
static inline kpatch_pre_patch_call_t __pre_patchtest(void) { return _fn; } \
static struct kpatch_pre_patch_callback kpatch_pre_patch_data __kpatch_section(.kpatch.callbacks.pre_patch) __used = { \
.fn = _fn, \
.objname = NULL \
};
#define KPATCH_POST_PATCH_CALLBACK(_fn) \
static inline kpatch_post_patch_call_t __post_patchtest(void) { return _fn; } \
static struct kpatch_post_patch_callback kpatch_post_patch_data __kpatch_section(.kpatch.callbacks.post_patch) __used = { \
.fn = _fn, \
.objname = NULL \
};
#define KPATCH_PRE_UNPATCH_CALLBACK(_fn) \
static inline kpatch_pre_unpatch_call_t __pre_unpatchtest(void) { return _fn; } \
static struct kpatch_pre_unpatch_callback kpatch_pre_unpatch_data __kpatch_section(.kpatch.callbacks.pre_unpatch) __used = { \
.fn = _fn, \
.objname = NULL \
};
#define KPATCH_POST_UNPATCH_CALLBACK(_fn) \
static inline kpatch_post_unpatch_call_t __post_unpatchtest(void) { return _fn; } \
static struct kpatch_post_unpatch_callback kpatch_post_unpatch_data __kpatch_section(.kpatch.callbacks.post_unpatch) __used = { \
.fn = _fn, \
.objname = NULL \
};
/*
* KPATCH_FORCE_UNSAFE macro
*
* USE WITH EXTREME CAUTION!
*
* Allows patch authors to bypass the activeness safety check at patch load
* time. Do this ONLY IF 1) the patch application will always/likely fail due
* to the function being on the stack of at least one thread at all times and
* 2) it is safe for both the original and patched versions of the function to
* run concurrently.
*/
#define KPATCH_FORCE_UNSAFE(_fn) \
void *__kpatch_force_func_##_fn __kpatch_section(.kpatch.force) = _fn;
/*
* KPATCH_PRINTK macro
*
* Use this instead of calling printk to avoid unwanted compiler optimizations
* which cause kpatch-build errors.
*
* The printk function is annotated with the __cold attribute, which tells gcc
* that the function is unlikely to be called. A side effect of this is that
* code paths containing calls to printk might also be marked cold, leading to
* other functions called in those code paths getting moved into .text.unlikely
* or being uninlined.
*
* This macro places printk in its own code path so as not to make the
* surrounding code path cold.
*/
#define KPATCH_PRINTK(_fmt, ...) \
({ \
if (jiffies) \
printk(_fmt, ## __VA_ARGS__); \
})
/*
* KPATCH_STATIC_CALL macro
*
* Replace usages of static_call() with this macro, when create-diff-object
* recommends it due to the original static call key living in a module.
*
* This converts the static call to a regular indirect call.
*/
#define KPATCH_STATIC_CALL(name) \
((typeof(STATIC_CALL_TRAMP(name))*)(STATIC_CALL_KEY(name).func))
#endif /* __KPATCH_MACROS_H_ */
|