Live-Patching Archive on lore.kernel.org
 help / color / Atom feed
From: Petr Mladek <pmladek@suse.com>
To: Jiri Kosina <jikos@kernel.org>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Miroslav Benes <mbenes@suse.cz>
Cc: Joe Lawrence <joe.lawrence@redhat.com>,
	Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>,
	Nicolai Stange <nstange@suse.de>,
	live-patching@vger.kernel.org, linux-kernel@vger.kernel.org,
	Petr Mladek <pmladek@suse.com>
Subject: [POC 13/23] livepatch: Remove livepatch module when the livepatched module is unloaded
Date: Fri, 17 Jan 2020 16:03:13 +0100
Message-ID: <20200117150323.21801-14-pmladek@suse.com> (raw)
In-Reply-To: <20200117150323.21801-1-pmladek@suse.com>

klp_module_going() does very similar things as before splitting
the livepatches. Especially, it unpatches the related code, calls
the callbacks, unlinks the structures from the linked lists.

It does not have to clean up the structure because the entire livepatch
module is going to be freed and removed.

Signed-off-by: Petr Mladek <pmladek@suse.com>
---
 kernel/livepatch/core.c | 84 ++++++++++++++++++-------------------------------
 1 file changed, 31 insertions(+), 53 deletions(-)

diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 6c51b194da57..73462b66f63f 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -599,21 +599,6 @@ static void __klp_free_funcs(struct klp_object *obj, bool nops_only)
 	}
 }
 
-/* Clean up when a patched object is unloaded */
-static void klp_free_object_loaded(struct klp_object *obj)
-{
-	struct klp_func *func;
-
-	obj->mod = NULL;
-
-	klp_for_each_func(obj, func) {
-		func->old_func = NULL;
-
-		if (func->nop)
-			func->new_func = NULL;
-	}
-}
-
 static void klp_free_object(struct klp_object *obj, bool nops_only)
 {
 	__klp_free_funcs(obj, nops_only);
@@ -909,6 +894,24 @@ static int klp_init_patch(struct klp_patch *patch)
 	return 0;
 }
 
+static void klp_remove_object(struct klp_object *obj)
+{
+	struct klp_patch *patch =
+		container_of(obj->kobj.parent, struct klp_patch, kobj);
+
+	if (patch != klp_transition_patch)
+		klp_pre_unpatch_callback(obj);
+
+	pr_notice("reverting patch '%s' on unloading module '%s'\n",
+		  patch->obj->patch_name, obj->name);
+
+	klp_unpatch_object(obj);
+
+	klp_post_unpatch_callback(obj);
+
+	klp_free_object(obj, false);
+}
+
 static int klp_check_module_name(struct klp_object *obj, bool is_module)
 {
 	char mod_name[MODULE_NAME_LEN];
@@ -1313,40 +1316,6 @@ void klp_discard_nops(struct klp_patch *new_patch)
 	klp_free_objects_dynamic(klp_transition_patch);
 }
 
-/*
- * Remove parts of patches that touch a given kernel module. The list of
- * patches processed might be limited. When limit is NULL, all patches
- * will be handled.
- */
-static void klp_cleanup_module_patches_limited(struct module *mod,
-					       struct klp_patch *limit)
-{
-	struct klp_patch *patch;
-	struct klp_object *obj;
-
-	klp_for_each_patch(patch) {
-		if (patch == limit)
-			break;
-
-		klp_for_each_object(patch, obj) {
-			if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
-				continue;
-
-			if (patch != klp_transition_patch)
-				klp_pre_unpatch_callback(obj);
-
-			pr_notice("reverting patch '%s' on unloading module '%s'\n",
-				  patch->obj->patch_name, obj->name);
-			klp_unpatch_object(obj);
-
-			klp_post_unpatch_callback(obj);
-
-			klp_free_object_loaded(obj);
-			break;
-		}
-	}
-}
-
 int klp_module_coming(struct module *mod)
 {
 	char patch_name[MODULE_NAME_LEN];
@@ -1404,19 +1373,28 @@ int klp_module_coming(struct module *mod)
 
 void klp_module_going(struct module *mod)
 {
+	struct klp_patch *patch;
+	struct klp_object *obj, *tmp_obj;
+
 	if (WARN_ON(mod->state != MODULE_STATE_GOING &&
 		    mod->state != MODULE_STATE_COMING))
 		return;
 
 	mutex_lock(&klp_mutex);
 	/*
-	 * Each module has to know that klp_module_going()
-	 * has been called. We never know what module will
-	 * get patched by a new patch.
+	 * All already enabled livepatches for this module as going to be
+	 * removed now. From this point, klp_enable_patch() must not load
+	 * any new livepatch modules for this module.
 	 */
 	mod->klp_alive = false;
 
-	klp_cleanup_module_patches_limited(mod, NULL);
+	klp_for_each_patch(patch) {
+		klp_for_each_object_safe(patch, obj, tmp_obj) {
+			if (obj->name && !strcmp(obj->name, mod->name)) {
+				klp_remove_object(obj);
+			}
+		}
+	}
 
 	mutex_unlock(&klp_mutex);
 }
-- 
2.16.4


  parent reply index

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-17 15:03 [POC 00/23] livepatch: Split livepatch module per-object Petr Mladek
2020-01-17 15:03 ` [POC 01/23] module: Allow to delete module also from inside kernel Petr Mladek
2020-01-21 11:11   ` Julien Thierry
2020-01-17 15:03 ` [POC 02/23] livepatch: Split livepatch modules per livepatched object Petr Mladek
2020-01-21 11:11   ` Julien Thierry
2020-01-28 12:16     ` Petr Mladek
2020-01-17 15:03 ` [POC 03/23] livepatch: Better checks of struct klp_object definition Petr Mladek
2020-01-21 11:27   ` Julien Thierry
2020-01-17 15:03 ` [POC 04/23] livepatch: Prevent loading livepatch sub-module unintentionally Petr Mladek
2020-04-03 17:54   ` Joe Lawrence
2020-01-17 15:03 ` [POC 05/23] livepatch: Initialize and free livepatch submodule Petr Mladek
2020-01-21 11:58   ` Julien Thierry
2020-01-17 15:03 ` [POC 06/23] livepatch: Enable the " Petr Mladek
2020-01-17 15:03 ` [POC 07/23] livepatch: Remove obsolete functionality from klp_module_coming() Petr Mladek
2020-01-17 15:03 ` [POC 08/23] livepatch: Automatically load livepatch module when the patch module is loaded Petr Mladek
2020-01-17 15:03 ` [POC 09/23] livepatch: Handle race when livepatches are reloaded during a module load Petr Mladek
2020-01-22 18:51   ` Julien Thierry
2020-01-17 15:03 ` [POC 10/23] livepatch: Handle modprobe exit code Petr Mladek
2020-01-17 15:03 ` [POC 11/23] livepatch: Safely detect forced transition when removing split livepatch modules Petr Mladek
2020-01-22 10:15   ` Julien Thierry
2020-01-17 15:03 ` [POC 12/23] livepatch: Automatically remove livepatch module when the object is freed Petr Mladek
2020-01-17 15:03 ` Petr Mladek [this message]
2020-01-17 15:03 ` [POC 14/23] livepatch: Never block livepatch modules when the related module is being removed Petr Mladek
2020-01-17 15:03 ` [POC 15/23] livepatch: Prevent infinite loop when loading livepatch module Petr Mladek
2020-01-17 15:03 ` [POC 16/23] livepatch: Add patch into the global list early Petr Mladek
2020-01-17 15:03 ` [POC 17/23] livepatch: Load livepatches for modules when loading the main livepatch Petr Mladek
2020-01-17 15:03 ` [POC 18/23] module: Refactor add_unformed_module() Petr Mladek
2020-01-17 15:03 ` [POC 19/23] module/livepatch: Allow to use exported symbols from livepatch module for "vmlinux" Petr Mladek
2020-04-06 18:48   ` Joe Lawrence
2020-04-07  7:33     ` Miroslav Benes
2020-04-07 20:57       ` Joe Lawrence
2020-01-17 15:03 ` [POC 20/23] module/livepatch: Relocate local variables in the module loaded when the livepatch is being loaded Petr Mladek
2020-01-18 10:29   ` kbuild test robot
2020-04-03 18:00   ` Joe Lawrence
2020-01-17 15:03 ` [POC 21/23] livepatch: Remove obsolete arch_klp_init_object_loaded() Petr Mladek
2020-01-17 15:03 ` [POC 22/23] livepatch/module: Remove obsolete copy_module_elf() Petr Mladek
2020-04-03 18:03   ` Joe Lawrence
2020-01-17 15:03 ` [POC 23/23] module: Remove obsolete module_disable_ro() Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200117150323.21801-14-pmladek@suse.com \
    --to=pmladek@suse.com \
    --cc=jikos@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@redhat.com \
    --cc=kamalesh@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=nstange@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Live-Patching Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/live-patching/0 live-patching/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 live-patching live-patching/ https://lore.kernel.org/live-patching \
		live-patching@vger.kernel.org
	public-inbox-index live-patching

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.live-patching


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git