[PATCH 00/13] arm64: extable: remove anonymous out-of-line fixups

Ard Biesheuvel ardb at kernel.org
Sun Oct 17 06:50:06 PDT 2021


On Wed, 13 Oct 2021 at 13:01, Mark Rutland <mark.rutland at arm.com> wrote:
>
> We recently realised that out-of-line extable fixups cause a number of problems
> for backtracing (mattering both for developers and for RELIABLE_STACKTRACE and
> LIVEPATCH). Dmitry spotted a confusing backtrace, which we identified was due
> to problems with unwinding fixups, as summarized in:
>
>   https://lore.kernel.org/linux-arm-kernel/20210927171812.GB9201@C02TD0UTHF1T.local/
>
> The gist is that while backtracing through a fixup, the fixup gets symmbolized
> as an offset from the nearest prior symbol (which happens to be
> `__entry_tramp_text_end`), and we the backtrace misses the function that was
> being fixed up (because the fixup handling adjusts the PC, then the fixup does
> a direct branch back to the original function). We can't reliably map from an
> arbitrary PC in the fixup text back to the original function.
>
> The way we create fixups is a bit unfortunate: most fixups are generated from
> common templates, and only differ in register to be poked and the address to
> branch back to, leading to redundant copies of the same logic that must pollute
> Since the fixups are all written in assembly, and duplicated for each fixup
> site, we can only perform very simple fixups, and can't handle any complex
> triage that we might need for some exceptions (e.g. MTE faults).
>
> This series address these concerns by getting rid of the out-of-line anonymous
> fixup logic:
>
> * For plain assembly functions, we move the fixup into the body of
>   the function, after the usual return, as we already do for our cache
>   routines. This simplifies the source code, and only adds a handful of
>   instructions to the main body of `.text`.
>
>   This is handled by the first three patches, which I think are trivial and
>   could be queued regardless of the rest of the series.
>
> * For inline assembly, we add specialised handlers which run in exception
>   context to update registers, then adjust the PC *within* the faulting
>   function. This requires some new glue to capture the handler and metadata in
>   struct exception_table_entry (costing 32 bits per fixup), but for any
>   non-trivial fixup (which is all of the inline asm cases), this removes at
>   least two instructions of out-of-line fixup.
>
> As the fixups are now handled from C code in exception context, we can more
> easily extend these in future with more complex triage if necessary.
>
> Overall, this doesn't have an appreciable impact on Image size (in local
> testing the size of the Image was identical before/after), but does shift the
> boundary between .text and .ordata, making .text smaller and .rodata bigger.
> .text somewhat while growing .rodata somewhat.
>
> I've tested this with both GCC and clang (including with clang CFI), and
> everything is working as expected.
>
> Other than changes to backtracing, there should be no functional change as a
> result of this series.
>
> Thanks
> Mark.
>
> Mark Rutland (13):
>   arm64: lib: __arch_clear_user(): fold fixups into body
>   arm64: lib: __arch_copy_from_user(): fold fixups into body
>   arm64: lib: __arch_copy_to_user(): fold fixups into body
>   arm64: kvm: use kvm_exception_table_entry
>   arm64: factor out GPR numbering helpers
>   arm64: gpr-num: support W registers
>   arm64: extable: consolidate definitions
>   arm64: extable: make fixup_exception() return bool
>   arm64: extable: use `ex` for `exception_table_entry`
>   arm64: extable: add `type` and `data` fields
>   arm64: extable: add a dedicated uaccess handler
>   arm64: extable: add load_unaligned_zeropad() handler
>   arm64: vmlinux.lds.S: remove `.fixup` section
>

This looks like a very worthwhile improvement to me, as it moves
complexity from the asm fault sites to the C handling code.

For the series,

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>

>  arch/arm64/include/asm/asm-extable.h    | 95 +++++++++++++++++++++++++++++++++
>  arch/arm64/include/asm/asm-uaccess.h    |  7 ++-
>  arch/arm64/include/asm/assembler.h      | 29 +---------
>  arch/arm64/include/asm/extable.h        | 23 +++++---
>  arch/arm64/include/asm/futex.h          | 25 +++------
>  arch/arm64/include/asm/gpr-num.h        | 26 +++++++++
>  arch/arm64/include/asm/kvm_asm.h        |  7 +--
>  arch/arm64/include/asm/sysreg.h         | 25 +++------
>  arch/arm64/include/asm/uaccess.h        | 26 ++-------
>  arch/arm64/include/asm/word-at-a-time.h | 21 ++------
>  arch/arm64/kernel/armv8_deprecated.c    | 12 ++---
>  arch/arm64/kernel/traps.c               |  9 +---
>  arch/arm64/kernel/vmlinux.lds.S         |  1 -
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 10 ++--
>  arch/arm64/lib/clear_user.S             |  9 ++--
>  arch/arm64/lib/copy_from_user.S         |  7 +--
>  arch/arm64/lib/copy_to_user.S           |  7 +--
>  arch/arm64/mm/extable.c                 | 85 +++++++++++++++++++++++++----
>  arch/arm64/net/bpf_jit_comp.c           |  9 ++--
>  scripts/sorttable.c                     | 30 +++++++++++
>  20 files changed, 306 insertions(+), 157 deletions(-)
>  create mode 100644 arch/arm64/include/asm/asm-extable.h
>  create mode 100644 arch/arm64/include/asm/gpr-num.h
>
> --
> 2.11.0
>



More information about the linux-arm-kernel mailing list