diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-08 08:58:25 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-08 08:58:25 -0800 |
commit | b7af27bf9471f5d54d71dc2e4228d6bc065bdb57 (patch) | |
tree | efe61bdce366720345f4f4fb663c31c9a4f00a08 /include | |
parent | 851ca779d110f694b5d078bc4af06d3ad37169e8 (diff) | |
parent | f9d138145686b52b48ccb36557d6842076e2b9dd (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching
Pull livepatching updates from Jiri Kosina:
- support for something we call 'atomic replace', and allows for much
better handling of cumulative patches (which is something very useful
for distros), from Jason Baron with help of Petr Mladek and Joe
Lawrence
- improvement of handling of tasks blocking finalization, from Miroslav
Benes
- update of MAINTAINERS file to reflect move towards group
maintainership
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching: (22 commits)
livepatch/selftests: use "$@" to preserve argument list
livepatch: Module coming and going callbacks can proceed with all listed patches
livepatch: Proper error handling in the shadow variables selftest
livepatch: return -ENOMEM on ptr_id() allocation failure
livepatch: Introduce klp_for_each_patch macro
livepatch: core: Return EOPNOTSUPP instead of ENOSYS
selftests/livepatch: add DYNAMIC_DEBUG config dependency
livepatch: samples: non static warnings fix
livepatch: update MAINTAINERS
livepatch: Remove signal sysfs attribute
livepatch: Send a fake signal periodically
selftests/livepatch: introduce tests
livepatch: Remove ordering (stacking) of the livepatches
livepatch: Atomic replace and cumulative patches documentation
livepatch: Remove Nop structures when unused
livepatch: Add atomic replace
livepatch: Use lists to manage patches, objects and functions
livepatch: Simplify API by removing registration step
livepatch: Don't block the removal of patches loaded after a forced transition
livepatch: Consolidate klp_free functions
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/livepatch.h | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index aec44b1d9582..53551f470722 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -24,6 +24,7 @@ #include <linux/module.h> #include <linux/ftrace.h> #include <linux/completion.h> +#include <linux/list.h> #if IS_ENABLED(CONFIG_LIVEPATCH) @@ -40,11 +41,14 @@ * @new_func: pointer to the patched function code * @old_sympos: a hint indicating which symbol position the old function * can be found (optional) - * @old_addr: the address of the function being patched + * @old_func: pointer to the function being patched * @kobj: kobject for sysfs resources + * @node: list node for klp_object func_list * @stack_node: list node for klp_ops func_stack list * @old_size: size of the old function * @new_size: size of the new function + * @kobj_added: @kobj has been added and needs freeing + * @nop: temporary patch to use the original code again; dyn. allocated * @patched: the func has been added to the klp_ops list * @transition: the func is currently being applied or reverted * @@ -77,10 +81,13 @@ struct klp_func { unsigned long old_sympos; /* internal */ - unsigned long old_addr; + void *old_func; struct kobject kobj; + struct list_head node; struct list_head stack_node; unsigned long old_size, new_size; + bool kobj_added; + bool nop; bool patched; bool transition; }; @@ -115,8 +122,12 @@ struct klp_callbacks { * @funcs: function entries for functions to be patched in the object * @callbacks: functions to be executed pre/post (un)patching * @kobj: kobject for sysfs resources + * @func_list: dynamic list of the function entries + * @node: list node for klp_patch obj_list * @mod: kernel module associated with the patched object * (NULL for vmlinux) + * @kobj_added: @kobj has been added and needs freeing + * @dynamic: temporary object for nop functions; dynamically allocated * @patched: the object's funcs have been added to the klp_ops list */ struct klp_object { @@ -127,7 +138,11 @@ struct klp_object { /* internal */ struct kobject kobj; + struct list_head func_list; + struct list_head node; struct module *mod; + bool kobj_added; + bool dynamic; bool patched; }; @@ -135,35 +150,54 @@ struct klp_object { * struct klp_patch - patch structure for live patching * @mod: reference to the live patch module * @objs: object entries for kernel objects to be patched - * @list: list node for global list of registered patches + * @replace: replace all actively used patches + * @list: list node for global list of actively used patches * @kobj: kobject for sysfs resources + * @obj_list: dynamic list of the object entries + * @kobj_added: @kobj has been added and needs freeing * @enabled: the patch is enabled (but operation may be incomplete) + * @forced: was involved in a forced transition + * @free_work: patch cleanup from workqueue-context * @finish: for waiting till it is safe to remove the patch module */ struct klp_patch { /* external */ struct module *mod; struct klp_object *objs; + bool replace; /* internal */ struct list_head list; struct kobject kobj; + struct list_head obj_list; + bool kobj_added; bool enabled; + bool forced; + struct work_struct free_work; struct completion finish; }; -#define klp_for_each_object(patch, obj) \ +#define klp_for_each_object_static(patch, obj) \ for (obj = patch->objs; obj->funcs || obj->name; obj++) -#define klp_for_each_func(obj, func) \ +#define klp_for_each_object_safe(patch, obj, tmp_obj) \ + list_for_each_entry_safe(obj, tmp_obj, &patch->obj_list, node) + +#define klp_for_each_object(patch, obj) \ + list_for_each_entry(obj, &patch->obj_list, node) + +#define klp_for_each_func_static(obj, func) \ for (func = obj->funcs; \ func->old_name || func->new_func || func->old_sympos; \ func++) -int klp_register_patch(struct klp_patch *); -int klp_unregister_patch(struct klp_patch *); +#define klp_for_each_func_safe(obj, func, tmp_func) \ + list_for_each_entry_safe(func, tmp_func, &obj->func_list, node) + +#define klp_for_each_func(obj, func) \ + list_for_each_entry(func, &obj->func_list, node) + int klp_enable_patch(struct klp_patch *); -int klp_disable_patch(struct klp_patch *); void arch_klp_init_object_loaded(struct klp_patch *patch, struct klp_object *obj); |