Re: [PATCH 1/2] arm64: module: Emit BTI veneers for cross-section calls

Josh Poimboeuf <[email protected]>
Newsgroups org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <anzo2Q-TxbB0PUhi@jpoimboe>
On Wed, Aug 12, 2026 at 06:21:00PM +0200, Ard Biesheuvel wrote:
> The compiler is permitted to omit BTI landing pads from static functions
> that never have their address taken, but are only called directly, even
> if those calls originate from other code sections.
> 
> This means that calls into a module's .text section from .init.text,
> which may need to be routed via a PLT if .text is out of direct
> branching range, may result in BTI exceptions due to the indirect calls
> performed by the PLT veneers. (Note that calls to .init.text from .text
> are not allowed.)
> 
> The 'solution' is to emit yet another veneer - this is what the ELF
> psABI for AArch64 mandates in this case.
> 
> So derive an upper bound for the number of veneers that may be needed in
> the core module region to ensure that any call from init code that ends
> up needing a PLT can be directed at a veneer with a BTI landing pad, and
> allocate the additional space.
> 
> Then, emit these veneers as needed, i.e., only when emitting a PLT entry
> for a call from an init code section to a normal code section in the
> same module. In practice, this only occurs when a module's .init.text
> happens to be allocated far away from its .text section, which might
> happen when the initial 128M 'near' module region runs out of space
> between allocating the core module and allocating its init region.
> 
> Signed-off-by: Ard Biesheuvel <[email protected]>
> ---
>  arch/arm64/Kconfig                  |   2 -
>  arch/arm64/include/asm/module.h     |  12 ++
>  arch/arm64/include/asm/module.lds.h |   3 +
>  arch/arm64/kernel/module-plts.c     | 128 +++++++++++++++++++-
>  4 files changed, 138 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b3afe0688919..25fa80b5591d 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -2114,8 +2114,6 @@ config ARM64_BTI_KERNEL
>  	depends on CC_HAS_BRANCH_PROT_PAC_RET_BTI
>  	# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94697
>  	depends on !CC_IS_GCC || GCC_VERSION >= 100100
> -	# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106671
> -	depends on !CC_IS_GCC

This doesn't work for livepatch though, and removing the "depends on
!CC_IS_GCC" is a livepatch regression as it broadly increases the
likelihood of ARM64_BTI_KERNEL (default y) getting enabled.

So "livepatch broken on arm64 clang 21+" now becomes "livepatch broken on arm64".

So either ARM64_BTI_KERNEL needs to depend on !LIVEPATCH (which will
keep BTI disabled for most distros), or we need a different approach
which uses __vmalloc_node_range() to allocate a veneer within 128MB of
the target.  I can try to write that up.

-- 
Josh
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.