arm64: head: use relative references to the RELA and RELR tables
authorArd Biesheuvel <ardb@kernel.org>
Fri, 24 Jun 2022 15:06:43 +0000 (17:06 +0200)
committerWill Deacon <will@kernel.org>
Fri, 24 Jun 2022 16:18:10 +0000 (17:18 +0100)
Formerly, we had to access the RELA and RELR tables via the kernel
mapping that was being relocated, and so deriving the start and end
addresses using ADRP/ADD references was not possible, as the relocation
code runs from the ID map.

Now that we map the entire kernel image via the ID map, we can simplify
this, and just load the entries via the ID map as well.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20220624150651.1358849-14-ardb@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/head.S
arch/arm64/kernel/vmlinux.lds.S

index 93734c9..f1497f7 100644 (file)
@@ -757,13 +757,10 @@ SYM_FUNC_START_LOCAL(__relocate_kernel)
         * Iterate over each entry in the relocation table, and apply the
         * relocations in place.
         */
-       ldr     w9, =__rela_offset              // offset to reloc table
-       ldr     w10, =__rela_size               // size of reloc table
-
+       adr_l   x9, __rela_start
+       adr_l   x10, __rela_end
        mov_q   x11, KIMAGE_VADDR               // default virtual offset
        add     x11, x11, x23                   // actual virtual offset
-       add     x9, x9, x11                     // __va(.rela)
-       add     x10, x9, x10                    // __va(.rela) + sizeof(.rela)
 
 0:     cmp     x9, x10
        b.hs    1f
@@ -813,10 +810,8 @@ SYM_FUNC_START_LOCAL(__relocate_kernel)
         * __relocate_kernel is called twice with non-zero displacements (i.e.
         * if there is both a physical misalignment and a KASLR displacement).
         */
-       ldr     w9, =__relr_offset              // offset to reloc table
-       ldr     w10, =__relr_size               // size of reloc table
-       add     x9, x9, x11                     // __va(.relr)
-       add     x10, x9, x10                    // __va(.relr) + sizeof(.relr)
+       adr_l   x9, __relr_start
+       adr_l   x10, __relr_end
 
        sub     x15, x23, x24                   // delta from previous offset
        cbz     x15, 7f                         // nothing to do if unchanged
index 5336737..20ebdd4 100644 (file)
@@ -256,21 +256,17 @@ SECTIONS
        HYPERVISOR_RELOC_SECTION
 
        .rela.dyn : ALIGN(8) {
+               __rela_start = .;
                *(.rela .rela*)
+               __rela_end = .;
        }
 
-       __rela_offset   = ABSOLUTE(ADDR(.rela.dyn) - KIMAGE_VADDR);
-       __rela_size     = SIZEOF(.rela.dyn);
-
-#ifdef CONFIG_RELR
        .relr.dyn : ALIGN(8) {
+               __relr_start = .;
                *(.relr.dyn)
+               __relr_end = .;
        }
 
-       __relr_offset   = ABSOLUTE(ADDR(.relr.dyn) - KIMAGE_VADDR);
-       __relr_size     = SIZEOF(.relr.dyn);
-#endif
-
        . = ALIGN(SEGMENT_ALIGN);
        __initdata_end = .;
        __init_end = .;