Patch "arm64: Force position-independent veneers" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    arm64: Force position-independent veneers

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm64-force-position-independent-veneers.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 0f20c34f49f8b173e24aa54aa68d84f7c540144d
Author: Mark Rutland <mark.rutland@xxxxxxx>
Date:   Fri Sep 27 11:18:38 2024 +0100

    arm64: Force position-independent veneers
    
    [ Upstream commit 9abe390e689f4f5c23c5f507754f8678431b4f72 ]
    
    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@xxxxxxxxxx/
    
    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@xxxxxxx>
    Reported-by: Marc Zyngier <maz@xxxxxxxxxx>
    Cc: Ard Biesheuvel <ardb@xxxxxxxxxx>
    Cc: Nathan Chancellor <nathan@xxxxxxxxxx>
    Cc: Nick Desaulniers <ndesaulniers@xxxxxxxxxx>
    Cc: Will Deacon <will@xxxxxxxxxx>
    Acked-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
    Reviewed-by: Nathan Chancellor <nathan@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20240927101838.3061054-1-mark.rutland@xxxxxxx
    Signed-off-by: Catalin Marinas <catalin.marinas@xxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 485b7dbd4f9e3..96dcddc358c78 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




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux