efi: libstub: Factor out min alignment and preferred kernel load address
authorArd Biesheuvel <ardb@kernel.org>
Wed, 12 Oct 2022 12:57:32 +0000 (14:57 +0200)
committerArd Biesheuvel <ardb@kernel.org>
Wed, 9 Nov 2022 11:42:03 +0000 (12:42 +0100)
Factor out the expressions that describe the preferred placement of the
loaded image as well as the minimum alignment so we can reuse them in
the decompressor.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/arm64/include/asm/efi.h
arch/loongarch/include/asm/efi.h
arch/riscv/include/asm/efi.h
drivers/firmware/efi/libstub/arm64-stub.c
drivers/firmware/efi/libstub/loongarch-stub.c
drivers/firmware/efi/libstub/riscv-stub.c

index 8604473a85b8b84f8952db3afcc9cd11e5c34a95..9253645866725212ac2232416a41a65b23411947 100644 (file)
@@ -84,6 +84,21 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
        return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
 }
 
+static inline unsigned long efi_get_kimg_min_align(void)
+{
+       extern bool efi_nokaslr;
+
+       /*
+        * Although relocatable kernels can fix up the misalignment with
+        * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are
+        * subtly out of sync with those recorded in the vmlinux when kaslr is
+        * disabled but the image required relocation anyway. Therefore retain
+        * 2M alignment if KASLR was explicitly disabled, even if it was not
+        * going to be activated to begin with.
+        */
+       return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN;
+}
+
 #define EFI_ALLOC_ALIGN                SZ_64K
 
 /*
index 60d6a170c18d9a07a25a9cc9c39c44a975c8066a..5a470c8d2bbc64e2bbde8a3c517603cb68e81da1 100644 (file)
@@ -24,4 +24,11 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
        return ULONG_MAX;
 }
 
+static inline unsigned long efi_get_kimg_min_align(void)
+{
+       return SZ_2M;
+}
+
+#define EFI_KIMG_PREFERRED_ADDRESS     PHYSADDR(VMLINUX_LOAD_ADDRESS)
+
 #endif /* _ASM_LOONGARCH_EFI_H */
index d0570936cb8c0bc1ecd1a52a2eef651833a05c41..a742868eb23ca5b7fdde631e2e02cab34d114149 100644 (file)
@@ -31,6 +31,17 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
        return ULONG_MAX;
 }
 
+static inline unsigned long efi_get_kimg_min_align(void)
+{
+       /*
+        * RISC-V requires the kernel image to placed 2 MB aligned base for 64
+        * bit and 4MB for 32 bit.
+        */
+       return IS_ENABLED(CONFIG_64BIT) ? SZ_2M : SZ_4M;
+}
+
+#define EFI_KIMG_PREFERRED_ADDRESS     efi_get_kimg_min_align()
+
 void efi_virtmap_load(void);
 void efi_virtmap_unload(void);
 
index bcb21afd8aeb61b703ee6da2c12794152021843d..f35c0e54e2940c7a7c22893fff6d3ca0f980a553 100644 (file)
@@ -88,16 +88,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
        efi_status_t status;
        unsigned long kernel_size, kernel_memsize = 0;
        u32 phys_seed = 0;
-
-       /*
-        * Although relocatable kernels can fix up the misalignment with
-        * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are
-        * subtly out of sync with those recorded in the vmlinux when kaslr is
-        * disabled but the image required relocation anyway. Therefore retain
-        * 2M alignment if KASLR was explicitly disabled, even if it was not
-        * going to be activated to begin with.
-        */
-       u64 min_kimg_align = efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN;
+       u64 min_kimg_align = efi_get_kimg_min_align();
 
        if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
                efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID;
index 32329f2a92f951965c50dc64e37f94757db984f8..a2e55e5c400309f37ce82bc37f000cd69139e405 100644 (file)
@@ -35,7 +35,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
        kernel_addr = (unsigned long)&kernel_offset - kernel_offset;
 
        status = efi_relocate_kernel(&kernel_addr, kernel_fsize, kernel_asize,
-                                    PHYSADDR(VMLINUX_LOAD_ADDRESS), SZ_2M, 0x0);
+                                    EFI_KIMG_PREFERRED_ADDRESS,
+                                    efi_get_kimg_min_align(), 0x0);
 
        *image_addr = kernel_addr;
        *image_size = kernel_asize;
index b450ebf959771ccb12ee29c0181312ecd2b6aa47..c5a551f69a7f41ae6b076572aac1b3349963d22b 100644 (file)
 
 #include "efistub.h"
 
-/*
- * RISC-V requires the kernel image to placed 2 MB aligned base for 64 bit and
- * 4MB for 32 bit.
- */
-#ifdef CONFIG_64BIT
-#define MIN_KIMG_ALIGN         SZ_2M
-#else
-#define MIN_KIMG_ALIGN         SZ_4M
-#endif
-
 typedef void __noreturn (*jump_kernel_func)(unsigned long, unsigned long);
 
 static unsigned long hartid;
@@ -125,9 +115,10 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
         * lowest possible memory region as long as the address and size meets
         * the alignment constraints.
         */
-       preferred_addr = MIN_KIMG_ALIGN;
+       preferred_addr = EFI_KIMG_PREFERRED_ADDRESS;
        status = efi_relocate_kernel(image_addr, kernel_size, *image_size,
-                                    preferred_addr, MIN_KIMG_ALIGN, 0x0);
+                                    preferred_addr, efi_get_kimg_min_align(),
+                                    0x0);
 
        if (status != EFI_SUCCESS) {
                efi_err("Failed to relocate kernel\n");