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: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Wang Yao <wangyao@lemote.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
Wang Yao 2023-12-06 08:24:27 +08:00 committed by Ard Biesheuvel
parent 01b1e3ca0e
commit 271f2a4a95
3 changed files with 6 additions and 6 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);