History

Merge tag 'livepatching-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching

Pull livepatching updates from Petr Mladek: - Correctly handle kobjects when a livepatch init fails - Avoid CPU hogging when searching for many livepatched symbols - Add livepatch API page into documentation * tag 'livepatching-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching: livepatch: Avoid CPU hogging with cond_resched livepatch: Fix missing unlock on error in klp_enable_patch() livepatch: Fix kobject refcount bug on klp_init_patch_early failure path Documentation: livepatch: Add livepatch API page

Linus Torvalds committed 4 years ago

Commit 77dbd722 parents d0a231f b2dfc3f8 files · +54 −23Browse files

Unified · Split

8 files
  1. Documentation/livepatch/api.rst +30 −0
  2. Documentation/livepatch/index.rst +1 −0
  3. Documentation/livepatch/shadow-vars.rst +2 −2
  4. Documentation/livepatch/system-state.rst +2 −2
  5. kernel/kallsyms.c +1 −0
  6. kernel/livepatch/core.c +13 −16
  7. kernel/livepatch/shadow.c +3 −3
  8. kernel/module.c +2 −0
Documentation/livepatch/api.rst+30−0
@@ -0,0 +1,30 @@
1+.. SPDX-License-Identifier: GPL-2.0
2+
3+=================
4+Livepatching APIs
5+=================
6+
7+Livepatch Enablement
8+====================
9+
10+.. kernel-doc:: kernel/livepatch/core.c
11+ :export:
12+
13+
14+Shadow Variables
15+================
16+
17+.. kernel-doc:: kernel/livepatch/shadow.c
18+ :export:
19+
20+System State Changes
21+====================
22+
23+.. kernel-doc:: kernel/livepatch/state.c
24+ :export:
25+
26+Object Types
27+============
28+
29+.. kernel-doc:: include/linux/livepatch.h
30+ :identifiers: klp_patch klp_object klp_func klp_callbacks klp_state
Documentation/livepatch/index.rst+1−0
@@ -14,6 +14,7 @@ Kernel Livepatching · 13 unmodified lines
1414 shadow-vars
1515 system-state
1616 reliable-stacktrace
17+ api
1718
1819 .. only:: subproject and html
1920
Documentation/livepatch/shadow-vars.rst+2−2
@@ -82,8 +82,8 @@ to do actions that can be done only once when a new variable is allocated. · 81 unmodified lines
8282 - call destructor function if defined
8383 - free shadow variable
8484
85−* klp_shadow_free_all() - detach and free all <*, id> shadow variables
86− - find and remove any <*, id> references from global hashtable
85+* klp_shadow_free_all() - detach and free all <_, id> shadow variables
86+ - find and remove any <_, id> references from global hashtable
8787
8888 - if found
8989
Documentation/livepatch/system-state.rst+2−2
@@ -52,12 +52,12 @@ struct klp_state: · 51 unmodified lines
5252
5353 The state can be manipulated using two functions:
5454
55− - *klp_get_state(patch, id)*
55+ - klp_get_state()
5656
5757 - Get struct klp_state associated with the given livepatch
5858 and state id.
5959
60− - *klp_get_prev_state(id)*
60+ - klp_get_prev_state()
6161
6262 - Get struct klp_state associated with the given feature id and
6363 already installed livepatches.
kernel/kallsyms.c+1−0
@@ -243,6 +243,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, · 242 unmodified lines
243243 ret = fn(data, namebuf, NULL, kallsyms_sym_address(i));
244244 if (ret != 0)
245245 return ret;
246+ cond_resched();
246247 }
247248 return 0;
248249 }
kernel/livepatch/core.c+13−16
@@ -862,14 +862,11 @@ static void klp_init_object_early(struct klp_patch *patch, · 861 unmodified lines
862862 list_add_tail(&obj->node, &patch->obj_list);
863863 }
864864
865−static int klp_init_patch_early(struct klp_patch *patch)
865+static void klp_init_patch_early(struct klp_patch *patch)
866866 {
867867 struct klp_object *obj;
868868 struct klp_func *func;
869869
870− if (!patch->objs)
871− return -EINVAL;
872−
873870 INIT_LIST_HEAD(&patch->list);
874871 INIT_LIST_HEAD(&patch->obj_list);
875872 kobject_init(&patch->kobj, &klp_ktype_patch);
@@ -879,20 +876,12 @@ static int klp_init_patch_early(struct klp_patch *patch) · 3 unmodified lines
879876 init_completion(&patch->finish);
880877
881878 klp_for_each_object_static(patch, obj) {
882− if (!obj->funcs)
883− return -EINVAL;
884−
885879 klp_init_object_early(patch, obj);
886880
887881 klp_for_each_func_static(obj, func) {
888882 klp_init_func_early(obj, func);
889883 }
890884 }
891−
892− if (!try_module_get(patch->mod))
893− return -ENODEV;
894−
895− return 0;
896885 }
897886
898887 static int klp_init_patch(struct klp_patch *patch)
@@ -1024,10 +1013,17 @@ err: · 125 unmodified lines
10241013 int klp_enable_patch(struct klp_patch *patch)
10251014 {
10261015 int ret;
1016+ struct klp_object *obj;
10271017
1028− if (!patch || !patch->mod)
1018+ if (!patch || !patch->mod || !patch->objs)
10291019 return -EINVAL;
10301020
1021+ klp_for_each_object_static(patch, obj) {
1022+ if (!obj->funcs)
1023+ return -EINVAL;
1024+ }
1025+
1026+
10311027 if (!is_livepatch_module(patch->mod)) {
10321028 pr_err("module %s is not marked as a livepatch module\n",
10331029 patch->mod->name);
@@ -1051,12 +1047,13 @@ int klp_enable_patch(struct klp_patch *patch) · 17 unmodified lines
10511047 return -EINVAL;
10521048 }
10531049
1054− ret = klp_init_patch_early(patch);
1055− if (ret) {
1050+ if (!try_module_get(patch->mod)) {
10561051 mutex_unlock(&klp_mutex);
1057− return ret;
1052+ return -ENODEV;
10581053 }
10591054
1055+ klp_init_patch_early(patch);
1056+
10601057 ret = klp_init_patch(patch);
10611058 if (ret)
10621059 goto err;
kernel/livepatch/shadow.c+3−3
@@ -272,12 +272,12 @@ void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor) · 271 unmodified lines
272272 EXPORT_SYMBOL_GPL(klp_shadow_free);
273273
274274 /**
275− * klp_shadow_free_all() - detach and free all <*, id> shadow variables
275+ * klp_shadow_free_all() - detach and free all <_, id> shadow variables
276276 * @id: data identifier
277277 * @dtor: custom callback that can be used to unregister the variable
278278 * and/or free data that the shadow variable points to (optional)
279279 *
280− * This function releases the memory for all <*, id> shadow variable
280+ * This function releases the memory for all <_, id> shadow variable
281281 * instances, callers should stop referencing them accordingly.
282282 */
283283 void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
@@ -288,7 +288,7 @@ void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor) · 4 unmodified lines
288288
289289 spin_lock_irqsave(&klp_shadow_lock, flags);
290290
291− /* Delete all <*, id> from hash */
291+ /* Delete all <_, id> from hash */
292292 hash_for_each(klp_shadow_hash, i, shadow, node) {
293293 if (klp_shadow_match(shadow, shadow->obj, id))
294294 klp_shadow_free_struct(shadow, dtor);
kernel/module.c+2−0
@@ -4499,6 +4499,8 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, · 4498 unmodified lines
44994499 mod, kallsyms_symbol_value(sym));
45004500 if (ret != 0)
45014501 goto out;
4502+
4503+ cond_resched();
45024504 }
45034505 }
45044506 out: