Skip to content
  • Petr Mladek's avatar
    livepatch: Simplify API by removing registration step · 958ef1e3
    Petr Mladek authored
    
    
    The possibility to re-enable a registered patch was useful for immediate
    patches where the livepatch module had to stay until the system reboot.
    The improved consistency model allows to achieve the same result by
    unloading and loading the livepatch module again.
    
    Also we are going to add a feature called atomic replace. It will allow
    to create a patch that would replace all already registered patches.
    The aim is to handle dependent patches more securely. It will obsolete
    the stack of patches that helped to handle the dependencies so far.
    Then it might be unclear when a cumulative patch re-enabling is safe.
    
    It would be complicated to support the many modes. Instead we could
    actually make the API and code easier to understand.
    
    Therefore, remove the two step public API. All the checks and init calls
    are moved from klp_register_patch() to klp_enabled_patch(). Also the patch
    is automatically freed, including the sysfs interface when the transition
    to the disabled state is completed.
    
    As a result, there is never a disabled patch on the top of the stack.
    Therefore we do not need to check the stack in __klp_enable_patch().
    And we could simplify the check in __klp_disable_patch().
    
    Also the API and logic is much easier. It is enough to call
    klp_enable_patch() in module_init() call. The patch can be disabled
    by writing '0' into /sys/kernel/livepatch/<patch>/enabled. Then the module
    can be removed once the transition finishes and sysfs interface is freed.
    
    The only problem is how to free the structures and kobjects safely.
    The operation is triggered from the sysfs interface. We could not put
    the related kobject from there because it would cause lock inversion
    between klp_mutex and kernfs locks, see kn->count lockdep map.
    
    Therefore, offload the free task to a workqueue. It is perfectly fine:
    
      + The patch can no longer be used in the livepatch operations.
    
      + The module could not be removed until the free operation finishes
        and module_put() is called.
    
      + The operation is asynchronous already when the first
        klp_try_complete_transition() fails and another call
        is queued with a delay.
    
    Suggested-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
    Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
    Acked-by: default avatarMiroslav Benes <mbenes@suse.cz>
    Acked-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    958ef1e3