diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-03-30 17:37:08 +0300 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-03-30 17:37:08 +0300 |
commit | 6e0aa8018f9c676b115b7ca6c20a056fc57c68a9 (patch) | |
tree | b35393574b48dcc05c99599add7f8b0015de3913 /kernel/livepatch/core.c | |
parent | 1ff27a3443addb19af609245b218fa510c7d37dd (diff) | |
parent | e42391cd048809d903291d07f86ed3934ce138e9 (diff) | |
download | linux-6e0aa8018f9c676b115b7ca6c20a056fc57c68a9.tar.xz |
Merge tag 'v4.0-rc6' into drm-intel-next
Backmerge Linux 4.0-rc6 because conflicts are (again) getting out of
hand. To make sure we don't lose any bugfixes from the 4.0-rc5-rc6
flurry of patches we've applied them all to -next too.
Conflicts:
drivers/gpu/drm/i915/intel_display.c
Always take the version from -next, we've already handled all
conflicts with explicit cherrypicking.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'kernel/livepatch/core.c')
-rw-r--r-- | kernel/livepatch/core.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 01ca08804f51..3f9f1d6b4c2e 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -89,16 +89,28 @@ static bool klp_is_object_loaded(struct klp_object *obj) /* sets obj->mod if object is not vmlinux and module is found */ static void klp_find_object_module(struct klp_object *obj) { + struct module *mod; + if (!klp_is_module(obj)) return; mutex_lock(&module_mutex); /* - * We don't need to take a reference on the module here because we have - * the klp_mutex, which is also taken by the module notifier. This - * prevents any module from unloading until we release the klp_mutex. + * We do not want to block removal of patched modules and therefore + * we do not take a reference here. The patches are removed by + * a going module handler instead. + */ + mod = find_module(obj->name); + /* + * Do not mess work of the module coming and going notifiers. + * Note that the patch might still be needed before the going handler + * is called. Module functions can be called even in the GOING state + * until mod->exit() finishes. This is especially important for + * patches that modify semantic of the functions. */ - obj->mod = find_module(obj->name); + if (mod && mod->klp_alive) + obj->mod = mod; + mutex_unlock(&module_mutex); } @@ -767,6 +779,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) return -EINVAL; obj->state = KLP_DISABLED; + obj->mod = NULL; klp_find_object_module(obj); @@ -961,6 +974,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action, mutex_lock(&klp_mutex); + /* + * Each module has to know that the notifier has been called. + * We never know what module will get patched by a new patch. + */ + if (action == MODULE_STATE_COMING) + mod->klp_alive = true; + else /* MODULE_STATE_GOING */ + mod->klp_alive = false; + list_for_each_entry(patch, &klp_patches, list) { for (obj = patch->objs; obj->funcs; obj++) { if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) |