• Josh Poimboeuf's avatar
    livepatch: Apply vmlinux-specific KLP relocations early · 7c8e2bdd
    Josh Poimboeuf authored
    KLP relocations are livepatch-specific relocations which are applied to
    a KLP module's text or data.  They exist for two reasons:
    
      1) Unexported symbols: replacement functions often need to access
         unexported symbols (e.g. static functions), which "normal"
         relocations don't allow.
    
      2) Late module patching: this is the ability for a KLP module to
         bypass normal module dependencies, such that the KLP module can be
         loaded *before* a to-be-patched module.  This means that
         relocations which need to access symbols in the to-be-patched
         module might need to be applied to the KLP module well after it has
         been loaded.
    
    Non-late-patched KLP relocations are applied from the KLP module's init
    function.  That usually works fine, unless the patched code wants to use
    alternatives, paravirt patching, jump tables, or some other special
    section which needs relocations.  Then we run into ordering issues and
    crashes.
    
    In order for those special sections to work properly, the KLP
    relocations should be applied *before* the special section init code
    runs, such as apply_paravirt(), apply_alternatives(), or
    jump_label_apply_nops().
    
    You might think the obvious solution would be to move the KLP relocation
    initialization earlier, but it's not necessarily that simple.  The
    problem is the above-mentioned late module patching, for which KLP
    relocations can get applied well after the KLP module is loaded.
    
    To "fix" this issue in the past, we created .klp.arch sections:
    
      .klp.arch.{module}..altinstructions
      .klp.arch.{module}..parainstructions
    
    Those sections allow KLP late module patching code to call
    apply_paravirt() and apply_alternatives() after the module-specific KLP
    relocations (.klp.rela.{module}.{section}) have been applied.
    
    But that has a lot of drawbacks, including code complexity, the need for
    arch-specific code, and the (per-arch) danger that we missed some
    special section -- for example the __jump_table section which is used
    for jump labels.
    
    It turns out there's a simpler and more functional approach.  There are
    two kinds of KLP relocation sections:
    
      1) vmlinux-specific KLP relocation sections
    
         .klp.rela.vmlinux.{sec}
    
         These are relocations (applied to the KLP module) which reference
         unexported vmlinux symbols.
    
      2) module-specific KLP relocation sections
    
         .klp.rela.{module}.{sec}:
    
         These are relocations (applied to the KLP module) which reference
         unexported or exported module symbols.
    
    Up until now, these have been treated the same.  However, they're
    inherently different.
    
    Because of late module patching, module-specific KLP relocations can be
    applied very late, thus they can create the ordering headaches described
    above.
    
    But vmlinux-specific KLP relocations don't have that problem.  There's
    nothing to prevent them from being applied earlier.  So apply them at
    the same time as normal relocations, when the KLP module is being
    loaded.
    
    This means that for vmlinux-specific KLP relocations, we no longer have
    any ordering issues.  vmlinux-referencing jump labels, alternatives, and
    paravirt patching will work automatically, without the need for the
    .klp.arch hacks.
    
    All that said, for module-specific KLP relocations, the ordering
    problems still exist and we *do* still need .klp.arch.  Or do we?  Stay
    tuned.
    Suggested-by: default avatarPeter Zijlstra <peterz@infradead.org>
    Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
    Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Acked-by: default avatarJoe Lawrence <joe.lawrence@redhat.com>
    Acked-by: default avatarMiroslav Benes <mbenes@suse.cz>
    Acked-by: default avatarJessica Yu <jeyu@kernel.org>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    7c8e2bdd
module.c 115 KB