Commit d7bea550 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Will Deacon
Browse files

arm64: head: use relative references to the RELA and RELR tables



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: default avatarArd Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20220624150651.1358849-14-ardb@kernel.org


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent c3cee924
Loading
Loading
Loading
Loading
+4 −9
Original line number Diff line number Diff line
@@ -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
+4 −8
Original line number Diff line number Diff line
@@ -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 = .;