Commit 271f2a4a authored by Wang Yao's avatar Wang Yao Committed by Ard Biesheuvel
Browse files

efi/loongarch: Use load address to calculate kernel entry address



The efi_relocate_kernel() may load the PIE kernel to anywhere, the
loaded address may not be equal to link address or
EFI_KIMG_PREFERRED_ADDRESS.

Acked-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
Signed-off-by: default avatarWang Yao <wangyao@lemote.com>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 01b1e3ca
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -32,6 +32,6 @@ static inline unsigned long efi_get_kimg_min_align(void)

#define EFI_KIMG_PREFERRED_ADDRESS	PHYSADDR(VMLINUX_LOAD_ADDRESS)

unsigned long kernel_entry_address(void);
unsigned long kernel_entry_address(unsigned long kernel_addr);

#endif /* _ASM_LOONGARCH_EFI_H */
+2 −2
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
	return status;
}

unsigned long kernel_entry_address(void)
unsigned long kernel_entry_address(unsigned long kernel_addr)
{
	unsigned long base = (unsigned long)&kernel_offset - kernel_offset;

	return (unsigned long)&kernel_entry - base + VMLINUX_LOAD_ADDRESS;
	return (unsigned long)&kernel_entry - base + kernel_addr;
}
+3 −3
Original line number Diff line number Diff line
@@ -37,9 +37,9 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
	return EFI_SUCCESS;
}

unsigned long __weak kernel_entry_address(void)
unsigned long __weak kernel_entry_address(unsigned long kernel_addr)
{
	return *(unsigned long *)(PHYSADDR(VMLINUX_LOAD_ADDRESS) + 8);
	return *(unsigned long *)(kernel_addr + 8) - VMLINUX_LOAD_ADDRESS + kernel_addr;
}

efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
@@ -73,7 +73,7 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
	csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
	csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);

	real_kernel_entry = (void *)kernel_entry_address();
	real_kernel_entry = (void *)kernel_entry_address(kernel_addr);

	real_kernel_entry(true, (unsigned long)cmdline_ptr,
			  (unsigned long)efi_system_table);