1 #ifndef _KSPLICE_PATCH_H
2 #define _KSPLICE_PATCH_H
4 #define KSPLICE_OPTION_ASSUME_RODATA 0
5 #define KSPLICE_OPTION_MATCH_DATA_EARLY 1
7 struct ksplice_option
{
10 } __attribute__((packed
));
14 #include <linux/gfp.h>
15 #include <linux/stringify.h>
18 #define __used __attribute_used__
21 #define ksplice_call_int(name, fn) \
22 static typeof(int (*)(void)) __ksplice_##name##_##fn __used \
23 __attribute__((__section__(".ksplice_call_" #name))) = fn
25 #define ksplice_call_void(name, fn) \
26 static typeof(void (*)(void)) __ksplice_##name##_##fn __used \
27 __attribute__((__section__(".ksplice_call_" #name))) = fn
29 #define ksplice_pre_apply(fn) ksplice_call_int(pre_apply, fn)
30 #define ksplice_check_apply(fn) ksplice_call_int(check_apply, fn)
31 #define ksplice_apply(fn) ksplice_call_void(apply, fn)
32 #define ksplice_post_apply(fn) ksplice_call_void(post_apply, fn)
33 #define ksplice_fail_apply(fn) ksplice_call_void(fail_apply, fn)
35 #define ksplice_pre_reverse(fn) ksplice_call_int(pre_reverse, fn)
36 #define ksplice_check_reverse(fn) ksplice_call_int(check_reverse, fn)
37 #define ksplice_reverse(fn) ksplice_call_void(reverse, fn)
38 #define ksplice_post_reverse(fn) ksplice_call_void(post_reverse, fn)
39 #define ksplice_fail_reverse(fn) ksplice_call_void(fail_reverse, fn)
42 #define ksplice_assume_rodata(obj) \
43 ksplice_option(KSPLICE_OPTION_ASSUME_RODATA, obj)
45 #define ksplice_match_data_early(obj) \
46 ksplice_option(KSPLICE_OPTION_MATCH_DATA_EARLY, obj)
48 #if BITS_PER_LONG == 32
49 #define KSPLICE_PTR ".long"
50 #elif BITS_PER_LONG == 64
51 #define KSPLICE_PTR ".quad"
52 #endif /* BITS_PER_LONG */
54 #define ksplice_option(num, obj) \
55 __asm__(".pushsection \".ksplice_options\", \"a\"\n" \
56 "\t.long " __stringify(num) "\n" \
57 "\t" KSPLICE_PTR " " #obj "\n" \
60 int init_shadow_field_type(int *shadow_key
, typeof(GFP_KERNEL
) gfp_flags
);
61 void *init_shadow_field(int *shadow_key
, void *obj
, int size
,
62 typeof(GFP_KERNEL
) gfp_flags
);
63 void cleanup_shadow_field(int *shadow_key
, void *obj
);
64 void *get_shadow_field(int *shadow_key
, void *obj
);
65 void cleanup_shadow_field_type(int *shadow_key
);
68 #define __DEFINE_SHADOW_FIELD(base_type, field_type, gfp_flags, \
69 init_field_type_fn, init_field_fn, get_field_fn, \
70 make_field_fn, cleanup_field_fn, \
71 cleanup_field_type_fn, shadow_key, init_field) \
72 static int shadow_key = 0; \
73 int init_field_type_fn(void) \
75 return init_shadow_field_type(&shadow_key, gfp_flags); \
77 field_type *init_field_fn(base_type *obj, typeof(GFP_KERNEL) flags) \
79 field_type *data = init_shadow_field(&shadow_key, (void *)obj, \
80 sizeof(*data), flags); \
85 void cleanup_field_fn(base_type *obj) \
87 cleanup_shadow_field(&shadow_key, obj); \
89 field_type *get_field_fn(base_type *obj) \
91 return get_shadow_field(&shadow_key, obj); \
93 field_type *make_field_fn(base_type *obj, typeof(GFP_KERNEL) flags) \
95 void *data = get_shadow_field(&shadow_key, (void *)obj); \
97 data = init_field_fn(obj, flags); \
100 void cleanup_field_type_fn(void) \
102 return cleanup_shadow_field_type(&shadow_key); \
104 struct eat_trailing_semicolon
106 #define DEFINE_SHADOW_FIELD(base_type, field_type, gfp_flags, name, init_field) \
107 __DEFINE_SHADOW_FIELD(base_type, field_type, gfp_flags, \
108 init_##name##_shadows, init_##name##_shadow, \
109 get_##name##_shadow, make_##name##_shadow, \
110 cleanup_##name##_shadow, cleanup_##name##_shadows,\
111 shadow_key_##name, init_field); \
112 ksplice_check_apply(init_##name##_shadows); \
113 ksplice_post_reverse(cleanup_##name##_shadows); \
114 ksplice_fail_apply(cleanup_##name##_shadows)
116 #define __DECLARE_SHADOW_FIELD(base_type, field_type, init_field_type_fn, \
117 init_field_fn, get_field_fn, make_field_fn, \
118 cleanup_field_fn, cleanup_field_type_fn) \
119 int init_field_type_fn(void); \
120 field_type *init_field_fn(base_type *obj, typeof(GFP_KERNEL) flags); \
121 void cleanup_field_fn(base_type *obj); \
122 field_type *get_field_fn(base_type *obj); \
123 field_type *make_field_fn(base_type *obj, typeof(GFP_KERNEL) flags); \
124 void cleanup_field_type_fn(void)
126 #define DECLARE_SHADOW_FIELD(base_type, field_type, name) \
127 __DECLARE_SHADOW_FIELD(base_type, field_type, init_##name##_shadows, \
128 init_##name##_shadow, get_##name##_shadow, \
129 make_##name##_shadow, cleanup_##name##_shadow, \
130 cleanup_##name##_shadows)
132 #endif /* __KERNEL__ */
134 #endif /* _KSPLICE_PATCH_H */