From 375bfca3459db1c5596c28c56d2ebac26e51c7b3 Mon Sep 17 00:00:00 2001 From: Alice Ferrazzi Date: Tue, 5 Feb 2019 03:33:28 +0900 Subject: livepatch: core: Return EOPNOTSUPP instead of ENOSYS As a result of an unsupported operation is better to use EOPNOTSUPP as error code. ENOSYS is only used for 'invalid syscall nr' and nothing else. Signed-off-by: Alice Ferrazzi Acked-by: Miroslav Benes Acked-by: Josh Poimboeuf Signed-off-by: Petr Mladek --- kernel/livepatch/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index adca5cf07f7e..5fc98a1cc3c3 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1036,7 +1036,7 @@ int klp_enable_patch(struct klp_patch *patch) if (!klp_have_reliable_stack()) { pr_err("This architecture doesn't have support for the livepatch consistency model.\n"); - return -ENOSYS; + return -EOPNOTSUPP; } -- cgit v1.2.3 From ecba29f434a8fa333356d54d2491d174c4aab8de Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Mon, 4 Feb 2019 14:56:50 +0100 Subject: livepatch: Introduce klp_for_each_patch macro There are already macros to iterate over struct klp_func and klp_object. Add also klp_for_each_patch(). But make it internal because also klp_patches list is internal. Suggested-by: Josh Poimboeuf Acked-by: Miroslav Benes Acked-by: Joe Lawrence Signed-off-by: Petr Mladek --- kernel/livepatch/core.c | 8 ++++---- kernel/livepatch/core.h | 6 ++++++ kernel/livepatch/transition.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 5fc98a1cc3c3..4b7f55d9e89c 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -554,7 +554,7 @@ static int klp_add_nops(struct klp_patch *patch) struct klp_patch *old_patch; struct klp_object *old_obj; - list_for_each_entry(old_patch, &klp_patches, list) { + klp_for_each_patch(old_patch) { klp_for_each_object(old_patch, old_obj) { int err; @@ -1089,7 +1089,7 @@ void klp_discard_replaced_patches(struct klp_patch *new_patch) { struct klp_patch *old_patch, *tmp_patch; - list_for_each_entry_safe(old_patch, tmp_patch, &klp_patches, list) { + klp_for_each_patch_safe(old_patch, tmp_patch) { if (old_patch == new_patch) return; @@ -1133,7 +1133,7 @@ static void klp_cleanup_module_patches_limited(struct module *mod, struct klp_patch *patch; struct klp_object *obj; - list_for_each_entry(patch, &klp_patches, list) { + klp_for_each_patch(patch) { if (patch == limit) break; @@ -1180,7 +1180,7 @@ int klp_module_coming(struct module *mod) */ mod->klp_alive = true; - list_for_each_entry(patch, &klp_patches, list) { + klp_for_each_patch(patch) { klp_for_each_object(patch, obj) { if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) continue; diff --git a/kernel/livepatch/core.h b/kernel/livepatch/core.h index e6200f38701f..ec43a40b853f 100644 --- a/kernel/livepatch/core.h +++ b/kernel/livepatch/core.h @@ -7,6 +7,12 @@ extern struct mutex klp_mutex; extern struct list_head klp_patches; +#define klp_for_each_patch_safe(patch, tmp_patch) \ + list_for_each_entry_safe(patch, tmp_patch, &klp_patches, list) + +#define klp_for_each_patch(patch) \ + list_for_each_entry(patch, &klp_patches, list) + void klp_free_patch_start(struct klp_patch *patch); void klp_discard_replaced_patches(struct klp_patch *new_patch); void klp_discard_nops(struct klp_patch *new_patch); diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index 300273819674..a3a6f32c6fd0 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -642,6 +642,6 @@ void klp_force_transition(void) for_each_possible_cpu(cpu) klp_update_patch_state(idle_task(cpu)); - list_for_each_entry(patch, &klp_patches, list) + klp_for_each_patch(patch) patch->forced = true; } -- cgit v1.2.3 From a087cdd4073b78f4739ce6709daeb4f3267b4dbf Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Mon, 4 Feb 2019 14:56:53 +0100 Subject: livepatch: Module coming and going callbacks can proceed with all listed patches Livepatches can no longer get enabled and disabled repeatedly. The list klp_patches contains only enabled patches and eventually the patch in transition. The module coming and going callbacks do no longer need to check for these state. They have to proceed with all listed patches. Suggested-by: Josh Poimboeuf Acked-by: Miroslav Benes Acked-by: Joe Lawrence Signed-off-by: Petr Mladek --- kernel/livepatch/core.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'kernel') diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 4b7f55d9e89c..d1af69e9f0e3 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1141,21 +1141,14 @@ static void klp_cleanup_module_patches_limited(struct module *mod, if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) continue; - /* - * Only unpatch the module if the patch is enabled or - * is in transition. - */ - if (patch->enabled || patch == klp_transition_patch) { - - if (patch != klp_transition_patch) - klp_pre_unpatch_callback(obj); + if (patch != klp_transition_patch) + klp_pre_unpatch_callback(obj); - pr_notice("reverting patch '%s' on unloading module '%s'\n", - patch->mod->name, obj->mod->name); - klp_unpatch_object(obj); + pr_notice("reverting patch '%s' on unloading module '%s'\n", + patch->mod->name, obj->mod->name); + klp_unpatch_object(obj); - klp_post_unpatch_callback(obj); - } + klp_post_unpatch_callback(obj); klp_free_object_loaded(obj); break; @@ -1194,13 +1187,6 @@ int klp_module_coming(struct module *mod) goto err; } - /* - * Only patch the module if the patch is enabled or is - * in transition. - */ - if (!patch->enabled && patch != klp_transition_patch) - break; - pr_notice("applying patch '%s' to loading module '%s'\n", patch->mod->name, obj->mod->name); -- cgit v1.2.3