• Josh Poimboeuf's avatar
    livepatch: allow removal of a disabled patch · 3ec24776
    Josh Poimboeuf authored
    Currently we do not allow patch module to unload since there is no
    method to determine if a task is still running in the patched code.
    
    The consistency model gives us the way because when the unpatching
    finishes we know that all tasks were marked as safe to call an original
    function. Thus every new call to the function calls the original code
    and at the same time no task can be somewhere in the patched code,
    because it had to leave that code to be marked as safe.
    
    We can safely let the patch module go after that.
    
    Completion is used for synchronization between module removal and sysfs
    infrastructure in a similar way to commit 942e4431 ("module: Fix
    mod->mkobj.kobj potentially freed too early").
    
    Note that we still do not allow the removal for immediate model, that is
    no consistency model. The module refcount may increase in this case if
    somebody disables and enables the patch several times. This should not
    cause any harm.
    
    With this change a call to try_module_get() is moved to
    __klp_enable_patch from klp_register_patch to make module reference
    counting symmetric (module_put() is in a patch disable path) and to
    allow to take a new reference to a disabled module when being enabled.
    
    Finally, we need to be very careful about possible races between
    klp_unregister_patch(), kobject_put() functions and operations
    on the related sysfs files.
    
    kobject_put(&patch->kobj) must be called without klp_mutex. Otherwise,
    it might be blocked by enabled_store() that needs the mutex as well.
    In addition, enabled_store() must check if the patch was not
    unregisted in the meantime.
    
    There is no need to do the same for other kobject_put() callsites
    at the moment. Their sysfs operations neither take the lock nor
    they access any data that might be freed in the meantime.
    
    There was an attempt to use kobjects the right way and prevent these
    races by design. But it made the patch definition more complicated
    and opened another can of worms. See
    https://lkml.kernel.org/r/1464018848-4303-1-git-send-email-pmladek@suse.com
    
    [Thanks to Petr Mladek for improving the commit message.]
    Signed-off-by: default avatarMiroslav Benes <mbenes@suse.cz>
    Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
    Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
    Acked-by: default avatarMiroslav Benes <mbenes@suse.cz>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    3ec24776
livepatch.h 5.62 KB