Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

efi: libstub: Factor out min alignment and preferred kernel load address

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>

+39 -23
+15
arch/arm64/include/asm/efi.h
··· 84 84 return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1)); 85 85 } 86 86 87 + static inline unsigned long efi_get_kimg_min_align(void) 88 + { 89 + extern bool efi_nokaslr; 90 + 91 + /* 92 + * Although relocatable kernels can fix up the misalignment with 93 + * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are 94 + * subtly out of sync with those recorded in the vmlinux when kaslr is 95 + * disabled but the image required relocation anyway. Therefore retain 96 + * 2M alignment if KASLR was explicitly disabled, even if it was not 97 + * going to be activated to begin with. 98 + */ 99 + return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; 100 + } 101 + 87 102 #define EFI_ALLOC_ALIGN SZ_64K 88 103 89 104 /*
+7
arch/loongarch/include/asm/efi.h
··· 24 24 return ULONG_MAX; 25 25 } 26 26 27 + static inline unsigned long efi_get_kimg_min_align(void) 28 + { 29 + return SZ_2M; 30 + } 31 + 32 + #define EFI_KIMG_PREFERRED_ADDRESS PHYSADDR(VMLINUX_LOAD_ADDRESS) 33 + 27 34 #endif /* _ASM_LOONGARCH_EFI_H */
+11
arch/riscv/include/asm/efi.h
··· 31 31 return ULONG_MAX; 32 32 } 33 33 34 + static inline unsigned long efi_get_kimg_min_align(void) 35 + { 36 + /* 37 + * RISC-V requires the kernel image to placed 2 MB aligned base for 64 38 + * bit and 4MB for 32 bit. 39 + */ 40 + return IS_ENABLED(CONFIG_64BIT) ? SZ_2M : SZ_4M; 41 + } 42 + 43 + #define EFI_KIMG_PREFERRED_ADDRESS efi_get_kimg_min_align() 44 + 34 45 void efi_virtmap_load(void); 35 46 void efi_virtmap_unload(void); 36 47
+1 -10
drivers/firmware/efi/libstub/arm64-stub.c
··· 88 88 efi_status_t status; 89 89 unsigned long kernel_size, kernel_memsize = 0; 90 90 u32 phys_seed = 0; 91 - 92 - /* 93 - * Although relocatable kernels can fix up the misalignment with 94 - * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are 95 - * subtly out of sync with those recorded in the vmlinux when kaslr is 96 - * disabled but the image required relocation anyway. Therefore retain 97 - * 2M alignment if KASLR was explicitly disabled, even if it was not 98 - * going to be activated to begin with. 99 - */ 100 - u64 min_kimg_align = efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; 91 + u64 min_kimg_align = efi_get_kimg_min_align(); 101 92 102 93 if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { 103 94 efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID;
+2 -1
drivers/firmware/efi/libstub/loongarch-stub.c
··· 35 35 kernel_addr = (unsigned long)&kernel_offset - kernel_offset; 36 36 37 37 status = efi_relocate_kernel(&kernel_addr, kernel_fsize, kernel_asize, 38 - PHYSADDR(VMLINUX_LOAD_ADDRESS), SZ_2M, 0x0); 38 + EFI_KIMG_PREFERRED_ADDRESS, 39 + efi_get_kimg_min_align(), 0x0); 39 40 40 41 *image_addr = kernel_addr; 41 42 *image_size = kernel_asize;
+3 -12
drivers/firmware/efi/libstub/riscv-stub.c
··· 12 12 13 13 #include "efistub.h" 14 14 15 - /* 16 - * RISC-V requires the kernel image to placed 2 MB aligned base for 64 bit and 17 - * 4MB for 32 bit. 18 - */ 19 - #ifdef CONFIG_64BIT 20 - #define MIN_KIMG_ALIGN SZ_2M 21 - #else 22 - #define MIN_KIMG_ALIGN SZ_4M 23 - #endif 24 - 25 15 typedef void __noreturn (*jump_kernel_func)(unsigned long, unsigned long); 26 16 27 17 static unsigned long hartid; ··· 115 125 * lowest possible memory region as long as the address and size meets 116 126 * the alignment constraints. 117 127 */ 118 - preferred_addr = MIN_KIMG_ALIGN; 128 + preferred_addr = EFI_KIMG_PREFERRED_ADDRESS; 119 129 status = efi_relocate_kernel(image_addr, kernel_size, *image_size, 120 - preferred_addr, MIN_KIMG_ALIGN, 0x0); 130 + preferred_addr, efi_get_kimg_min_align(), 131 + 0x0); 121 132 122 133 if (status != EFI_SUCCESS) { 123 134 efi_err("Failed to relocate kernel\n");