xref: /linux/kernel/livepatch/core.h (revision 3bfaf1f7044c6a3b1e00fcad2d0529f0da449d67)
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_start(struct klp_patch *patch);
17 void klp_discard_replaced_patches(struct klp_patch *new_patch);
18 void klp_discard_nops(struct klp_patch *new_patch);
19 
20 static inline bool klp_is_object_loaded(struct klp_object *obj)
21 {
22 	return !obj->name || obj->mod;
23 }
24 
25 static inline int klp_pre_patch_callback(struct klp_object *obj)
26 {
27 	int ret = 0;
28 
29 	if (obj->callbacks.pre_patch)
30 		ret = (*obj->callbacks.pre_patch)(obj);
31 
32 	obj->callbacks.post_unpatch_enabled = !ret;
33 
34 	return ret;
35 }
36 
37 static inline void klp_post_patch_callback(struct klp_object *obj)
38 {
39 	if (obj->callbacks.post_patch)
40 		(*obj->callbacks.post_patch)(obj);
41 }
42 
43 static inline void klp_pre_unpatch_callback(struct klp_object *obj)
44 {
45 	if (obj->callbacks.pre_unpatch)
46 		(*obj->callbacks.pre_unpatch)(obj);
47 }
48 
49 static inline void klp_post_unpatch_callback(struct klp_object *obj)
50 {
51 	if (obj->callbacks.post_unpatch_enabled &&
52 	    obj->callbacks.post_unpatch)
53 		(*obj->callbacks.post_unpatch)(obj);
54 
55 	obj->callbacks.post_unpatch_enabled = false;
56 }
57 
58 #endif /* _LIVEPATCH_CORE_H */
59