]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
efi/loongarch: Use load address to calculate kernel entry address
authorWang Yao <wangyao@lemote.com>
Wed, 6 Dec 2023 00:24:27 +0000 (08:24 +0800)
committerArd Biesheuvel <ardb@kernel.org>
Mon, 11 Dec 2023 10:18:26 +0000 (11:18 +0100)
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>
arch/loongarch/include/asm/efi.h
drivers/firmware/efi/libstub/loongarch-stub.c
drivers/firmware/efi/libstub/loongarch.c

index 091897d40b0375758b4822ae1a95719013314709..91d81f9730ab3f81c8e6cba875a6fdadc4b0657a 100644 (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 */
index 72c71ae201f0dad34ab0b035c7af8eeb525d66ba..d6ec5d4b8dbe0878e029a349e6f7110d6e22bc19 100644 (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;
 }
index 807cba2693fc177abd3255073a0b56121182ac86..0e0aa6cda73f7c9fbcce5ab354e05e1623583710 100644 (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);