[RFC PATCH 8/9] livepatch: allow patch modules to be removed

Josh Poimboeuf
2015-02-09T17:31:59Z

Now that we have a consistency model we can detect when unpatching is
complete and the patch module can be safely removed.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
kernel/livepatch/core.c | 25 ++++---------------------
kernel/livepatch/transition.c | 3 +++
2 files changed, 7 insertions(+), 21 deletions(-)

diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 790dc10..e572523 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -352,6 +352,9 @@ static int __klp_enable_patch(struct klp_patch *patch)
!list_prev_entry(patch, list)->enabled)
return -EBUSY;

+ if (!try_module_get(patch->mod))
+ return -ENODEV;
+
pr_notice_once("tainting kernel with TAINT_LIVEPATCH\n");
add_taint(TAINT_LIVEPATCH, LOCKDEP_STILL_OK);

@@ -497,10 +500,6 @@ static struct attribute *klp_patch_attrs[] = {

static void klp_kobj_release_patch(struct kobject *kobj)
{
- /*
- * Once we have a consistency model we'll need to module_put() the
- * patch module here. See klp_register_patch() for more details.
- */
}

static struct kobj_type klp_ktype_patch = {
@@ -715,29 +714,13 @@ EXPORT_SYMBOL_GPL(klp_unregister_patch);
*/
int klp_register_patch(struct klp_patch *patch)
{
- int ret;
-
if (!klp_initialized())
return -ENODEV;

if (!patch || !patch->mod)
return -EINVAL;

- /*
- * A reference is taken on the patch module to prevent it from being
- * unloaded. Right now, we don't allow patch modules to unload since
- * there is currently no method to determine if a thread is still
- * running in the patched code contained in the patch module once
- * the ftrace registration is successful.
- */
- if (!try_module_get(patch->mod))
- return -ENODEV;
-
- ret = klp_init_patch(patch);
- if (ret)
- module_put(patch->mod);
-
- return ret;
+ return klp_init_patch(patch);
}
EXPORT_SYMBOL_GPL(klp_register_patch);

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 2630296..20fafd2 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -54,6 +54,9 @@ void klp_complete_transition(void)
for (func = obj->funcs; func->old_name; func++)
func->transition = 0;

+ if (klp_universe_goal == KLP_UNIVERSE_OLD)
+ module_put(klp_transition_patch->mod);
+
klp_transition_patch = NULL;
}

--
2.1.0