aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/livepatch.h
diff options
context:
space:
mode:
authorPetr Mladek <pmladek@suse.com>2019-01-09 07:43:21 -0500
committerJiri Kosina <jkosina@suse.cz>2019-01-11 14:51:23 -0500
commit0430f78bf38f9972f0cf0522709cc63d49fa164c (patch)
tree365e431896c99c4a10b3d3db72cc261796587be6 /include/linux/livepatch.h
parent26c3e98e2f8e44e856cd36c12b3eaefcc6eafb16 (diff)
livepatch: Consolidate klp_free functions
The code for freeing livepatch structures is a bit scattered and tricky: + direct calls to klp_free_*_limited() and kobject_put() are used to release partially initialized objects + klp_free_patch() removes the patch from the public list and releases all objects except for patch->kobj + object_put(&patch->kobj) and the related wait_for_completion() are called directly outside klp_mutex; this code is duplicated; Now, we are going to remove the registration stage to simplify the API and the code. This would require handling more situations in klp_enable_patch() error paths. More importantly, we are going to add a feature called atomic replace. It will need to dynamically create func and object structures. We will want to reuse the existing init() and free() functions. This would create even more error path scenarios. This patch implements more straightforward free functions: + checks kobj_added flag instead of @limit[*] + initializes patch->list early so that the check for empty list always works + The action(s) that has to be done outside klp_mutex are done in separate klp_free_patch_finish() function. It waits only when patch->kobj was really released via the _start() part. The patch does not change the existing behavior. [*] We need our own flag to track that the kobject was successfully added to the hierarchy. Note that kobj.state_initialized only indicates that kobject has been initialized, not whether is has been added (and needs to be removed on cleanup). Signed-off-by: Petr Mladek <pmladek@suse.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Miroslav Benes <mbenes@suse.cz> Cc: Jessica Yu <jeyu@kernel.org> Cc: Jiri Kosina <jikos@kernel.org> Cc: Jason Baron <jbaron@akamai.com> Acked-by: Miroslav Benes <mbenes@suse.cz> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'include/linux/livepatch.h')
-rw-r--r--include/linux/livepatch.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index 634e13876380..6978785bc059 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -45,6 +45,7 @@
45 * @stack_node: list node for klp_ops func_stack list 45 * @stack_node: list node for klp_ops func_stack list
46 * @old_size: size of the old function 46 * @old_size: size of the old function
47 * @new_size: size of the new function 47 * @new_size: size of the new function
48 * @kobj_added: @kobj has been added and needs freeing
48 * @patched: the func has been added to the klp_ops list 49 * @patched: the func has been added to the klp_ops list
49 * @transition: the func is currently being applied or reverted 50 * @transition: the func is currently being applied or reverted
50 * 51 *
@@ -81,6 +82,7 @@ struct klp_func {
81 struct kobject kobj; 82 struct kobject kobj;
82 struct list_head stack_node; 83 struct list_head stack_node;
83 unsigned long old_size, new_size; 84 unsigned long old_size, new_size;
85 bool kobj_added;
84 bool patched; 86 bool patched;
85 bool transition; 87 bool transition;
86}; 88};
@@ -117,6 +119,7 @@ struct klp_callbacks {
117 * @kobj: kobject for sysfs resources 119 * @kobj: kobject for sysfs resources
118 * @mod: kernel module associated with the patched object 120 * @mod: kernel module associated with the patched object
119 * (NULL for vmlinux) 121 * (NULL for vmlinux)
122 * @kobj_added: @kobj has been added and needs freeing
120 * @patched: the object's funcs have been added to the klp_ops list 123 * @patched: the object's funcs have been added to the klp_ops list
121 */ 124 */
122struct klp_object { 125struct klp_object {
@@ -128,6 +131,7 @@ struct klp_object {
128 /* internal */ 131 /* internal */
129 struct kobject kobj; 132 struct kobject kobj;
130 struct module *mod; 133 struct module *mod;
134 bool kobj_added;
131 bool patched; 135 bool patched;
132}; 136};
133 137
@@ -137,6 +141,7 @@ struct klp_object {
137 * @objs: object entries for kernel objects to be patched 141 * @objs: object entries for kernel objects to be patched
138 * @list: list node for global list of registered patches 142 * @list: list node for global list of registered patches
139 * @kobj: kobject for sysfs resources 143 * @kobj: kobject for sysfs resources
144 * @kobj_added: @kobj has been added and needs freeing
140 * @enabled: the patch is enabled (but operation may be incomplete) 145 * @enabled: the patch is enabled (but operation may be incomplete)
141 * @finish: for waiting till it is safe to remove the patch module 146 * @finish: for waiting till it is safe to remove the patch module
142 */ 147 */
@@ -148,6 +153,7 @@ struct klp_patch {
148 /* internal */ 153 /* internal */
149 struct list_head list; 154 struct list_head list;
150 struct kobject kobj; 155 struct kobject kobj;
156 bool kobj_added;
151 bool enabled; 157 bool enabled;
152 struct completion finish; 158 struct completion finish;
153}; 159};