1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LIVEPATCH_CORE_H
3 #define _LIVEPATCH_CORE_H
4 
5 #include <linux/livepatch.h>
6 
7 extern struct mutex klp_mutex;
8 extern struct list_head klp_patches;
9 
10 #define klp_for_each_patch_safe(patch, tmp_patch)		\
11 	list_for_each_entry_safe(patch, tmp_patch, &klp_patches, list)
12 
13 #define klp_for_each_patch(patch)	\
14 	list_for_each_entry(patch, &klp_patches, list)
15 
16 void klp_free_patch_async(struct klp_patch *patch);
17 void klp_free_replaced_patches_async(struct klp_patch *new_patch);
18 void klp_unpatch_replaced_patches(struct klp_patch *new_patch);
19 void klp_discard_nops(struct klp_patch *new_patch);
20 
klp_is_object_loaded(struct klp_object * obj)21 static inline bool klp_is_object_loaded(struct klp_object *obj)
22 {
23 	return !obj->name || obj->mod;
24 }
25 
klp_pre_patch_callback(struct klp_object * obj)26 static inline int klp_pre_patch_callback(struct klp_object *obj)
27 {
28 	int ret = 0;
29 
30 	if (obj->callbacks.pre_patch)
31 		ret = (*obj->callbacks.pre_patch)(obj);
32 
33 	obj->callbacks.post_unpatch_enabled = !ret;
34 
35 	return ret;
36 }
37 
klp_post_patch_callback(struct klp_object * obj)38 static inline void klp_post_patch_callback(struct klp_object *obj)
39 {
40 	if (obj->callbacks.post_patch)
41 		(*obj->callbacks.post_patch)(obj);
42 }
43 
klp_pre_unpatch_callback(struct klp_object * obj)44 static inline void klp_pre_unpatch_callback(struct klp_object *obj)
45 {
46 	if (obj->callbacks.pre_unpatch)
47 		(*obj->callbacks.pre_unpatch)(obj);
48 }
49 
klp_post_unpatch_callback(struct klp_object * obj)50 static inline void klp_post_unpatch_callback(struct klp_object *obj)
51 {
52 	if (obj->callbacks.post_unpatch_enabled &&
53 	    obj->callbacks.post_unpatch)
54 		(*obj->callbacks.post_unpatch)(obj);
55 
56 	obj->callbacks.post_unpatch_enabled = false;
57 }
58 
59 #endif /* _LIVEPATCH_CORE_H */
60