* [PATCH] arm64: Force position-independent veneers
@ 2024-09-27 10:18 Mark Rutland
2024-09-27 10:42 ` Ard Biesheuvel
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Mark Rutland @ 2024-09-27 10:18 UTC (permalink / raw)
To: linux-arm-kernel
Cc: ardb, catalin.marinas, mark.rutland, maz, nathan, ndesaulniers,
will
Certain portions of code always need to be position-independent
regardless of CONFIG_RELOCATABLE, including code which is executed in an
idmap or which is executed before relocations are applied. In some
kernel configurations the LLD linker generates position-dependent
veneers for such code, and when executed these result in early boot-time
failures.
Marc Zyngier encountered a boot failure resulting from this when
building a (particularly cursed) configuration with LLVM, as he reported
to the list:
https://lore.kernel.org/linux-arm-kernel/86wmjwvatn.wl-maz@kernel.org/
In Marc's kernel configuration, the .head.text and .rodata.text sections
end up more than 128MiB apart, requiring a veneer to branch between the
two:
| [mark@lakrids:~/src/linux]% usekorg 14.1.0 aarch64-linux-objdump -t vmlinux | grep -w _text
| ffff800080000000 g .head.text 0000000000000000 _text
| [mark@lakrids:~/src/linux]% usekorg 14.1.0 aarch64-linux-objdump -t vmlinux | grep -w primary_entry
| ffff8000889df0e0 g .rodata.text 000000000000006c primary_entry,
... consequently, LLD inserts a position-dependent veneer for the branch
from _stext (in .head.text) to primary_entry (in .rodata.text):
| ffff800080000000 <_text>:
| ffff800080000000: fa405a4d ccmp x18, #0x0, #0xd, pl // pl = nfrst
| ffff800080000004: 14003fff b ffff800080010000 <__AArch64AbsLongThunk_primary_entry>
...
| ffff800080010000 <__AArch64AbsLongThunk_primary_entry>:
| ffff800080010000: 58000050 ldr x16, ffff800080010008 <__AArch64AbsLongThunk_primary_entry+0x8>
| ffff800080010004: d61f0200 br x16
| ffff800080010008: 889df0e0 .word 0x889df0e0
| ffff80008001000c: ffff8000 .word 0xffff8000
... and as this is executed early in boot before the kernel is mapped in
TTBR1 this results in a silent boot failure.
Fix this by passing '--pic-veneer' to the linker, which will cause the
linker to use position-independent veneers, e.g.
| ffff800080000000 <_text>:
| ffff800080000000: fa405a4d ccmp x18, #0x0, #0xd, pl // pl = nfrst
| ffff800080000004: 14003fff b ffff800080010000 <__AArch64ADRPThunk_primary_entry>
...
| ffff800080010000 <__AArch64ADRPThunk_primary_entry>:
| ffff800080010000: f004e3f0 adrp x16, ffff800089c8f000 <__idmap_text_start>
| ffff800080010004: 91038210 add x16, x16, #0xe0
| ffff800080010008: d61f0200 br x16
I've opted to pass '--pic-veneer' unconditionally, as:
* In addition to solving the boot failure, these sequences are generally
nicer as they require fewer instructions and don't need to perform
data accesses.
* While the position-independent veneer sequences have a limited +/-2GiB
range, this is not a new restriction. Even kernels built with
CONFIG_RELOCATABLE=n are limited to 2GiB in size as we have several
structues using 32-bit relative offsets and PPREL32 relocations, which
are similarly limited to +/-2GiB in range. These include extable
entries, jump table entries, and alt_instr entries.
* GNU LD defaults to using position-independent veneers, and supports
the same '--pic-veneer' option, so this change is not expected to
adversely affect GNU LD.
I've tested with GNU LD 2.30 to 2.42 inclusive and LLVM 13.0.1 to 19.1.0
inclusive, using the kernel.org binaries from:
* https://mirrors.edge.kernel.org/pub/tools/crosstool/
* https://mirrors.edge.kernel.org/pub/tools/llvm/
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reported-by: Marc Zyngier <maz@kernel.org>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index f6bc3da1ef110..c8e237b20ef29 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -10,7 +10,7 @@
#
# Copyright (C) 1995-2001 by Russell King
-LDFLAGS_vmlinux :=--no-undefined -X
+LDFLAGS_vmlinux :=--no-undefined -X --pic-veneer
ifeq ($(CONFIG_RELOCATABLE), y)
# Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour
--
2.30.2
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] arm64: Force position-independent veneers
2024-09-27 10:18 [PATCH] arm64: Force position-independent veneers Mark Rutland
@ 2024-09-27 10:42 ` Ard Biesheuvel
2024-09-27 13:49 ` Nathan Chancellor
2024-10-01 13:03 ` Catalin Marinas
2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2024-09-27 10:42 UTC (permalink / raw)
To: Mark Rutland
Cc: linux-arm-kernel, catalin.marinas, maz, nathan, ndesaulniers,
will
On Fri, 27 Sept 2024 at 12:18, Mark Rutland <mark.rutland@arm.com> wrote:
>
> Certain portions of code always need to be position-independent
> regardless of CONFIG_RELOCATABLE, including code which is executed in an
> idmap or which is executed before relocations are applied. In some
> kernel configurations the LLD linker generates position-dependent
> veneers for such code, and when executed these result in early boot-time
> failures.
>
...
>
> I've opted to pass '--pic-veneer' unconditionally, as:
>
> * In addition to solving the boot failure, these sequences are generally
> nicer as they require fewer instructions and don't need to perform
> data accesses.
>
Yeah, and accessing literal pools interspersed with the code. I find
it rather bizarre that --pic-veneer is not the default when using the
small code model.
...
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reported-by: Marc Zyngier <maz@kernel.org>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Cc: Nick Desaulniers <ndesaulniers@google.com>
> Cc: Will Deacon <will@kernel.org>
> ---
> arch/arm64/Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] arm64: Force position-independent veneers
2024-09-27 10:18 [PATCH] arm64: Force position-independent veneers Mark Rutland
2024-09-27 10:42 ` Ard Biesheuvel
@ 2024-09-27 13:49 ` Nathan Chancellor
2024-10-01 13:03 ` Catalin Marinas
2 siblings, 0 replies; 4+ messages in thread
From: Nathan Chancellor @ 2024-09-27 13:49 UTC (permalink / raw)
To: Mark Rutland
Cc: linux-arm-kernel, ardb, catalin.marinas, maz, ndesaulniers, will
On Fri, Sep 27, 2024 at 11:18:38AM +0100, Mark Rutland wrote:
> Certain portions of code always need to be position-independent
> regardless of CONFIG_RELOCATABLE, including code which is executed in an
> idmap or which is executed before relocations are applied. In some
> kernel configurations the LLD linker generates position-dependent
> veneers for such code, and when executed these result in early boot-time
> failures.
>
> Marc Zyngier encountered a boot failure resulting from this when
> building a (particularly cursed) configuration with LLVM, as he reported
> to the list:
Heh, I admire the "particularly cursed" bit.
> I've tested with GNU LD 2.30 to 2.42 inclusive and LLVM 13.0.1 to 19.1.0
> inclusive, using the kernel.org binaries from:
>
> * https://mirrors.edge.kernel.org/pub/tools/crosstool/
> * https://mirrors.edge.kernel.org/pub/tools/llvm/
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Reported-by: Marc Zyngier <maz@kernel.org>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Cc: Nick Desaulniers <ndesaulniers@google.com>
> Cc: Will Deacon <will@kernel.org>
Thanks for the patch!
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
> ---
> arch/arm64/Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index f6bc3da1ef110..c8e237b20ef29 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -10,7 +10,7 @@
> #
> # Copyright (C) 1995-2001 by Russell King
>
> -LDFLAGS_vmlinux :=--no-undefined -X
> +LDFLAGS_vmlinux :=--no-undefined -X --pic-veneer
>
> ifeq ($(CONFIG_RELOCATABLE), y)
> # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] arm64: Force position-independent veneers
2024-09-27 10:18 [PATCH] arm64: Force position-independent veneers Mark Rutland
2024-09-27 10:42 ` Ard Biesheuvel
2024-09-27 13:49 ` Nathan Chancellor
@ 2024-10-01 13:03 ` Catalin Marinas
2 siblings, 0 replies; 4+ messages in thread
From: Catalin Marinas @ 2024-10-01 13:03 UTC (permalink / raw)
To: linux-arm-kernel, Mark Rutland
Cc: Will Deacon, ardb, maz, nathan, ndesaulniers
On Fri, 27 Sep 2024 11:18:38 +0100, Mark Rutland wrote:
> Certain portions of code always need to be position-independent
> regardless of CONFIG_RELOCATABLE, including code which is executed in an
> idmap or which is executed before relocations are applied. In some
> kernel configurations the LLD linker generates position-dependent
> veneers for such code, and when executed these result in early boot-time
> failures.
>
> [...]
Applied to arm64 (for-next/fixes), thanks!
[1/1] arm64: Force position-independent veneers
https://git.kernel.org/arm64/c/9abe390e689f
--
Catalin
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-10-01 13:06 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-27 10:18 [PATCH] arm64: Force position-independent veneers Mark Rutland
2024-09-27 10:42 ` Ard Biesheuvel
2024-09-27 13:49 ` Nathan Chancellor
2024-10-01 13:03 ` Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox