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

Showing the changes to kernel/livepatch (2 of 8 files). Show all

Unified · Split

2 files
  1. kernel/livepatch/core.c +13 −16
  2. kernel/livepatch/shadow.c +3 −3
kernel/livepatch/core.c+13−16
@@ -862,14 +862,11 @@ static void klp_init_object_early(struct klp_patch *patch, · 861 unmodified lines
862 list_add_tail(&obj->node, &patch->obj_list);862 list_add_tail(&obj->node, &patch->obj_list);
863}863}
864 864
865static int klp_init_patch_early(struct klp_patch *patch)865static void klp_init_patch_early(struct klp_patch *patch)
866{866{
867 struct klp_object *obj;867 struct klp_object *obj;
868 struct klp_func *func;868 struct klp_func *func;
869 869
870 if (!patch->objs)
871 return -EINVAL;
872
873 INIT_LIST_HEAD(&patch->list);870 INIT_LIST_HEAD(&patch->list);
874 INIT_LIST_HEAD(&patch->obj_list);871 INIT_LIST_HEAD(&patch->obj_list);
875 kobject_init(&patch->kobj, &klp_ktype_patch);872 kobject_init(&patch->kobj, &klp_ktype_patch);
@@ -879,20 +876,12 @@ static int klp_init_patch_early(struct klp_patch *patch) · 3 unmodified lines
879 init_completion(&patch->finish);876 init_completion(&patch->finish);
880 877
881 klp_for_each_object_static(patch, obj) {878 klp_for_each_object_static(patch, obj) {
882 if (!obj->funcs)
883 return -EINVAL;
884
885 klp_init_object_early(patch, obj);879 klp_init_object_early(patch, obj);
886 880
887 klp_for_each_func_static(obj, func) {881 klp_for_each_func_static(obj, func) {
888 klp_init_func_early(obj, func);882 klp_init_func_early(obj, func);
889 }883 }
890 }884 }
891
892 if (!try_module_get(patch->mod))
893 return -ENODEV;
894
895 return 0;
896}885}
897 886
898static int klp_init_patch(struct klp_patch *patch)887static int klp_init_patch(struct klp_patch *patch)
@@ -1024,10 +1013,17 @@ err: · 125 unmodified lines
1024int klp_enable_patch(struct klp_patch *patch)1013int klp_enable_patch(struct klp_patch *patch)
1025{1014{
1026 int ret;1015 int ret;
1016 struct klp_object *obj;
1027 1017
1028 if (!patch || !patch->mod)1018 if (!patch || !patch->mod || !patch->objs)
1029 return -EINVAL;1019 return -EINVAL;
1030 1020
1021 klp_for_each_object_static(patch, obj) {
1022 if (!obj->funcs)
1023 return -EINVAL;
1024 }
1025
1026
1031 if (!is_livepatch_module(patch->mod)) {1027 if (!is_livepatch_module(patch->mod)) {
1032 pr_err("module %s is not marked as a livepatch module\n",1028 pr_err("module %s is not marked as a livepatch module\n",
1033 patch->mod->name);1029 patch->mod->name);
@@ -1051,12 +1047,13 @@ int klp_enable_patch(struct klp_patch *patch) · 17 unmodified lines
1051 return -EINVAL;1047 return -EINVAL;
1052 }1048 }
1053 1049
1054 ret = klp_init_patch_early(patch);1050 if (!try_module_get(patch->mod)) {
1055 if (ret) {
1056 mutex_unlock(&klp_mutex);1051 mutex_unlock(&klp_mutex);
1057 return ret;1052 return -ENODEV;
1058 }1053 }
1059 1054
1055 klp_init_patch_early(patch);
1056
1060 ret = klp_init_patch(patch);1057 ret = klp_init_patch(patch);
1061 if (ret)1058 if (ret)
1062 goto err;1059 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
272EXPORT_SYMBOL_GPL(klp_shadow_free);272EXPORT_SYMBOL_GPL(klp_shadow_free);
273 273
274/**274/**
275 * klp_shadow_free_all() - detach and free all <*, id> shadow variables275 * klp_shadow_free_all() - detach and free all <_, id> shadow variables
276 * @id: data identifier276 * @id: data identifier
277 * @dtor: custom callback that can be used to unregister the variable277 * @dtor: custom callback that can be used to unregister the variable
278 * and/or free data that the shadow variable points to (optional)278 * and/or free data that the shadow variable points to (optional)
279 *279 *
280 * This function releases the memory for all <*, id> shadow variable280 * This function releases the memory for all <_, id> shadow variable
281 * instances, callers should stop referencing them accordingly.281 * instances, callers should stop referencing them accordingly.
282 */282 */
283void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)283void 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
288 288
289 spin_lock_irqsave(&klp_shadow_lock, flags);289 spin_lock_irqsave(&klp_shadow_lock, flags);
290 290
291 /* Delete all <*, id> from hash */291 /* Delete all <_, id> from hash */
292 hash_for_each(klp_shadow_hash, i, shadow, node) {292 hash_for_each(klp_shadow_hash, i, shadow, node) {
293 if (klp_shadow_match(shadow, shadow->obj, id))293 if (klp_shadow_match(shadow, shadow->obj, id))
294 klp_shadow_free_struct(shadow, dtor);294 klp_shadow_free_struct(shadow, dtor);