[PATCH v2] arm64: implement support for static call trampolines

Ard Biesheuvel ardb at kernel.org
Thu Oct 29 07:32:50 EDT 2020


On Thu, 29 Oct 2020 at 12:27, Quentin Perret <qperret at google.com> wrote:
>
> Hi Ard,
>
> On Wednesday 28 Oct 2020 at 19:41:14 (+0100), Ard Biesheuvel wrote:
> > diff --git a/arch/arm64/include/asm/static_call.h b/arch/arm64/include/asm/static_call.h
> > new file mode 100644
> > index 000000000000..7ddf939d57f5
> > --- /dev/null
> > +++ b/arch/arm64/include/asm/static_call.h
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_STATIC_CALL_H
> > +#define _ASM_STATIC_CALL_H
> > +
> > +/*
> > + * We have to account for the possibility that the static call site may
> > + * be updated to refer to a target that is out of range for an ordinary
> > + * 'B' branch instruction, and so we need to pre-allocate some space for
> > + * a ADRP/ADD/BR sequence.
> > + */
> > +#define __ARCH_DEFINE_STATIC_CALL_TRAMP(name, insn)                      \
> > +     asm(".pushsection       .static_call.text, \"ax\"               \n" \
> > +         ".align             5                                       \n" \
> > +         ".globl             " STATIC_CALL_TRAMP_STR(name) "         \n" \
> > +         STATIC_CALL_TRAMP_STR(name) ":                              \n" \
> > +         "hint       34      /* BTI C */                             \n" \
> > +         insn "                                                      \n" \
> > +         "ret                                                        \n" \
> > +         "nop                                                        \n" \
> > +         "nop                                                        \n" \
> > +         "adrp       x16, " STATIC_CALL_KEY(name) "                  \n" \
> > +         "ldr        x16, [x16, :lo12:" STATIC_CALL_KEY(name) "]     \n" \
> > +         "br         x16                                             \n" \
> > +         ".popsection                                                \n")
>
> Still trying to understand all this in details, so bear with me, but is
> there any way this could be turned into the 'inline' static call
> variant?
>
> That is, could we have a piece of inline assembly at all static_call
> locations that would do a branch-link, with basically x0-x18 and
> x29,x30 in the clobber list (+ some have some magic to place the
> parameters in the right register, like we do for SMCCC calls for
> instance). That'd save a branch to the trampoline.
>
> Ideally we'd need a way to tell the compile 'this inline assembly code
> does a function call', but I'm not aware of any easy way to do that
> (other that marking register clobbered + probably other things that I'm
> missing).
>
> In any case, I was looking forward to an arm64 static call port so
> thanks for putting that together.
>

Hello Quentin,

We'll need tooling along the lines of the GCC plugin I wrote [0] to
implement inline static calls - doing function calls from inline
assembly is too messy, too fragile and too error prone to rely on.

However, as I discussed with Will offline yesterday as well, the
question that got snowed under is whether we need any of this on arm64
in the first place. It seems highly unlikely that inline static calls
are worth it, and even out-of-line static calls are probably not worth
the hassle as we don't have the retpoline problem.

So this code should be considered an invitation for discussion, and
perhaps someone can invent a use case where benchmarks can show a
worthwhile improvement. But let's not get ahead of ourselves.


[0] https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=static-calls



More information about the linux-arm-kernel mailing list