• Mark Rutland's avatar
    ftrace: arm64: move from REGS to ARGS · 26299b3f
    Mark Rutland authored
    This commit replaces arm64's support for FTRACE_WITH_REGS with support
    for FTRACE_WITH_ARGS. This removes some overhead and complexity, and
    removes some latent issues with inconsistent presentation of struct
    pt_regs (which can only be reliably saved/restored at exception
    boundaries).
    
    FTRACE_WITH_REGS has been supported on arm64 since commit:
    
      3b23e499 ("arm64: implement ftrace with regs")
    
    As noted in the commit message, the major reasons for implementing
    FTRACE_WITH_REGS were:
    
    (1) To make it possible to use the ftrace graph tracer with pointer
        authentication, where it's necessary to snapshot/manipulate the LR
        before it is signed by the instrumented function.
    
    (2) To make it possible to implement LIVEPATCH in future, where we need
        to hook function entry before an instrumented function manipulates
        the stack or argument registers. Practically speaking, we need to
        preserve the argument/return registers, PC, LR, and SP.
    
    Neither of these need a struct pt_regs, and only require the set of
    registers which are live at function call/return boundaries. Our calling
    convention is defined by "Procedure Call Standard for the Arm® 64-bit
    Architecture (AArch64)" (AKA "AAPCS64"), which can currently be found
    at:
    
      https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
    
    Per AAPCS64, all function call argument and return values are held in
    the following GPRs:
    
    * X0 - X7 : parameter / result registers
    * X8      : indirect result location register
    * SP      : stack pointer (AKA SP)
    
    Additionally, ad function call boundaries, the following GPRs hold
    context/return information:
    
    * X29 : frame pointer (AKA FP)
    * X30 : link register (AKA LR)
    
    ... and for ftrace we need to capture the instrumented address:
    
     * PC  : program counter
    
    No other GPRs are relevant, as none of the other arguments hold
    parameters or return values:
    
    * X9  - X17 : temporaries, may be clobbered
    * X18       : shadow call stack pointer (or temorary)
    * X19 - X28 : callee saved
    
    This patch implements FTRACE_WITH_ARGS for arm64, only saving/restoring
    the minimal set of registers necessary. This is always sufficient to
    manipulate control flow (e.g. for live-patching) or to manipulate
    function arguments and return values.
    
    This reduces the necessary stack usage from 336 bytes for pt_regs down
    to 112 bytes for ftrace_regs + 32 bytes for two frame records, freeing
    up 188 bytes. This could be reduced further with changes to the
    unwinder.
    
    As there is no longer a need to save different sets of registers for
    different features, we no longer need distinct `ftrace_caller` and
    `ftrace_regs_caller` trampolines. This allows the trampoline assembly to
    be simpler, and simplifies code which previously had to handle the two
    trampolines.
    
    I've tested this with the ftrace selftests, where there are no
    unexpected failures.
    Co-developed-by: default avatarFlorent Revest <revest@chromium.org>
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Signed-off-by: default avatarFlorent Revest <revest@chromium.org>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Masami Hiramatsu <mhiramat@kernel.org>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Will Deacon <will@kernel.org>
    Reviewed-by: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
    Reviewed-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
    Link: https://lore.kernel.org/r/20221103170520.931305-5-mark.rutland@arm.comSigned-off-by: default avatarWill Deacon <will@kernel.org>
    26299b3f
ftrace.c 9 KB