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

efi/x86: Move x86 back to libstub

This reverts commit 84be880560fb, which itself reverted my original
attempt to move x86 from #include'ing .c files from across the tree
to using the EFI stub built as a static library.

The issue that affected the original approach was that splitting
the implementation into several .o files resulted in the variable
'efi_early' becoming a global with external linkage, which under
-fPIC implies that references to it must go through the GOT. However,
dealing with this additional GOT entry turned out to be troublesome
on some EFI implementations. (GCC's visibility=hidden attribute is
supposed to lift this requirement, but it turned out not to work on
the 32-bit build.)

Instead, use a pure getter function to get a reference to efi_early.
This approach results in no additional GOT entries being generated,
so there is no need for any changes in the early GOT handling.

Tested-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>

authored by

Ard Biesheuvel and committed by
Matt Fleming
243b6754 af5a29ae

+31 -22
+2 -1
arch/x86/boot/compressed/Makefile
··· 35 35 36 36 $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone 37 37 38 - vmlinux-objs-$(CONFIG_EFI_STUB) += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o 38 + vmlinux-objs-$(CONFIG_EFI_STUB) += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \ 39 + $(objtree)/drivers/firmware/efi/libstub/lib.a 39 40 40 41 $(obj)/vmlinux: $(vmlinux-objs-y) FORCE 41 42 $(call if_changed,ld)
+4 -4
arch/x86/boot/compressed/eboot.c
··· 21 21 22 22 static struct efi_config *efi_early; 23 23 24 - #define efi_call_early(f, ...) \ 25 - efi_early->call(efi_early->f, __VA_ARGS__); 24 + __pure const struct efi_config *__efi_early(void) 25 + { 26 + return efi_early; 27 + } 26 28 27 29 #define BOOT_SERVICES(bits) \ 28 30 static void setup_boot_services##bits(struct efi_config *c) \ ··· 286 284 efi_early->call(*func, out, str); 287 285 } 288 286 } 289 - 290 - #include "../../../../drivers/firmware/efi/libstub/efi-stub-helper.c" 291 287 292 288 static void find_bits(unsigned long mask, u8 *pos, u8 *size) 293 289 {
-16
arch/x86/boot/compressed/eboot.h
··· 103 103 void *blt; 104 104 }; 105 105 106 - struct efi_config { 107 - u64 image_handle; 108 - u64 table; 109 - u64 allocate_pool; 110 - u64 allocate_pages; 111 - u64 get_memory_map; 112 - u64 free_pool; 113 - u64 free_pages; 114 - u64 locate_handle; 115 - u64 handle_protocol; 116 - u64 exit_boot_services; 117 - u64 text_output; 118 - efi_status_t (*call)(unsigned long, ...); 119 - bool is64; 120 - } __packed; 121 - 122 106 #endif /* BOOT_COMPRESSED_EBOOT_H */
+24
arch/x86/include/asm/efi.h
··· 158 158 } 159 159 #endif /* CONFIG_EFI_MIXED */ 160 160 161 + 162 + /* arch specific definitions used by the stub code */ 163 + 164 + struct efi_config { 165 + u64 image_handle; 166 + u64 table; 167 + u64 allocate_pool; 168 + u64 allocate_pages; 169 + u64 get_memory_map; 170 + u64 free_pool; 171 + u64 free_pages; 172 + u64 locate_handle; 173 + u64 handle_protocol; 174 + u64 exit_boot_services; 175 + u64 text_output; 176 + efi_status_t (*call)(unsigned long, ...); 177 + bool is64; 178 + } __packed; 179 + 180 + __pure const struct efi_config *__efi_early(void); 181 + 182 + #define efi_call_early(f, ...) \ 183 + __efi_early()->call(__efi_early()->f, __VA_ARGS__); 184 + 161 185 extern bool efi_reboot_required(void); 162 186 163 187 #else
+1 -1
drivers/firmware/efi/Makefile
··· 7 7 obj-$(CONFIG_UEFI_CPER) += cper.o 8 8 obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o 9 9 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o 10 - obj-$(CONFIG_EFI_ARM_STUB) += libstub/ 10 + obj-$(CONFIG_EFI_STUB) += libstub/