• Mark Rutland's avatar
    arm64: alternatives: add alternative_has_feature_*() · 21fb26bf
    Mark Rutland authored
    Currrently we use a mixture of alternative sequences and static branches
    to handle features detected at boot time. For ease of maintenance we
    generally prefer to use static branches in C code, but this has a few
    downsides:
    
    * Each static branch has metadata in the __jump_table section, which is
      not discarded after features are finalized. This wastes some space,
      and slows down the patching of other static branches.
    
    * The static branches are patched at a different point in time from the
      alternatives, so changes are not atomic. This leaves a transient
      period where there could be a mismatch between the behaviour of
      alternatives and static branches, which could be problematic for some
      features (e.g. pseudo-NMI).
    
    * More (instrumentable) kernel code is executed to patch each static
      branch, which can be risky when patching certain features (e.g.
      irqflags management for pseudo-NMI).
    
    * When CONFIG_JUMP_LABEL=n, static branches are turned into a load of a
      flag and a conditional branch. This means it isn't safe to use such
      static branches in an alternative address space (e.g. the NVHE/PKVM
      hyp code), where the generated address isn't safe to acccess.
    
    To deal with these issues, this patch introduces new
    alternative_has_feature_*() helpers, which work like static branches but
    are patched using alternatives. This ensures the patching is performed
    at the same time as other alternative patching, allows the metadata to
    be freed after patching, and is safe for use in alternative address
    spaces.
    
    Note that all supported toolchains have asm goto support, and since
    commit:
    
      a0a12c3e ("asm goto: eradicate CC_HAS_ASM_GOTO)"
    
    ... the CC_HAS_ASM_GOTO Kconfig symbol has been removed, so no feature
    check is necessary, and we can always make use of asm goto.
    
    Additionally, note that:
    
    * This has no impact on cpus_have_cap(), which is a dynamic check.
    
    * This has no functional impact on cpus_have_const_cap(). The branches
      are patched slightly later than before this patch, but these branches
      are not reachable until caps have been finalised.
    
    * It is now invalid to use cpus_have_final_cap() in the window between
      feature detection and patching. All existing uses are only expected
      after patching anyway, so this should not be a problem.
    
    * The LSE atomics will now be enabled during alternatives patching
      rather than immediately before. As the LL/SC an LSE atomics are
      functionally equivalent this should not be problematic.
    
    When building defconfig with GCC 12.1.0, the resulting Image is 64KiB
    smaller:
    
    | % ls -al Image-*
    | -rw-r--r-- 1 mark mark 37108224 Aug 23 09:56 Image-after
    | -rw-r--r-- 1 mark mark 37173760 Aug 23 09:54 Image-before
    
    According to bloat-o-meter.pl:
    
    | add/remove: 44/34 grow/shrink: 602/1294 up/down: 39692/-61108 (-21416)
    | Function                                     old     new   delta
    | [...]
    | Total: Before=16618336, After=16596920, chg -0.13%
    | add/remove: 0/2 grow/shrink: 0/0 up/down: 0/-1296 (-1296)
    | Data                                         old     new   delta
    | arm64_const_caps_ready                        16       -     -16
    | cpu_hwcap_keys                              1280       -   -1280
    | Total: Before=8987120, After=8985824, chg -0.01%
    | add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
    | RO Data                                      old     new   delta
    | Total: Before=18408, After=18408, chg +0.00%
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Cc: Ard Biesheuvel <ardb@kernel.org>
    Cc: James Morse <james.morse@arm.com>
    Cc: Joey Gouly <joey.gouly@arm.com>
    Cc: Marc Zyngier <maz@kernel.org>
    Cc: Will Deacon <will@kernel.org>
    Reviewed-by: default avatarArd Biesheuvel <ardb@kernel.org>
    Link: https://lore.kernel.org/r/20220912162210.3626215-8-mark.rutland@arm.comSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    21fb26bf
cpufeature.c 116 KB