EFI updates for v5.8
Subsystems (6)
Ard Biesheuvel
maintainerHello Ingo, Thomas,
Please pull the attached changes into tip/efi/next. There is some coordination going on with the RISC-V tree this time, so please take the patches in this exact order, and apply them onto v5.7-rc2 so the first three patches can serve as a shared stable base between the efi/core branch and the riscv tree.
The following changes since commit ae83d0b416db002fe95601e7f97f64b59514d936:
Linux 5.7-rc2 (2020-04-19 14:35:30 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git tags/efi-next
for you to fetch changes up to 4eb8320bd1aaa7e69d039f2c251735e3ef0b9a38:
efi: Move arch_tables check to caller (2020-04-24 14:52:16 +0200)
----------------------------------------------------------------
EFI changes for v5.8:
- preliminary changes for RISC-V
- add support for setting the resolution on the EFI framebuffer
- simplify kernel image loading for arm64
- Move .bss into .data via the linker script instead of relying on symbol annotations.
- Get rid of __pure getters to access global variables
- Clean up the config table matching arrays
----------------------------------------------------------------
Ard Biesheuvel (14):
efi/libstub: Make initrd file loader configurable efi/libstub: Unify EFI call wrappers for non-x86 efi/libstub/random: Align allocate size to EFI_ALLOC_ALIGN efi/libstub/random: Increase random alloc granularity efi/libstub/arm64: Replace 'preferred' offset with alignment check efi/libstub/arm64: Simplify randomized loading of kernel image efi/libstub: Add API function to allocate aligned memory efi/libstub/arm64: Switch to ordinary page allocator for kernel image efi/libstub: Move efi_relocate_kernel() into separate source file efi/libstub: Drop __pure getter for efi_system_table efi/libstub: Drop __pure getters for EFI stub options efi/libstub/x86: Avoid getter function for efi_is64
efi: Clean up config table description arrays
efi: Move arch_tables check to caller
Arvind Sankar (17):
efi/gop: Remove redundant current_fb_base efi/gop: Move check for framebuffer before con_out efi/gop: Get mode information outside the loop efi/gop: Factor out locating the gop into a function efi/gop: Slightly re-arrange logic of find_gop efi/gop: Move variable declarations into loop block efi/gop: Use helper macros for populating lfb_base efi/gop: Use helper macros for find_bits efi/gop: Remove unreachable code from setup_pixel_info efi/gop: Add prototypes for query_mode and set_mode efi/gop: Allow specifying mode number on command line efi/gop: Allow specifying mode by <xres>x<yres> efi/gop: Allow specifying depth as well as resolution efi/gop: Allow automatically choosing the best mode efi/arm: Remove __efistub_global annotation efi/x86: Remove __efistub_global and add relocation check
efi: Kill __efistub_global
Atish Patra (1):
efi/libstub: Move arm-stub to a common file
Zou Wei (1):
efi/libstub/arm: Make install_memreserve_table static
Documentation/fb/efifb.rst | 33 +-
arch/arm/Kconfig | 2 +-
arch/arm/boot/compressed/vmlinux.lds.S | 2 +-
arch/arm/include/asm/efi.h | 8 -
arch/arm64/Kconfig | 2 +-
arch/arm64/include/asm/efi.h | 8 -
arch/ia64/kernel/efi.c | 12 +-
arch/x86/boot/compressed/vmlinux.lds.S | 1 +
arch/x86/include/asm/efi.h | 29 +-
arch/x86/platform/efi/efi.c | 8 +-
drivers/firmware/efi/Kconfig | 15 +-
drivers/firmware/efi/arm-init.c | 4 +-
drivers/firmware/efi/efi.c | 44 +-
drivers/firmware/efi/libstub/Makefile | 42 +-
drivers/firmware/efi/libstub/alignedmem.c | 57 +++
drivers/firmware/efi/libstub/arm64-stub.c | 94 ++--
drivers/firmware/efi/libstub/efi-stub-helper.c | 47 +-
.../efi/libstub/{arm-stub.c => efi-stub.c} | 23 +-
drivers/firmware/efi/libstub/efistub.h | 96 ++--
drivers/firmware/efi/libstub/fdt.c | 8 +-
drivers/firmware/efi/libstub/file.c | 34 +-
drivers/firmware/efi/libstub/gop.c | 492 ++++++++++++++++-----
drivers/firmware/efi/libstub/mem.c | 191 +-------
drivers/firmware/efi/libstub/randomalloc.c | 6 +-
drivers/firmware/efi/libstub/relocate.c | 174 ++++++++
drivers/firmware/efi/libstub/x86-stub.c | 35 +-
include/linux/efi.h | 2 +-
27 files changed, 895 insertions(+), 574 deletions(-)
create mode 100644 drivers/firmware/efi/libstub/alignedmem.c
rename drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c} (96%)
create mode 100644 drivers/firmware/efi/libstub/relocate.cArd Biesheuvel
maintainerPATCH 1/33 efi/libstub: Move arm-stub to a common file
From: Atish Patra <[email protected]>
Most of the arm-stub code is written in an architecture independent manner. As a result, RISC-V can reuse most of the arm-stub code.
Rename the arm-stub.c to efi-stub.c so that ARM, ARM64 and RISC-V can use it. This patch doesn't introduce any functional changes.
---
arch/arm/Kconfig | 2 +-
arch/arm64/Kconfig | 2 +-
drivers/firmware/efi/Kconfig | 4 ++--
drivers/firmware/efi/libstub/Makefile | 12 ++++++------
.../firmware/efi/libstub/{arm-stub.c => efi-stub.c} | 0
5 files changed, 10 insertions(+), 10 deletions(-)
rename drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c} (100%)arch/arm/Kconfig +1 -1
@@ -1954,7 +1954,7 @@ config EFI select UCS2_STRING select EFI_PARAMS_FROM_FDT select EFI_STUB - select EFI_ARMSTUB + select EFI_GENERIC_STUB select EFI_RUNTIME_WRAPPERS ---help--- This option provides support for runtime services provided
arch/arm64/Kconfig +1 -1
@@ -1785,7 +1785,7 @@ config EFI select EFI_PARAMS_FROM_FDT select EFI_RUNTIME_WRAPPERS select EFI_STUB - select EFI_ARMSTUB + select EFI_GENERIC_STUB default y help This option provides support for runtime services provided
drivers/firmware/efi/Kconfig +2 -2
@@ -106,12 +106,12 @@ config EFI_PARAMS_FROM_FDT config EFI_RUNTIME_WRAPPERS bool -config EFI_ARMSTUB +config EFI_GENERIC_STUB bool config EFI_ARMSTUB_DTB_LOADER bool "Enable the DTB loader" - depends on EFI_ARMSTUB + depends on EFI_GENERIC_STUB default y help Select this config option to add support for the dtb= command
drivers/firmware/efi/libstub/Makefile +6 -6
@@ -23,7 +23,7 @@ cflags-$(CONFIG_ARM) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ -fno-builtin -fpic \ $(call cc-option,-mno-single-pic-base) -cflags-$(CONFIG_EFI_ARMSTUB) += -I$(srctree)/scripts/dtc/libfdt +cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt KBUILD_CFLAGS := $(cflags-y) -DDISABLE_BRANCH_PROFILING \ -include $(srctree)/drivers/firmware/efi/libstub/hidden.h \
@@ -45,13 +45,13 @@ lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ skip_spaces.o lib-cmdline.o lib-ctype.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 -arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c +efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE $(call if_changed_rule,cc_o_c) -lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o \ - $(patsubst %.c,lib-%.o,$(arm-deps-y)) +lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o fdt.o string.o \ + $(patsubst %.c,lib-%.o,$(efi-deps-y)) lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o
@@ -73,8 +73,8 @@ CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # a verification pass to see if any absolute relocations exist in any of the # object files. # -extra-$(CONFIG_EFI_ARMSTUB) := $(lib-y) -lib-$(CONFIG_EFI_ARMSTUB) := $(patsubst %.o,%.stub.o,$(lib-y)) +extra-$(CONFIG_EFI_GENERIC_STUB) := $(lib-y) +lib-$(CONFIG_EFI_GENERIC_STUB) := $(patsubst %.o,%.stub.o,$(lib-y)) STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \ --prefix-symbols=__efistub_
drivers/firmware/efi/libstub/efi-stub.c renamed from drivers/firmware/efi/libstub/arm-stub.c +0 -0
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 2/33 efi/libstub: Make initrd file loader configurable
In reply to Ard BiesheuvelLoading an initrd passed via the kernel command line is deprecated: it is limited to files that reside in the same volume as the one the kernel itself was loaded from, and we have more flexible ways to achieve the same. So make it configurable so new architectures can decide not to enable it.
--- drivers/firmware/efi/Kconfig | 11 ++++++++ drivers/firmware/efi/libstub/efistub.h | 38 ++++++++++++++++++++------ drivers/firmware/efi/libstub/file.c | 32 +++++----------------- 3 files changed, 47 insertions(+), 34 deletions(-)
drivers/firmware/efi/Kconfig +11 -0
@@ -124,6 +124,17 @@ config EFI_ARMSTUB_DTB_LOADER functionality for bootloaders that do not have such support this option is necessary. +config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER + bool "Enable the command line initrd loader" + depends on EFI_GENERIC_STUB + default y + help + Select this config option to add support for the initrd= command + line parameter, allowing an initrd that resides on the same volume + as the kernel image to be loaded into memory. + + This method is deprecated. + config EFI_BOOTLOADER_CONTROL tristate "EFI Bootloader Control" depends on EFI_VARS
drivers/firmware/efi/libstub/efistub.h +29 -9
@@ -651,15 +651,35 @@ efi_status_t efi_parse_options(char const *cmdline);efi_status_t efi_setup_gop (struct screen_info *si,efi_guid_t *proto,unsigned long size); -efi_status_t efi_load_dtb (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size); - -efi_status_t efi_load_initrd (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size, -unsigned long soft_limit, -unsigned long hard_limit); +efi_status_t handle_cmdline_files (efi_loaded_image_t *image, +const efi_char16_t *optstr, +int optstr_size, +unsigned long soft_limit, +unsigned long hard_limit, +unsigned long *load_addr, +unsigned long *load_size); + + +static inline efi_status_t efi_load_dtb (efi_loaded_image_t *image, +unsigned long *load_addr, +unsigned long *load_size) +{ +return handle_cmdline_files (image,L"dtb=" ,sizeof (L"dtb=" ) -2 , +ULONG_MAX ,ULONG_MAX , load_addr, load_size); +} + +static inline efi_status_t efi_load_initrd (efi_loaded_image_t *image, +unsigned long *load_addr, +unsigned long *load_size, +unsigned long soft_limit, +unsigned long hard_limit) +{ +if (!IS_ENABLED (CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER )) +return EFI_SUCCESS ; + +return handle_cmdline_files (image,L"initrd=" ,sizeof (L"initrd=" ) -2 , + soft_limit, hard_limit, load_addr, load_size); +} efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr, unsigned long *load_size,
drivers/firmware/efi/libstub/file.c +7 -25
@@ -121,13 +121,13 @@ static int find_file_option(const efi_char16_t *cmdline, int cmdline_len,* We only support loading a file from the same filesystem as * the kernel image. */ -static efi_status_t handle_cmdline_files (efi_loaded_image_t *image, -const efi_char16_t *optstr, -int optstr_size, -unsigned long soft_limit, -unsigned long hard_limit, -unsigned long *load_addr, -unsigned long *load_size) +efi_status_t handle_cmdline_files (efi_loaded_image_t *image, +const efi_char16_t *optstr, +int optstr_size, +unsigned long soft_limit, +unsigned long hard_limit, +unsigned long *load_addr, +unsigned long *load_size) {const efi_char16_t *cmdline = image->load_options;int cmdline_len = image->load_options_size /2 ;
@@ -239,21 +239,3 @@ static efi_status_t handle_cmdline_files(efi_loaded_image_t *image,efi_free (alloc_size, alloc_addr);return status; } - -efi_status_t efi_load_dtb (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size) -{ -return handle_cmdline_files (image,L"dtb=" ,sizeof (L"dtb=" ) -2 , -ULONG_MAX ,ULONG_MAX , load_addr, load_size); -} - -efi_status_t efi_load_initrd (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size, -unsigned long soft_limit, -unsigned long hard_limit) -{ -return handle_cmdline_files (image,L"initrd=" ,sizeof (L"initrd=" ) -2 , - soft_limit, hard_limit, load_addr, load_size); -}
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 3/33 efi/libstub: Unify EFI call wrappers for non-x86
In reply to Ard BiesheuvelWe have wrappers around EFI calls so that x86 can define special versions for mixed mode, while all other architectures can use the same simple definition that just issues the call directly. In preparation for the arrival of yet another architecture that doesn't need anything special here (RISC-V), let's move the default definition into a shared header.
--- arch/arm/include/asm/efi.h | 8 -------- arch/arm64/include/asm/efi.h | 8 -------- drivers/firmware/efi/libstub/efistub.h | 16 ++++++++++++++++ 3 files changed, 16 insertions(+), 16 deletions(-)
arch/arm/include/asm/efi.h +0 -8
@@ -50,14 +50,6 @@ void efi_virtmap_unload(void);/* arch specific definitions used by the stub code */ -#define efi_bs_call (func, ...) efi_system_table()->boottime->func(__VA_ARGS__) -#define efi_rt_call (func, ...) efi_system_table()->runtime->func(__VA_ARGS__) -#define efi_is_native () (true) - -#define efi_table_attr (inst, attr) (inst->attr) - -#define efi_call_proto (inst, func, ...) inst->func(inst, ##__VA_ARGS__) -struct screen_info *alloc_screen_info (void );void free_screen_info (struct screen_info *si);
arch/arm64/include/asm/efi.h +0 -8
@@ -86,14 +86,6 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,return (image_addr & ~(SZ_1G -1UL )) + (1UL << (VA_BITS_MIN -1 )); } -#define efi_bs_call (func, ...) efi_system_table()->boottime->func(__VA_ARGS__) -#define efi_rt_call (func, ...) efi_system_table()->runtime->func(__VA_ARGS__) -#define efi_is_native () (true) - -#define efi_table_attr (inst, attr) (inst->attr) - -#define efi_call_proto (inst, func, ...) inst->func(inst, ##__VA_ARGS__) - #define alloc_screen_info(x...) &screen_infostatic inline void free_screen_info (struct screen_info *si)
drivers/firmware/efi/libstub/efistub.h +16 -0
@@ -39,6 +39,22 @@ extern bool __pure novamap(void);extern __pure efi_system_table_t *efi_system_table (void ); +#ifndef efi_bs_call +#define efi_bs_call (func, ...) efi_system_table()->boottime->func(__VA_ARGS__) +#endif +#ifndef efi_rt_call +#define efi_rt_call (func, ...) efi_system_table()->runtime->func(__VA_ARGS__) +#endif +#ifndef efi_is_native +#define efi_is_native () (true) +#endif +#ifndef efi_table_attr +#define efi_table_attr (inst, attr) (inst->attr) +#endif +#ifndef efi_call_proto +#define efi_call_proto (inst, func, ...) inst->func(inst, ##__VA_ARGS__) +#endif +#define pr_efi (msg) do { \ if (!is_quiet()) efi_printk("EFI stub: "msg); \ } while (0)
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 4/33 efi/libstub/arm: Make install_memreserve_table static
In reply to Ard BiesheuvelFrom: Zou Wei <[email protected]>
Fix the following sparse warning:
drivers/firmware/efi/libstub/arm-stub.c:68:6: warning:
symbol 'install_memreserve_table' was not declared. Should it be static?
--- drivers/firmware/efi/libstub/efi-stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/libstub/efi-stub.c +1 -1
@@ -65,7 +65,7 @@ static struct screen_info *setup_graphics(void)return si; } -void install_memreserve_table (void ) +static void install_memreserve_table (void ) {struct linux_efi_memreserve *rsv;efi_guid_t memreserve_table_guid =LINUX_EFI_MEMRESERVE_TABLE_GUID ;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 6/33 efi/gop: Move check for framebuffer before con_out
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
If the gop doesn't have a framebuffer, there's no point in checking for con_out support.
--- drivers/firmware/efi/libstub/gop.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/firmware/efi/libstub/gop.c +6 -5
@@ -113,15 +113,16 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,if (status !=EFI_SUCCESS )continue ; + mode =efi_table_attr (gop, mode); + info =efi_table_attr (mode, info); +if (info->pixel_format ==PIXEL_BLT_ONLY ) +continue ; + status =efi_bs_call (handle_protocol, h, &conout_proto, &dummy);if (status ==EFI_SUCCESS ) conout_found = true; - mode =efi_table_attr (gop, mode); - info =efi_table_attr (mode, info); - -if ((!first_gop || conout_found) && - info->pixel_format !=PIXEL_BLT_ONLY ) { +if (!first_gop || conout_found) {/* * Systems that use the UEFI Console Splitter may * provide multiple GOP devices, not all of which are
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 7/33 efi/gop: Get mode information outside the loop
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Move extraction of the mode information parameters outside the loop to find the gop, and eliminate some redundant variables.
--- drivers/firmware/efi/libstub/gop.c | 38 +++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-)
drivers/firmware/efi/libstub/gop.c +14 -24
@@ -89,12 +89,9 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, unsigned long size, void **handles) { efi_graphics_output_protocol_t *gop, *first_gop; -u16 width, height; -u32 pixels_per_scan_line; -u32 ext_lfb_base; +efi_graphics_output_protocol_mode_t *mode; +efi_graphics_output_mode_info_t *info =NULL ;efi_physical_addr_t fb_base; -efi_pixel_bitmask_t pixel_info; -int pixel_format;efi_status_t status;efi_handle_t h;int i;
@@ -103,8 +100,6 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, gop =NULL ;for_each_efi_handle (h, handles, size, i) { -efi_graphics_output_protocol_mode_t *mode; -efi_graphics_output_mode_info_t *info =NULL ;efi_guid_t conout_proto =EFI_CONSOLE_OUT_DEVICE_GUID ;bool conout_found = false;void *dummy =NULL ;
@@ -129,15 +124,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,* backed by real hardware. The workaround is to search * for a GOP implementing the ConOut protocol, and if * one isn't found, to just fall back to the first GOP. -*/ - width = info->horizontal_resolution; - height = info->vertical_resolution; - pixel_format = info->pixel_format; - pixel_info = info->pixel_information; - pixels_per_scan_line = info->pixels_per_scan_line; - fb_base =efi_table_attr (mode, frame_buffer_base); - -/* +* * Once we've found a GOP supporting ConOut, * don't bother looking any further. */
@@ -152,21 +139,24 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,return EFI_NOT_FOUND ;/* EFI framebuffer */ + mode =efi_table_attr (first_gop, mode); + info =efi_table_attr (mode, info); + si->orig_video_isVGA =VIDEO_TYPE_EFI ; - si->lfb_width = width; - si->lfb_height = height; - si->lfb_base = fb_base; + si->lfb_width = info->horizontal_resolution; + si->lfb_height = info->vertical_resolution; - ext_lfb_base = (u64 )(unsigned long )fb_base >>32 ; -if (ext_lfb_base) { + fb_base =efi_table_attr (mode, frame_buffer_base); + si->lfb_base = fb_base; + si->ext_lfb_base = (u64 )(unsigned long )fb_base >>32 ; +if (si->ext_lfb_base) si->capabilities |=VIDEO_CAPABILITY_64BIT_BASE ; - si->ext_lfb_base = ext_lfb_base; - } si->pages =1 ; -setup_pixel_info (si, pixels_per_scan_line, pixel_info, pixel_format); +setup_pixel_info (si, info->pixels_per_scan_line, + info->pixel_information, info->pixel_format); si->lfb_size = si->lfb_linelength * si->lfb_height;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 9/33 efi/gop: Slightly re-arrange logic of find_gop
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Small cleanup to get rid of conout_found.
--- drivers/firmware/efi/libstub/gop.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)
drivers/firmware/efi/libstub/gop.c +13 -17
@@ -99,7 +99,6 @@ find_gop(efi_guid_t *proto, unsigned long size, void **handles)for_each_efi_handle (h, handles, size, i) {efi_guid_t conout_proto =EFI_CONSOLE_OUT_DEVICE_GUID ; -bool conout_found = false;void *dummy =NULL ; status =efi_bs_call (handle_protocol, h, proto, (void **)&gop);
@@ -111,25 +110,22 @@ find_gop(efi_guid_t *proto, unsigned long size, void **handles)if (info->pixel_format ==PIXEL_BLT_ONLY )continue ; +/* +* Systems that use the UEFI Console Splitter may +* provide multiple GOP devices, not all of which are +* backed by real hardware. The workaround is to search +* for a GOP implementing the ConOut protocol, and if +* one isn't found, to just fall back to the first GOP. +* +* Once we've found a GOP supporting ConOut, +* don't bother looking any further. +*/ status =efi_bs_call (handle_protocol, h, &conout_proto, &dummy);if (status ==EFI_SUCCESS ) - conout_found = true; - -if (!first_gop || conout_found) { -/* -* Systems that use the UEFI Console Splitter may -* provide multiple GOP devices, not all of which are -* backed by real hardware. The workaround is to search -* for a GOP implementing the ConOut protocol, and if -* one isn't found, to just fall back to the first GOP. -* -* Once we've found a GOP supporting ConOut, -* don't bother looking any further. -*/ +return gop; + +if (!first_gop) first_gop = gop; -if (conout_found) -break ; - } }return first_gop;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 10/33 efi/gop: Move variable declarations into loop block
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Declare the variables inside the block where they're used.
Get rid of a couple of redundant initializers.
--- drivers/firmware/efi/libstub/gop.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/firmware/efi/libstub/gop.c +8 -5
@@ -88,16 +88,19 @@ setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,static efi_graphics_output_protocol_t *find_gop (efi_guid_t *proto,unsigned long size,void **handles) { -efi_graphics_output_protocol_t *gop, *first_gop; -efi_graphics_output_protocol_mode_t *mode; -efi_graphics_output_mode_info_t *info =NULL ; -efi_status_t status; +efi_graphics_output_protocol_t *first_gop;efi_handle_t h;int i; first_gop =NULL ;for_each_efi_handle (h, handles, size, i) { +efi_status_t status; + +efi_graphics_output_protocol_t *gop; +efi_graphics_output_protocol_mode_t *mode; +efi_graphics_output_mode_info_t *info; +efi_guid_t conout_proto =EFI_CONSOLE_OUT_DEVICE_GUID ;void *dummy =NULL ;
@@ -136,7 +139,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, {efi_graphics_output_protocol_t *gop;efi_graphics_output_protocol_mode_t *mode; -efi_graphics_output_mode_info_t *info =NULL ; +efi_graphics_output_mode_info_t *info;efi_physical_addr_t fb_base; gop =find_gop (proto, size, handles);
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 12/33 efi/gop: Use helper macros for find_bits
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Use the __ffs/__fls macros to calculate the position and size of the mask.
Correct type of mask to u32 instead of unsigned long.
--- drivers/firmware/efi/libstub/gop.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-)
drivers/firmware/efi/libstub/gop.c +8 -18
@@ -5,6 +5,7 @@* * ----------------------------------------------------------------------- */ +#include <linux/bitops.h> #include <linux/efi.h> #include <linux/screen_info.h> #include <asm/efi.h>
@@ -12,27 +13,16 @@#include "efistub.h" -static void find_bits (unsigned long mask,u8 *pos,u8 *size) +static void find_bits (u32 mask,u8 *pos,u8 *size) { -u8 first, len; - - first =0 ; - len =0 ; - -if (mask) { -while (!(mask &0x1 )) { - mask = mask >>1 ; - first++; - } - -while (mask &0x1 ) { - mask = mask >>1 ; - len++; - } +if (!mask) { + *pos = *size =0 ; +return ; } - *pos = first; - *size = len; +/* UEFI spec guarantees that the set bits are contiguous */ + *pos =__ffs (mask); + *size =__fls (mask) - *pos +1 ; } static void
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 13/33 efi/gop: Remove unreachable code from setup_pixel_info
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
pixel_format must be one of
PIXEL_RGB_RESERVED_8BIT_PER_COLOR
PIXEL_BGR_RESERVED_8BIT_PER_COLOR
PIXEL_BIT_MASK
since we skip PIXEL_BLT_ONLY when finding a gop.
Remove the redundant code and add another check in find_gop to skip any pixel formats that we don't know about, in case a later version of the UEFI spec adds one.
Reformat the code a little.
--- drivers/firmware/efi/libstub/gop.c | 66 ++++++++++++------------------ 1 file changed, 26 insertions(+), 40 deletions(-)
drivers/firmware/efi/libstub/gop.c +26 -40
@@ -29,49 +29,34 @@ static void setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line, efi_pixel_bitmask_t pixel_info, int pixel_format) { - if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) { - si->lfb_depth = 32; - si->lfb_linelength = pixels_per_scan_line *4 ; - si->red_size =8 ; - si->red_pos =0 ; - si->green_size =8 ; - si->green_pos =8 ; - si->blue_size =8 ; - si->blue_pos =16 ; - si->rsvd_size =8 ; - si->rsvd_pos =24 ; - } else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) { - si->lfb_depth =32 ; - si->lfb_linelength = pixels_per_scan_line *4 ; - si->red_size =8 ; - si->red_pos =16 ; - si->green_size =8 ; - si->green_pos =8 ; - si->blue_size =8 ; - si->blue_pos =0 ; - si->rsvd_size =8 ; - si->rsvd_pos =24 ; - }else if (pixel_format ==PIXEL_BIT_MASK ) { -find_bits (pixel_info.red_mask, &si->red_pos, &si->red_size); -find_bits (pixel_info.green_mask, &si->green_pos, - &si->green_size); -find_bits (pixel_info.blue_mask, &si->blue_pos, &si->blue_size); -find_bits (pixel_info.reserved_mask, &si->rsvd_pos, - &si->rsvd_size); + if (pixel_format == PIXEL_BIT_MASK) { + find_bits(pixel_info.red_mask, + &si->red_pos, &si->red_size); +find_bits (pixel_info.green_mask, + &si->green_pos, &si->green_size); +find_bits (pixel_info.blue_mask, + &si->blue_pos, &si->blue_size); +find_bits (pixel_info.reserved_mask, + &si->rsvd_pos, &si->rsvd_size); si->lfb_depth = si->red_size + si->green_size + si->blue_size + si->rsvd_size; si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) /8 ; } else { - si->lfb_depth =4 ; - si->lfb_linelength = si->lfb_width /2 ; - si->red_size =0 ; - si->red_pos =0 ; - si->green_size =0 ; - si->green_pos =0 ; - si->blue_size =0 ; - si->blue_pos =0 ; - si->rsvd_size =0 ; - si->rsvd_pos =0 ; +if (pixel_format ==PIXEL_RGB_RESERVED_8BIT_PER_COLOR ) { + si->red_pos =0 ; + si->blue_pos =16 ; + }else /* PIXEL_BGR_RESERVED_8BIT_PER_COLOR */ { + si->blue_pos =0 ; + si->red_pos =16 ; + } + + si->green_pos =8 ; + si->rsvd_pos =24 ; + si->red_size = si->green_size = + si->blue_size = si->rsvd_size =8 ; + + si->lfb_depth =32 ; + si->lfb_linelength = pixels_per_scan_line *4 ; } }
@@ -100,7 +85,8 @@ find_gop(efi_guid_t *proto, unsigned long size, void **handles) mode =efi_table_attr (gop, mode); info =efi_table_attr (mode, info); -if (info->pixel_format ==PIXEL_BLT_ONLY ) +if (info->pixel_format ==PIXEL_BLT_ONLY || + info->pixel_format >=PIXEL_FORMAT_MAX )continue ;/*
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 14/33 efi/gop: Add prototypes for query_mode and set_mode
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Add prototypes and argmap for the Graphics Output Protocol's QueryMode and SetMode functions.
--- arch/x86/include/asm/efi.h | 4 ++++ drivers/firmware/efi/libstub/efistub.h | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/include/asm/efi.h +4 -0
@@ -307,6 +307,10 @@ static inline u32 efi64_convert_status(efi_status_t status)#define __efi64_argmap_load_file (protocol, path, policy, bufsize, buf) \ ((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf)) +/* Graphics Output Protocol */ +#define __efi64_argmap_query_mode (gop, mode, size, info) \ + ((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info)) +/* * The macros below handle the plumbing for the argument mapping. To add a * mapping for a specific EFI method, simply define a macro
drivers/firmware/efi/libstub/efistub.h +4 -2
@@ -314,8 +314,10 @@ typedef union efi_graphics_output_protocol efi_graphics_output_protocol_t;union efi_graphics_output_protocol {struct { -void *query_mode; -void *set_mode; + efi_status_t (__efiapi *query_mode)(efi_graphics_output_protocol_t *, + u32, unsigned long *, + efi_graphics_output_mode_info_t **); + efi_status_t (__efiapi *set_mode) (efi_graphics_output_protocol_t *,u32 );void *blt;efi_graphics_output_protocol_mode_t *mode; };
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 15/33 efi/gop: Allow specifying mode number on command line
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Add the ability to choose a video mode for the selected gop by using a command-line argument of the form
video=efifb:mode=<n>
--- Documentation/fb/efifb.rst | 20 +++- .../firmware/efi/libstub/efi-stub-helper.c | 3 + drivers/firmware/efi/libstub/efistub.h | 2 + drivers/firmware/efi/libstub/gop.c | 107 ++++++++++++++++++ 4 files changed, 129 insertions(+), 3 deletions(-)
Documentation/fb/efifb.rst +17 -3
@@ -2,8 +2,10 @@ What is efifb? ============== -This is a generic EFI platform driver for Intel based Apple computers. -efifb is only for EFI booted Intel Macs. +This is a generic EFI platform driver for systems with UEFI firmware. The +system must be booted via the EFI stub for this to be usable. efifb supports +both firmware with Graphics Output Protocol (GOP) displays as well as older +systems with only Universal Graphics Adapter (UGA) displays. Supported Hardware ==================
@@ -12,11 +14,14 @@ Supported Hardware - Macbook - Macbook Pro 15"/17" - MacMini +- ARM/ARM64/X86 systems with UEFI firmware How to use it? ============== -efifb does not have any kind of autodetection of your machine. +For UGA displays, efifb does not have any kind of autodetection of your +machine. + You have to add the following kernel parameters in your elilo.conf:: Macbook :
@@ -28,6 +33,9 @@ You have to add the following kernel parameters in your elilo.conf:: Macbook Pro 17", iMac 20" : video=efifb:i20 +For GOP displays, efifb can autodetect the display's resolution and framebuffer +address, so these should work out of the box without any special parameters. + Accepted options: ======= ===========================================================
@@ -36,4 +44,10 @@ nowc Don't map the framebuffer write combined. This can be used when large amounts of console data are written. ======= =========================================================== +Options for GOP displays: + +mode=n + The EFI stub will set the mode of the display to mode number n if + possible. + Edgar Hucek <[email protected]>
drivers/firmware/efi/libstub/efi-stub-helper.c +3 -0
@@ -105,6 +105,9 @@ efi_status_t efi_parse_options(char const *cmdline) efi_disable_pci_dma = true;if (parse_option_str (val,"no_disable_early_pci_dma" )) efi_disable_pci_dma = false; + }else if (!strcmp (param,"video" ) && + val &&strstarts (val,"efifb:" )) { +efi_parse_option_graphics (val +strlen ("efifb:" )); } }efi_bs_call (free_pool, buf);
drivers/firmware/efi/libstub/efistub.h +2 -0
@@ -666,6 +666,8 @@ efi_status_t efi_relocate_kernel(unsigned long *image_addr,efi_status_t efi_parse_options (char const *cmdline); +void efi_parse_option_graphics (char *option); +efi_status_t efi_setup_gop (struct screen_info *si,efi_guid_t *proto,unsigned long size);
drivers/firmware/efi/libstub/gop.c +107 -0
124 lines not on this page · raw message
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 16/33 efi/gop: Allow specifying mode by <xres>x<yres>
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Add the ability to choose a video mode using a command-line argument of the form
video=efifb:<xres>x<yres>
--- Documentation/fb/efifb.rst | 5 ++ drivers/firmware/efi/libstub/gop.c | 84 +++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 1 deletion(-)
Documentation/fb/efifb.rst +5 -0
@@ -50,4 +50,9 @@ mode=n The EFI stub will set the mode of the display to mode number n if possible. +<xres>x<yres> + The EFI stub will search for a display mode that matches the specified + horizontal and vertical resolution, and set the mode of the display to + it if one is found. + Edgar Hucek <[email protected]>
drivers/firmware/efi/libstub/gop.c +83 -1
123 lines not on this page · raw message
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 18/33 efi/gop: Allow automatically choosing the best mode
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Add the ability to automatically pick the highest resolution video mode (defined as the product of vertical and horizontal resolution) by using a command-line argument of the form
video=efifb:auto
If there are multiple modes with the highest resolution, pick one with the highest color depth.
--- Documentation/fb/efifb.rst | 6 +++ drivers/firmware/efi/libstub/gop.c | 84 +++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
Documentation/fb/efifb.rst +6 -0
@@ -57,4 +57,10 @@ mode=n "rgb" or "bgr" to match specifically those pixel formats, or a number for a mode with matching bits per pixel. +auto + The EFI stub will choose the mode with the highest resolution (product + of horizontal and vertical resolution). If there are multiple modes + with the highest resolution, it will choose one with the highest color + depth. + Edgar Hucek <[email protected]>
drivers/firmware/efi/libstub/gop.c +83 -1
114 lines not on this page · raw message
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 19/33 efi/libstub/random: Align allocate size to EFI_ALLOC_ALIGN
In reply to Ard BiesheuvelThe EFI stub uses a per-architecture #define for the minimum base and size alignment of page allocations, which is set to 4 KB for all architecures except arm64, which uses 64 KB, to ensure that allocations can always be (un)mapped efficiently, regardless of the page size used by the kernel proper, which could be a kexec'ee
The API wrappers around page based allocations assume that this alignment is always taken into account, and so efi_free() will also round up its size argument to EFI_ALLOC_ALIGN.
Currently, efi_random_alloc() does not honour this alignment for the allocated size, and so freeing such an allocation may result in unrelated memory to be freed, potentially leading to issues after boot. So let's round up size in efi_random_alloc() as well.
--- drivers/firmware/efi/libstub/randomalloc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/firmware/efi/libstub/randomalloc.c +3 -1
@@ -74,6 +74,8 @@ efi_status_t efi_random_alloc(unsigned long size,if (align <EFI_ALLOC_ALIGN ) align =EFI_ALLOC_ALIGN ; + size =round_up (size,EFI_ALLOC_ALIGN ); +/* count the suitable slots in each memory map entry */ for (map_offset =0 ; map_offset < map_size; map_offset += desc_size) {efi_memory_desc_t *md = (void *)memory_map + map_offset;
@@ -109,7 +111,7 @@ efi_status_t efi_random_alloc(unsigned long size, } target =round_up (md->phys_addr, align) + target_slot * align; - pages =round_up (size,EFI_PAGE_SIZE ) /EFI_PAGE_SIZE ; + pages = size /EFI_PAGE_SIZE ; status =efi_bs_call (allocate_pages,EFI_ALLOCATE_ADDRESS ,EFI_LOADER_DATA , pages, &target);
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 20/33 efi/libstub/random: Increase random alloc granularity
In reply to Ard BiesheuvelThe implementation of efi_random_alloc() arbitrarily truncates the provided random seed to 16 bits, which limits the granularity of the randomly chosen allocation offset in memory. This is currently only an issue if the size of physical memory exceeds 128 GB, but going forward, we will reduce the allocation alignment to 64 KB, and this means we need to increase the granularity to ensure that the random memory allocations are distributed evenly.
We will need to switch to 64-bit arithmetic for the multiplication, but this does not result in 64-bit integer intrinsic calls on ARM or on i386.
--- drivers/firmware/efi/libstub/randomalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/libstub/randomalloc.c +1 -1
@@ -87,7 +87,7 @@ efi_status_t efi_random_alloc(unsigned long size, }/* find a random number between 0 and total_slots */ - target_slot = (total_slots * (u16 )random_seed) >>16 ; + target_slot = (total_slots * (u64)(random_seed &U32_MAX )) >>32 ;/* * target_slot is now a value in the range [0, total_slots), and so
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 22/33 efi/libstub/arm64: Simplify randomized loading of kernel image
In reply to Ard BiesheuvelThe KASLR code path in the arm64 version of the EFI stub incorporates some overly complicated logic to randomly allocate a region of the right
alignment: there is no need to randomize the placement of the kernel modulo 2 MiB separately from the placement of the 2 MiB aligned allocation itself - we can simply follow the same logic used by the non-randomized placement, which is to allocate at the correct alignment, and only take TEXT_OFFSET into account if it is not a round multiple of the alignment.
--- drivers/firmware/efi/libstub/arm64-stub.c | 32 ++++------------------- 1 file changed, 5 insertions(+), 27 deletions(-)
drivers/firmware/efi/libstub/arm64-stub.c +5 -27
@@ -52,7 +52,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, {efi_status_t status;unsigned long kernel_size, kernel_memsize =0 ; -u64 phys_seed =0 ; +u32 phys_seed =0 ;if (IS_ENABLED (CONFIG_RANDOMIZE_BASE )) {if (!nokaslr ()) {
@@ -74,36 +74,15 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, kernel_size = _edata - _text; kernel_memsize = kernel_size + (_end - _edata); + *reserve_size = kernel_memsize +TEXT_OFFSET % min_kimg_align;if (IS_ENABLED (CONFIG_RANDOMIZE_BASE ) && phys_seed !=0 ) { -/* -* Produce a displacement in the interval [0, MIN_KIMG_ALIGN) -* that doesn't violate this kernel's de-facto alignment -* constraints. -*/ -u32 mask = (MIN_KIMG_ALIGN -1 ) & ~(EFI_KIMG_ALIGN -1 ); -u32 offset = (phys_seed >>32 ) & mask; - -/* -* With CONFIG_RANDOMIZE_TEXT_OFFSET=y, TEXT_OFFSET may not -* be a multiple of EFI_KIMG_ALIGN, and we must ensure that -* we preserve the misalignment of 'offset' relative to -* EFI_KIMG_ALIGN so that statically allocated objects whose -* alignment exceeds PAGE_SIZE appear correctly aligned in -* memory. -*/ - offset |=TEXT_OFFSET %EFI_KIMG_ALIGN ; -/* * If KASLR is enabled, and we have some randomness available, * locate the kernel at a randomized offset in physical memory. */ - *reserve_size = kernel_memsize + offset; - status =efi_random_alloc (*reserve_size, -MIN_KIMG_ALIGN , reserve_addr, - (u32 )phys_seed); - - *image_addr = *reserve_addr + offset; + status =efi_random_alloc (*reserve_size, min_kimg_align, + reserve_addr, phys_seed); }else { status =EFI_OUT_OF_RESOURCES ; }
@@ -119,7 +98,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,return EFI_SUCCESS ; } - *reserve_size = kernel_memsize +TEXT_OFFSET % min_kimg_align; status =efi_low_alloc (*reserve_size, min_kimg_align, reserve_addr);
@@ -128,9 +106,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, *reserve_size =0 ;return status; } - *image_addr = *reserve_addr +TEXT_OFFSET % min_kimg_align; } + *image_addr = *reserve_addr +TEXT_OFFSET % min_kimg_align;memcpy ((void *)*image_addr, _text, kernel_size);return EFI_SUCCESS ;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 21/33 efi/libstub/arm64: Replace 'preferred' offset with alignment check
In reply to Ard BiesheuvelThe notion of a 'preferred' load offset for the kernel dates back to the times when the kernel's primary mapping overlapped with the linear region, and memory below it could not be used at all.
Today, the arm64 kernel does not really care where it is loaded in physical memory, as long as the alignment requirements are met, and so there is no point in unconditionally moving the kernel to a new location in memory at boot. Instead, we can
- check for a KASLR seed, and randomly reallocate the kernel if one is provided
- otherwise, check whether the alignment requirements are met for the current placement of the kernel, and just run it in place if they are
- finally, do an ordinary page allocation and reallocate the kernel to a suitably aligned buffer anywhere in memory.
By the same reasoning, there is no need to take TEXT_OFFSET into account if it is a round multiple of the minimum alignment, which is the usual case for relocatable kernels with TEXT_OFFSET randomization disabled. Otherwise, it suffices to use the relative misaligment of TEXT_OFFSET when reallocating the kernel.
--- drivers/firmware/efi/libstub/arm64-stub.c | 62 +++++++++-------------- 1 file changed, 25 insertions(+), 37 deletions(-)
drivers/firmware/efi/libstub/arm64-stub.c +25 -37
@@ -34,6 +34,15 @@ efi_status_t check_platform_features(void)return EFI_SUCCESS ; } +/* +* Relocatable kernels can fix up the misalignment with respect to +* MIN_KIMG_ALIGN, so they only require a minimum alignment of EFI_KIMG_ALIGN +* (which accounts for the alignment of statically allocated objects such as +* the swapper stack.) +*/ +static const u64 min_kimg_align =IS_ENABLED (CONFIG_RELOCATABLE ) ?EFI_KIMG_ALIGN + :MIN_KIMG_ALIGN ; + efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *image_size, unsigned long *reserve_addr,
@@ -43,7 +52,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, {efi_status_t status;unsigned long kernel_size, kernel_memsize =0 ; -unsigned long preferred_offset;u64 phys_seed =0 ;if (IS_ENABLED (CONFIG_RANDOMIZE_BASE )) {
@@ -61,14 +69,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } } -/* -* The preferred offset of the kernel Image is TEXT_OFFSET bytes beyond -* a 2 MB aligned base, which itself may be lower than dram_base, as -* long as the resulting offset equals or exceeds it. -*/ - preferred_offset =round_down (dram_base,MIN_KIMG_ALIGN ) +TEXT_OFFSET ; -if (preferred_offset < dram_base) - preferred_offset +=MIN_KIMG_ALIGN ; +if (image->image_base != _text) +pr_efi_err ("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n" ); kernel_size = _edata - _text; kernel_memsize = kernel_size + (_end - _edata);
@@ -103,46 +105,32 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, *image_addr = *reserve_addr + offset; }else { -/* -* Else, try a straight allocation at the preferred offset. -* This will work around the issue where, if dram_base == 0x0, -* efi_low_alloc() refuses to allocate at 0x0 (to prevent the -* address of the allocation to be mistaken for a FAIL return -* value or a NULL pointer). It will also ensure that, on -* platforms where the [dram_base, dram_base + TEXT_OFFSET) -* interval is partially occupied by the firmware (like on APM -* Mustang), we can still place the kernel at the address -* 'dram_base + TEXT_OFFSET'. -*/ - *image_addr = (unsigned long )_text; -if (*image_addr == preferred_offset) -return EFI_SUCCESS ; - - *image_addr = *reserve_addr = preferred_offset; - *reserve_size =round_up (kernel_memsize,EFI_ALLOC_ALIGN ); - - status =efi_bs_call (allocate_pages,EFI_ALLOCATE_ADDRESS , -EFI_LOADER_DATA , - *reserve_size /EFI_PAGE_SIZE , - (efi_physical_addr_t *)reserve_addr); + status =EFI_OUT_OF_RESOURCES ; }if (status !=EFI_SUCCESS ) { - *reserve_size = kernel_memsize +TEXT_OFFSET ; +if (IS_ALIGNED ((u64 )_text -TEXT_OFFSET , min_kimg_align)) { +/* +* Just execute from wherever we were loaded by the +* UEFI PE/COFF loader if the alignment is suitable. +*/ + *image_addr = (u64 )_text; + *reserve_size =0 ; +return EFI_SUCCESS ; + } + + *reserve_size = kernel_memsize +TEXT_OFFSET % min_kimg_align; status =efi_low_alloc (*reserve_size, -MIN_KIMG_ALIGN , reserve_addr); + min_kimg_align, reserve_addr);if (status !=EFI_SUCCESS ) {pr_efi_err ("Failed to relocate kernel\n" ); *reserve_size =0 ;return status; } - *image_addr = *reserve_addr +TEXT_OFFSET ; + *image_addr = *reserve_addr +TEXT_OFFSET % min_kimg_align; } -if (image->image_base != _text) -pr_efi_err ("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n" ); -memcpy ((void *)*image_addr, _text, kernel_size);return EFI_SUCCESS ;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 24/33 efi/libstub/arm64: Switch to ordinary page allocator for kernel image
In reply to Ard BiesheuvelIt is no longer necessary to locate the kernel as low as possible in physical memory, and so we can switch from efi_low_alloc() [which is a rather nasty concoction on top of GetMemoryMap()] to a new helper called efi_allocate_pages_aligned(), which simply rounds up the size to account for the alignment, and frees the misaligned pages again.
So considering that the kernel can live anywhere in the physical address space, as long as its alignment requirements are met, let's switch to efi_allocate_pages_aligned() to allocate the pages.
--- drivers/firmware/efi/libstub/arm64-stub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/firmware/efi/libstub/arm64-stub.c +2 -2
@@ -98,8 +98,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,return EFI_SUCCESS ; } - status =efi_low_alloc (*reserve_size, - min_kimg_align, reserve_addr); + status =efi_allocate_pages_aligned (*reserve_size, reserve_addr, +ULONG_MAX , min_kimg_align);if (status !=EFI_SUCCESS ) {pr_efi_err ("Failed to relocate kernel\n" );
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 27/33 efi/x86: Remove __efistub_global and add relocation check
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Instead of using __efistub_global to force variables into the .data section, leave them in the .bss but pull the EFI stub's .bss section into .data in the linker script for the compressed kernel.
Add relocation checking for x86 as well to catch non-PC-relative relocations that require runtime processing, since the EFI stub does not do any runtime relocation processing.
This will catch, for example, data relocations created by static initializers of pointers.
--- arch/x86/boot/compressed/vmlinux.lds.S | 1 + drivers/firmware/efi/libstub/Makefile | 32 +++++++++++++++++--------- drivers/firmware/efi/libstub/efistub.h | 4 ---- 3 files changed, 22 insertions(+), 15 deletions(-)
arch/x86/boot/compressed/vmlinux.lds.S +1 -0
@@ -52,6 +52,7 @@ SECTIONS _data = . ; *(.data) *(.data.*) + *(.bss.efistub) _edata = . ; } . = ALIGN(L1_CACHE_BYTES);
drivers/firmware/efi/libstub/Makefile +21 -11
@@ -60,6 +60,25 @@ lib-$(CONFIG_X86) += x86-stub.o CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) +# +# For x86, bootloaders like systemd-boot or grub-efi do not zero-initialize the +# .bss section, so the .bss section of the EFI stub needs to be included in the +# .data section of the compressed kernel to ensure initialization. Rename the +# .bss section here so it's easy to pick out in the linker script. +# +STUBCOPY_FLAGS-$(CONFIG_X86) += --rename-section .bss=.bss.efistub,load,alloc +STUBCOPY_RELOC-$(CONFIG_X86_32) := R_386_32 +STUBCOPY_RELOC-$(CONFIG_X86_64) := R_X86_64_64 + +# +# ARM discards the .data section because it disallows r/w data in the +# decompressor. So move our .data to .data.efistub and .bss to .bss.efistub, +# which are preserved explicitly by the decompressor linker script. +# +STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub \ + --rename-section .bss=.bss.efistub,load,alloc +STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS + # # arm64 puts the stub in the kernel proper, which will unnecessarily retain all # code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
@@ -74,8 +93,8 @@ CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # a verification pass to see if any absolute relocations exist in any of the # object files. # -extra-$(CONFIG_EFI_GENERIC_STUB) := $(lib-y) -lib-$(CONFIG_EFI_GENERIC_STUB) := $(patsubst %.o,%.stub.o,$(lib-y)) +extra-y := $(lib-y) +lib-y := $(patsubst %.o,%.stub.o,$(lib-y)) STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \ --prefix-symbols=__efistub_
@@ -98,12 +117,3 @@ quiet_cmd_stubcopy = STUBCPY $@ /bin/false; \ fi; \ $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@ - -# -# ARM discards the .data section because it disallows r/w data in the -# decompressor. So move our .data to .data.efistub and .bss to .bss.efistub, -# which are preserved explicitly by the decompressor linker script. -# -STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub \ - --rename-section .bss=.bss.efistub,load,alloc -STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS
drivers/firmware/efi/libstub/efistub.h +0 -4
@@ -25,11 +25,7 @@#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE#endif -#if defined(CONFIG_X86 ) -#define __efistub_global __section(.data) -#else #define __efistub_global -#endif extern bool __pure nochunk (void );extern bool __pure nokaslr (void );
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 28/33 efi: Kill __efistub_global
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Now that both arm and x86 are using the linker script to place the EFI stub's global variables in the correct section, remove __efistub_global.
--- drivers/firmware/efi/libstub/efi-stub-helper.c | 15 +++++++-------- drivers/firmware/efi/libstub/efi-stub.c | 4 ++-- drivers/firmware/efi/libstub/efistub.h | 2 -- drivers/firmware/efi/libstub/gop.c | 2 +- drivers/firmware/efi/libstub/x86-stub.c | 2 +- 5 files changed, 11 insertions(+), 14 deletions(-)
drivers/firmware/efi/libstub/efi-stub-helper.c +7 -8
@@ -12,14 +12,13 @@#include "efistub.h" -static bool __efistub_global efi_nochunk; -static bool __efistub_global efi_nokaslr; -static bool __efistub_global efi_noinitrd; -static bool __efistub_global efi_quiet; -static bool __efistub_global efi_novamap; -static bool __efistub_global efi_nosoftreserve; -static bool __efistub_global efi_disable_pci_dma = -IS_ENABLED (CONFIG_EFI_DISABLE_PCI_DMA ); +static bool efi_nochunk; +static bool efi_nokaslr; +static bool efi_noinitrd; +static bool efi_quiet; +static bool efi_novamap; +static bool efi_nosoftreserve; +static bool efi_disable_pci_dma =IS_ENABLED (CONFIG_EFI_DISABLE_PCI_DMA );bool __pure nochunk (void ) {
drivers/firmware/efi/libstub/efi-stub.c +2 -2
@@ -36,9 +36,9 @@#endif static u64 virtmap_base =EFI_RT_VIRTUAL_BASE ; -static bool __efistub_global flat_va_mapping; +static bool flat_va_mapping; -static efi_system_table_t *__efistub_global sys_table; +static efi_system_table_t *sys_table;__pure efi_system_table_t *efi_system_table (void ) {
drivers/firmware/efi/libstub/efistub.h +0 -2
@@ -25,8 +25,6 @@#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE#endif -#define __efistub_global -extern bool __pure nochunk (void );extern bool __pure nokaslr (void );extern bool __pure noinitrd (void );
drivers/firmware/efi/libstub/gop.c +1 -1
@@ -32,7 +32,7 @@ static struct {u8 depth; } res; }; -}cmdline __efistub_global = { .option =EFI_CMDLINE_NONE }; +} cmdline = { .option = EFI_CMDLINE_NONE };static bool parse_modenum (char *option,char **next) {
drivers/firmware/efi/libstub/x86-stub.c +1 -1
@@ -20,7 +20,7 @@/* Maximum physical address for 64-bit kernel with 4-level paging */ #define MAXMEM_X86_64_4LEVEL (1ull << 46) -static efi_system_table_t *sys_table __efistub_global; +static efi_system_table_t *sys_table;extern const bool efi_is64;extern u32 image_offset;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 30/33 efi/libstub: Drop __pure getters for EFI stub options
In reply to Ard BiesheuvelThe practice of using __pure getter functions to access global variables in the EFI stub dates back to the time when we had to carefully prevent GOT entries from being emitted, because we could not rely on the toolchain to do this for us.
Today, we use the hidden visibility pragma for all EFI stub source files, which now all live in the same subdirectory, and we apply a sanity check on the objects, so we can get rid of these getter functions and simply refer to global data objects directly.
So switch over the remaining boolean variables carrying options set on the kernel command line.
--- drivers/firmware/efi/libstub/arm64-stub.c | 2 +- .../firmware/efi/libstub/efi-stub-helper.c | 31 ++++--------------- drivers/firmware/efi/libstub/efi-stub.c | 6 ++-- drivers/firmware/efi/libstub/efistub.h | 12 +++---- drivers/firmware/efi/libstub/fdt.c | 2 +- drivers/firmware/efi/libstub/file.c | 2 +- drivers/firmware/efi/libstub/x86-stub.c | 4 +-- 7 files changed, 20 insertions(+), 39 deletions(-)
drivers/firmware/efi/libstub/arm64-stub.c +1 -1
@@ -55,7 +55,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,u32 phys_seed =0 ;if (IS_ENABLED (CONFIG_RANDOMIZE_BASE )) { -if (!nokaslr ()) { +if (!efi_nokaslr) { status =efi_get_random_bytes (sizeof (phys_seed), (u8 *)&phys_seed);if (status ==EFI_NOT_FOUND ) {
drivers/firmware/efi/libstub/efi-stub-helper.c +6 -25
@@ -12,34 +12,15 @@#include "efistub.h" -static bool efi_nochunk; -static bool efi_nokaslr; -static bool efi_noinitrd; -static bool efi_quiet; -static bool efi_novamap; +bool efi_nochunk; +bool efi_nokaslr; +bool efi_noinitrd; +bool efi_quiet; +bool efi_novamap; +static bool efi_nosoftreserve;static bool efi_disable_pci_dma =IS_ENABLED (CONFIG_EFI_DISABLE_PCI_DMA ); -bool __pure nochunk (void ) -{ -return efi_nochunk; -} -bool __pure nokaslr (void ) -{ -return efi_nokaslr; -} -bool __pure noinitrd (void ) -{ -return efi_noinitrd; -} -bool __pure is_quiet (void ) -{ -return efi_quiet; -} -bool __pure novamap (void ) -{ -return efi_novamap; -}bool __pure __efi_soft_reserve_enabled (void ) {return !efi_nosoftreserve;
drivers/firmware/efi/libstub/efi-stub.c +3 -3
@@ -263,7 +263,7 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)if (!fdt_addr)pr_efi ("Generating empty DTB\n" ); -if (!noinitrd ()) { +if (!efi_noinitrd) { max_addr =efi_get_max_initrd_addr (dram_base, image_addr); status =efi_load_initrd_dev_path (&initrd_addr, &initrd_size, max_addr);
@@ -294,7 +294,7 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg) EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);/* hibernation expects the runtime regions to stay in the same place */ -if (!IS_ENABLED (CONFIG_HIBERNATION ) && !nokaslr () && !flat_va_mapping) { +if (!IS_ENABLED (CONFIG_HIBERNATION ) && !efi_nokaslr && !flat_va_mapping) {/* * Randomize the base of the UEFI runtime services region. * Preserve the 2 MB alignment of the region by taking a
@@ -367,7 +367,7 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, size = in->num_pages *EFI_PAGE_SIZE ; in->virt_addr = in->phys_addr; -if (novamap ()) { +if (efi_novamap) {continue ; }
drivers/firmware/efi/libstub/efistub.h +6 -6
@@ -25,11 +25,11 @@#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE#endif -extern bool __pure nochunk (void ); -extern bool __pure nokaslr (void ); -extern bool __pure noinitrd (void ); -extern bool __pure is_quiet (void ); -extern bool __pure novamap (void ); +extern bool efi_nochunk; +extern bool efi_nokaslr; +extern bool efi_noinitrd; +extern bool efi_quiet; +extern bool efi_novamap;extern const efi_system_table_t *efi_system_table;
@@ -50,7 +50,7 @@ extern const efi_system_table_t *efi_system_table;#endif #define pr_efi (msg) do { \ - if (!is_quiet()) efi_printk("EFI stub: "msg); \ + if (!efi_quiet) efi_printk("EFI stub: "msg); \ } while (0)#define pr_efi_err (msg) efi_printk("EFI stub: ERROR: "msg)
drivers/firmware/efi/libstub/fdt.c +1 -1
@@ -310,7 +310,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,if (status ==EFI_SUCCESS ) {efi_set_virtual_address_map_t *svam; -if (novamap ()) +if (efi_novamap)return EFI_SUCCESS ;/* Install the new virtual address map */
drivers/firmware/efi/libstub/file.c +1 -1
@@ -142,7 +142,7 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,if (!load_addr || !load_size)return EFI_INVALID_PARAMETER ; -if (IS_ENABLED (CONFIG_X86 ) && !nochunk ()) +if (IS_ENABLED (CONFIG_X86 ) && !efi_nochunk) efi_chunk_size =EFI_READ_CHUNK_SIZE ; alloc_addr = alloc_size =0 ;
drivers/firmware/efi/libstub/x86-stub.c +2 -2
@@ -427,7 +427,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,if (status !=EFI_SUCCESS ) goto fail2; -if (!noinitrd ()) { +if (!efi_noinitrd) { status = efi_load_initrd(image, &ramdisk_addr, &ramdisk_size, hdr->initrd_addr_max,
@@ -787,7 +787,7 @@ unsigned long efi_main(efi_handle_t handle,* permit an initrd loaded from the LINUX_EFI_INITRD_MEDIA_GUID device * path to supersede it. */ -if (!noinitrd ()) { +if (!efi_noinitrd) {unsigned long addr, size; status =efi_load_initrd_dev_path (&addr, &size,ULONG_MAX );
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 31/33 efi/libstub/x86: Avoid getter function for efi_is64
In reply to Ard BiesheuvelWe no longer need to take special care when using global variables in the EFI stub, so switch to a simple symbol reference for efi_is64.
--- arch/x86/include/asm/efi.h | 11 ++++++++--- drivers/firmware/efi/libstub/x86-stub.c | 8 -------- 2 files changed, 8 insertions(+), 11 deletions(-)
arch/x86/include/asm/efi.h +8 -3
@@ -225,14 +225,19 @@ efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size,/* arch specific definitions used by the stub code */ -__attribute_const__ bool efi_is_64bit(void); +extern const bool efi_is64; + +static inline bool efi_is_64bit (void ) +{ +if (IS_ENABLED (CONFIG_EFI_MIXED )) +return efi_is64; +return IS_ENABLED (CONFIG_X86_64 ); +}static inline bool efi_is_native (void ) {if (!IS_ENABLED (CONFIG_X86_64 ))return true; -if (!IS_ENABLED (CONFIG_EFI_MIXED )) -return true;return efi_is_64bit (); }
drivers/firmware/efi/libstub/x86-stub.c +0 -8
@@ -21,16 +21,8 @@#define MAXMEM_X86_64_4LEVEL (1ull << 46)const efi_system_table_t *efi_system_table; -extern const bool efi_is64;extern u32 image_offset; -__attribute_const__ bool efi_is_64bit(void) -{ -if (IS_ENABLED (CONFIG_EFI_MIXED )) -return efi_is64; -return IS_ENABLED (CONFIG_X86_64 ); -} -static efi_status_t preserve_pci_rom_image (efi_pci_io_protocol_t *pci,struct pci_setup_rom **__rom) {
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 32/33 efi: Clean up config table description arrays
In reply to Ard BiesheuvelIncrease legibility by adding whitespace to the efi_config_table_type_t arrays that describe which EFI config tables we look for when going over the firmware provided list. While at it, replace the 'name' char pointer with a char array, which is more space efficient on relocatable 64-bit kernels, as it avoids a 8 byte pointer and the associated relocation data (24 bytes when using RELA format)
--- arch/ia64/kernel/efi.c | 12 ++++++------ arch/x86/platform/efi/efi.c | 8 ++++---- drivers/firmware/efi/arm-init.c | 4 ++-- drivers/firmware/efi/efi.c | 28 ++++++++++++++-------------- include/linux/efi.h | 2 +- 5 files changed, 27 insertions(+), 27 deletions(-)
arch/ia64/kernel/efi.c +6 -6
@@ -57,12 +57,12 @@ unsigned long hcdp_phys = EFI_INVALID_TABLE_ADDR;unsigned long sal_systab_phys =EFI_INVALID_TABLE_ADDR ;static const efi_config_table_type_t arch_tables[]__initconst = { - {ESI_TABLE_GUID ,"ESI" , &esi_phys}, - {HCDP_TABLE_GUID ,"HCDP" , &hcdp_phys}, - {MPS_TABLE_GUID ,"MPS" , &mps_phys}, - {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID ,"PALO" , &palo_phys}, - {SAL_SYSTEM_TABLE_GUID ,"SALsystab" , &sal_systab_phys}, - {NULL_GUID ,NULL ,0 }, + {ESI_TABLE_GUID , &esi_phys,"ESI" }, + {HCDP_TABLE_GUID , &hcdp_phys,"HCDP" }, + {MPS_TABLE_GUID , &mps_phys,"MPS" }, + {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID , &palo_phys,"PALO" }, + {SAL_SYSTEM_TABLE_GUID , &sal_systab_phys,"SALsystab" }, + {}, };extern efi_status_t efi_call_phys (void *, ...);
arch/x86/platform/efi/efi.c +4 -4
@@ -62,12 +62,12 @@ static unsigned long efi_runtime, efi_nr_tables;unsigned long efi_fw_vendor, efi_config_table;static const efi_config_table_type_t arch_tables[]__initconst = { - {EFI_PROPERTIES_TABLE_GUID ,"PROP" , &prop_phys}, - {UGA_IO_PROTOCOL_GUID ,"UGA" , &uga_phys}, + {EFI_PROPERTIES_TABLE_GUID , &prop_phys,"PROP" }, + {UGA_IO_PROTOCOL_GUID , &uga_phys,"UGA" }, #ifdef CONFIG_X86_UV - {UV_SYSTEM_TABLE_GUID ,"UVsystab" , &uv_systab_phys}, + {UV_SYSTEM_TABLE_GUID , &uv_systab_phys,"UVsystab" }, #endif - {NULL_GUID ,NULL ,NULL }, + {}, };static const unsigned long *const efi_tables[] = {
drivers/firmware/efi/arm-init.c +2 -2
@@ -54,8 +54,8 @@ static phys_addr_t __init efi_to_phys(unsigned long addr)static __initdata unsigned long screen_info_table =EFI_INVALID_TABLE_ADDR ;static const efi_config_table_type_t arch_tables[]__initconst = { - {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID ,NULL , &screen_info_table}, - {NULL_GUID ,NULL ,NULL } + {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID , &screen_info_table}, + {} };static void __init init_screen_info (void )
drivers/firmware/efi/efi.c +14 -14
@@ -502,21 +502,21 @@ void __init efi_mem_reserve(phys_addr_t addr, u64 size) }static const efi_config_table_type_t common_tables[]__initconst = { - {ACPI_20_TABLE_GUID ,"ACPI 2.0" , &efi.acpi20}, - {ACPI_TABLE_GUID ,"ACPI" , &efi.acpi}, - {SMBIOS_TABLE_GUID ,"SMBIOS" , &efi.smbios}, - {SMBIOS3_TABLE_GUID ,"SMBIOS 3.0" , &efi.smbios3}, - {EFI_SYSTEM_RESOURCE_TABLE_GUID ,"ESRT" , &efi.esrt}, - {EFI_MEMORY_ATTRIBUTES_TABLE_GUID ,"MEMATTR" , &efi_mem_attr_table}, - {LINUX_EFI_RANDOM_SEED_TABLE_GUID ,"RNG" , &efi_rng_seed}, - {LINUX_EFI_TPM_EVENT_LOG_GUID ,"TPMEventLog" , &efi.tpm_log}, - {LINUX_EFI_TPM_FINAL_LOG_GUID ,"TPMFinalLog" , &efi.tpm_final_log}, - {LINUX_EFI_MEMRESERVE_TABLE_GUID ,"MEMRESERVE" , &mem_reserve}, - {EFI_RT_PROPERTIES_TABLE_GUID ,"RTPROP" , &rt_prop}, + {ACPI_20_TABLE_GUID , &efi.acpi20,"ACPI 2.0" }, + {ACPI_TABLE_GUID , &efi.acpi,"ACPI" }, + {SMBIOS_TABLE_GUID , &efi.smbios,"SMBIOS" }, + {SMBIOS3_TABLE_GUID , &efi.smbios3,"SMBIOS 3.0" }, + {EFI_SYSTEM_RESOURCE_TABLE_GUID , &efi.esrt,"ESRT" }, + {EFI_MEMORY_ATTRIBUTES_TABLE_GUID , &efi_mem_attr_table,"MEMATTR" }, + {LINUX_EFI_RANDOM_SEED_TABLE_GUID , &efi_rng_seed,"RNG" }, + {LINUX_EFI_TPM_EVENT_LOG_GUID , &efi.tpm_log,"TPMEventLog" }, + {LINUX_EFI_TPM_FINAL_LOG_GUID , &efi.tpm_final_log,"TPMFinalLog" }, + {LINUX_EFI_MEMRESERVE_TABLE_GUID , &mem_reserve,"MEMRESERVE" }, + {EFI_RT_PROPERTIES_TABLE_GUID , &rt_prop,"RTPROP" }, #ifdef CONFIG_EFI_RCI2_TABLE - {DELLEMC_EFI_RCI2_TABLE_GUID ,NULL , &rci2_table_phys}, + {DELLEMC_EFI_RCI2_TABLE_GUID , &rci2_table_phys }, #endif - {NULL_GUID ,NULL ,NULL }, + {}, }; static __init int match_config_table(const efi_guid_t *guid,
@@ -529,7 +529,7 @@ static __init int match_config_table(const efi_guid_t *guid,for (i =0 ;efi_guidcmp (table_types[i].guid,NULL_GUID ); i++) {if (!efi_guidcmp (*guid, table_types[i].guid)) { *(table_types[i].ptr) = table; -if (table_types[i].name) +if (table_types[i].name[0 ])pr_cont (" %s=0x%lx " , table_types[i].name, table);return 1 ;
include/linux/efi.h +1 -1
@@ -379,8 +379,8 @@ typedef union {typedef struct {efi_guid_t guid; -const char *name;unsigned long *ptr; +const char name[16 ]; }efi_config_table_type_t ;#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 33/33 efi: Move arch_tables check to caller
In reply to Ard BiesheuvelInstead of making match_config_table() test its table_types pointer for NULL-ness, omit the call entirely if no arch_tables pointer was provided to efi_config_parse_tables().
--- drivers/firmware/efi/efi.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
drivers/firmware/efi/efi.c +8 -10
@@ -525,15 +525,13 @@ static __init int match_config_table(const efi_guid_t *guid, {int i; -if (table_types) { -for (i =0 ;efi_guidcmp (table_types[i].guid,NULL_GUID ); i++) { -if (!efi_guidcmp (*guid, table_types[i].guid)) { - *(table_types[i].ptr) = table; -if (table_types[i].name[0 ]) -pr_cont (" %s=0x%lx " , - table_types[i].name, table); -return 1 ; - } +for (i =0 ;efi_guidcmp (table_types[i].guid,NULL_GUID ); i++) { +if (!efi_guidcmp (*guid, table_types[i].guid)) { + *(table_types[i].ptr) = table; +if (table_types[i].name[0 ]) +pr_cont ("%s=0x%lx " , + table_types[i].name, table); +return 1 ; } }
@@ -570,7 +568,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables, table = tbl32[i].table; } -if (!match_config_table (guid, table, common_tables)) +if (!match_config_table (guid, table, common_tables) && arch_tables)match_config_table (guid, table, arch_tables); }pr_cont ("\n" );
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 29/33 efi/libstub: Drop __pure getter for efi_system_table
In reply to Ard BiesheuvelThe practice of using __pure getter functions to access global variables in the EFI stub dates back to the time when we had to carefully prevent GOT entries from being emitted, because we could not rely on the toolchain to do this for us.
Today, we use the hidden visibility pragma for all EFI stub source files, which now all live in the same subdirectory, and we apply a sanity check on the objects, so we can get rid of these getter functions and simply refer to global data objects directly.
Start with efi_system_table(), and convert it into a global variable. While at it, make it a pointer-to-const, because we can.
--- arch/x86/include/asm/efi.h | 14 ++++++----- .../firmware/efi/libstub/efi-stub-helper.c | 6 ++--- drivers/firmware/efi/libstub/efi-stub.c | 13 ++++------- drivers/firmware/efi/libstub/efistub.h | 6 ++--- drivers/firmware/efi/libstub/fdt.c | 6 ++--- drivers/firmware/efi/libstub/x86-stub.c | 23 ++++++++----------- 6 files changed, 30 insertions(+), 38 deletions(-)
arch/x86/include/asm/efi.h +8 -6
@@ -339,15 +339,17 @@ static inline u32 efi64_convert_status(efi_status_t status)#define efi_bs_call (func, ...) \ (efi_is_native() \ - ? efi_system_table()->boottime->func(__VA_ARGS__) \ - : __efi64_thunk_map(efi_table_attr(efi_system_table(), \ - boottime), func, __VA_ARGS__)) + ? efi_system_table->boottime->func(__VA_ARGS__) \ + : __efi64_thunk_map(efi_table_attr(efi_system_table, \ + boottime), \ + func, __VA_ARGS__))#define efi_rt_call (func, ...) \ (efi_is_native() \ - ? efi_system_table()->runtime->func(__VA_ARGS__) \ - : __efi64_thunk_map(efi_table_attr(efi_system_table(), \ - runtime), func, __VA_ARGS__)) + ? efi_system_table->runtime->func(__VA_ARGS__) \ + : __efi64_thunk_map(efi_table_attr(efi_system_table, \ + runtime), \ + func, __VA_ARGS__))extern bool efi_reboot_required (void );extern bool efi_is_table_address (unsigned long phys_addr);
drivers/firmware/efi/libstub/efi-stub-helper.c +3 -3
@@ -287,8 +287,8 @@ efi_status_t efi_exit_boot_services(void *handle,void *get_efi_config_table (efi_guid_t guid) { -unsigned long tables =efi_table_attr (efi_system_table (), tables); -int nr_tables =efi_table_attr (efi_system_table (), nr_tables); +unsigned long tables =efi_table_attr (efi_system_table, tables); +int nr_tables =efi_table_attr (efi_system_table, nr_tables);int i;for (i =0 ; i < nr_tables; i++) {
@@ -305,7 +305,7 @@ void *get_efi_config_table(efi_guid_t guid)void efi_char16_printk (efi_char16_t *str) { -efi_call_proto (efi_table_attr (efi_system_table (), con_out), +efi_call_proto (efi_table_attr (efi_system_table, con_out), output_string, str); }
drivers/firmware/efi/libstub/efi-stub.c +4 -9
@@ -38,12 +38,7 @@static u64 virtmap_base =EFI_RT_VIRTUAL_BASE ;static bool flat_va_mapping; -static efi_system_table_t *sys_table; - -__pure efi_system_table_t *efi_system_table (void ) -{ -return sys_table; -} +const efi_system_table_t *efi_system_table;static struct screen_info *setup_graphics (void ) {
@@ -167,10 +162,10 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)efi_properties_table_t *prop_tbl;unsigned long max_addr; - sys_table = sys_table_arg; + efi_system_table = sys_table_arg;/* Check if we were booted by the EFI firmware */ -if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) { +if (efi_system_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) { status =EFI_INVALID_PARAMETER ; goto fail; }
@@ -184,7 +179,7 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)* information about the running image, such as size and the command * line. */ - status = sys_table->boottime->handle_protocol (handle, + status = efi_system_table->boottime->handle_protocol (handle, &loaded_image_proto, (void *)&image);if (status !=EFI_SUCCESS ) {pr_efi_err ("Failed to get loaded image protocol\n" );
drivers/firmware/efi/libstub/efistub.h +3 -3
@@ -31,13 +31,13 @@ extern bool __pure noinitrd(void);extern bool __pure is_quiet (void );extern bool __pure novamap (void ); -extern __pure efi_system_table_t *efi_system_table (void ); +extern const efi_system_table_t *efi_system_table;#ifndef efi_bs_call -#define efi_bs_call (func, ...) efi_system_table()->boottime->func(__VA_ARGS__) +#define efi_bs_call (func, ...) efi_system_table->boottime->func(__VA_ARGS__)#endif #ifndef efi_rt_call -#define efi_rt_call (func, ...) efi_system_table()->runtime->func(__VA_ARGS__) +#define efi_rt_call (func, ...) efi_system_table->runtime->func(__VA_ARGS__)#endif #ifndef efi_is_native#define efi_is_native () (true)
drivers/firmware/efi/libstub/fdt.c +3 -3
@@ -110,7 +110,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,/* Add FDT entries for EFI runtime services in chosen node. */ node =fdt_subnode_offset (fdt,0 ,"chosen" ); - fdt_val64 =cpu_to_fdt64 ((u64 )(unsigned long )efi_system_table ()); + fdt_val64 =cpu_to_fdt64 ((u64 )(unsigned long )efi_system_table); status =fdt_setprop_var (fdt, node,"linux,uefi-system-table" , fdt_val64);if (status)
@@ -314,7 +314,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,return EFI_SUCCESS ;/* Install the new virtual address map */ - svam =efi_system_table ()->runtime->set_virtual_address_map; + svam = efi_system_table->runtime->set_virtual_address_map; status =svam (runtime_entry_count * desc_size, desc_size, desc_ver, runtime_map);
@@ -348,7 +348,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,efi_free (MAX_FDT_SIZE , *new_fdt_addr); fail: -efi_system_table ()->boottime->free_pool (runtime_map); + efi_system_table->boottime->free_pool (runtime_map);return EFI_LOAD_ERROR ; }
drivers/firmware/efi/libstub/x86-stub.c +9 -14
@@ -20,15 +20,10 @@/* Maximum physical address for 64-bit kernel with 4-level paging */ #define MAXMEM_X86_64_4LEVEL (1ull << 46) -static efi_system_table_t *sys_table; +const efi_system_table_t *efi_system_table;extern const bool efi_is64;extern u32 image_offset; -__pure efi_system_table_t *efi_system_table (void ) -{ -return sys_table; -} - __attribute_const__ bool efi_is_64bit(void) {if (IS_ENABLED (CONFIG_EFI_MIXED ))
@@ -227,7 +222,7 @@ static const efi_char16_t apple[] = L"Apple";static void setup_quirks (struct boot_params *boot_params) {efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long ) -efi_table_attr (efi_system_table (), fw_vendor); +efi_table_attr (efi_system_table, fw_vendor);if (!memcmp (fw_vendor, apple,sizeof (apple))) {if (IS_ENABLED (CONFIG_APPLE_PROPERTIES ))
@@ -377,10 +372,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,unsigned long ramdisk_addr;unsigned long ramdisk_size; - sys_table = sys_table_arg; + efi_system_table = sys_table_arg;/* Check if we were booted by the EFI firmware */ -if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) +if (efi_system_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE )efi_exit (handle,EFI_INVALID_PARAMETER ); status =efi_bs_call (handle_protocol, handle, &proto, (void **)&image);
@@ -446,7 +441,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, } } -efi_stub_entry (handle, sys_table, boot_params); +efi_stub_entry (handle, sys_table_arg, boot_params);/* not reached */ fail2:
@@ -651,14 +646,14 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, : EFI32_LOADER_SIGNATURE;memcpy (&p->efi->efi_loader_signature, signature,sizeof (__u32)); - p->efi->efi_systab = (unsigned long )efi_system_table (); + p->efi->efi_systab = (unsigned long )efi_system_table; p->efi->efi_memdesc_size = *map->desc_size; p->efi->efi_memdesc_version = *map->desc_ver; p->efi->efi_memmap = (unsigned long )*map->map; p->efi->efi_memmap_size = *map->map_size;#ifdef CONFIG_X86_64 - p->efi->efi_systab_hi = (unsigned long )efi_system_table () >>32 ; + p->efi->efi_systab_hi = (unsigned long )efi_system_table >>32 ; p->efi->efi_memmap_hi = (unsigned long )*map->map >>32 ;#endif
@@ -719,10 +714,10 @@ unsigned long efi_main(efi_handle_t handle,efi_status_t status;unsigned long cmdline_paddr; - sys_table = sys_table_arg; + efi_system_table = sys_table_arg;/* Check if we were booted by the EFI firmware */ -if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) +if (efi_system_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE )efi_exit (handle,EFI_INVALID_PARAMETER );/*
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 25/33 efi/libstub: Move efi_relocate_kernel() into separate source file
In reply to Ard BiesheuvelMove efi_relocate_kernel() into a separate source file, so that it only gets pulled into builds for architectures that use it. Since efi_relocate_kernel() is the only user of efi_low_alloc(), let's move that over as well.
--- drivers/firmware/efi/libstub/Makefile | 2 +- drivers/firmware/efi/libstub/efistub.h | 15 -- drivers/firmware/efi/libstub/mem.c | 168 ----------------------- drivers/firmware/efi/libstub/relocate.c | 174 ++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 184 deletions(-) create mode 100644 drivers/firmware/efi/libstub/relocate.c
drivers/firmware/efi/libstub/Makefile +1 -1
@@ -43,7 +43,7 @@ KCOV_INSTRUMENT := n lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ file.o mem.o random.o randomalloc.o pci.o \ skip_spaces.o lib-cmdline.o lib-ctype.o \ - alignedmem.o + alignedmem.o relocate.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
drivers/firmware/efi/libstub/efistub.h +0 -15
@@ -639,21 +639,6 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len,efi_status_t efi_get_memory_map (struct efi_boot_memmap *map); -efi_status_t efi_low_alloc_above (unsigned long size,unsigned long align, -unsigned long *addr,unsigned long min); - -static inline -efi_status_t efi_low_alloc (unsigned long size,unsigned long align, -unsigned long *addr) -{ -/* -* Don't allocate at 0x0. It will confuse code that -* checks pointers against NULL. Skip the first 8 -* bytes so we start at a nice even number. -*/ -return efi_low_alloc_above (size, align, addr,0x8 ); -} -efi_status_t efi_allocate_pages (unsigned long size,unsigned long *addr,unsigned long max);
drivers/firmware/efi/libstub/mem.c +0 -168
177 lines not on this page · raw message
drivers/firmware/efi/libstub/relocate.c new file +174 -0
174 lines not on this page · raw message
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 26/33 efi/arm: Remove __efistub_global annotation
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Instead of using __efistub_global to force variables into the .data section, leave them in the .bss but pull the EFI stub's .bss section into .data in the linker script for the compressed kernel.
--- arch/arm/boot/compressed/vmlinux.lds.S | 2 +- drivers/firmware/efi/libstub/Makefile | 7 ++++--- drivers/firmware/efi/libstub/efistub.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-)
arch/arm/boot/compressed/vmlinux.lds.S +1 -1
@@ -78,7 +78,7 @@ SECTIONS * The EFI stub always executes from RAM, and runs strictly before the * decompressor, so we can make an exception for its r/w data, and keep it */ - *(.data.efistub) + *(.data.efistub .bss.efistub) __pecoff_data_end = .; /*
drivers/firmware/efi/libstub/Makefile +4 -3
@@ -101,8 +101,9 @@ quiet_cmd_stubcopy = STUBCPY $@ # # ARM discards the .data section because it disallows r/w data in the -# decompressor. So move our .data to .data.efistub, which is preserved -# explicitly by the decompressor linker script. +# decompressor. So move our .data to .data.efistub and .bss to .bss.efistub, +# which are preserved explicitly by the decompressor linker script. # -STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub +STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub \ + --rename-section .bss=.bss.efistub,load,alloc STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS
drivers/firmware/efi/libstub/efistub.h +1 -1
@@ -25,7 +25,7 @@#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE#endif -#if defined(CONFIG_ARM ) || defined(CONFIG_X86 ) +#if defined(CONFIG_X86 )#define __efistub_global __section(.data)#else #define __efistub_global
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 23/33 efi/libstub: Add API function to allocate aligned memory
In reply to Ard BiesheuvelBreak out the code to create an aligned page allocation from mem.c and move it into a function efi_allocate_pages_aligned() in alignedmem.c. Update efi_allocate_pages() to invoke it unless the minimum alignment equals the EFI page size (4 KB), in which case the ordinary page allocator is sufficient. This way, efi_allocate_pages_aligned() will only be pulled into the build if it is actually being used (which will be on arm64 only in the immediate future)
--- drivers/firmware/efi/libstub/Makefile | 3 +- drivers/firmware/efi/libstub/alignedmem.c | 57 +++++++++++++++++++++++ drivers/firmware/efi/libstub/efistub.h | 3 ++ drivers/firmware/efi/libstub/mem.c | 25 ++++------ 4 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 drivers/firmware/efi/libstub/alignedmem.c
drivers/firmware/efi/libstub/Makefile +2 -1
@@ -42,7 +42,8 @@ KCOV_INSTRUMENT := n lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ file.o mem.o random.o randomalloc.o pci.o \ - skip_spaces.o lib-cmdline.o lib-ctype.o + skip_spaces.o lib-cmdline.o lib-ctype.o \ + alignedmem.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
drivers/firmware/efi/libstub/alignedmem.c new file +57 -0
57 lines not on this page · raw message
drivers/firmware/efi/libstub/efistub.h +3 -0
@@ -657,6 +657,9 @@ efi_status_t efi_low_alloc(unsigned long size, unsigned long align,efi_status_t efi_allocate_pages (unsigned long size,unsigned long *addr,unsigned long max); +efi_status_t efi_allocate_pages_aligned (unsigned long size,unsigned long *addr, +unsigned long max,unsigned long align); + efi_status_t efi_relocate_kernel(unsigned long *image_addr, unsigned long image_size, unsigned long alloc_size,
drivers/firmware/efi/libstub/mem.c +9 -16
@@ -93,31 +93,24 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap *map)efi_status_t efi_allocate_pages (unsigned long size,unsigned long *addr,unsigned long max) { -efi_physical_addr_t alloc_addr =ALIGN_DOWN (max +1 ,EFI_ALLOC_ALIGN ) -1 ; -int slack =EFI_ALLOC_ALIGN /EFI_PAGE_SIZE -1 ; +efi_physical_addr_t alloc_addr;efi_status_t status; - size =round_up (size,EFI_ALLOC_ALIGN ); +if (EFI_ALLOC_ALIGN >EFI_PAGE_SIZE ) +return efi_allocate_pages_aligned (size, addr, max, +EFI_ALLOC_ALIGN ); + + alloc_addr =ALIGN_DOWN (max +1 ,EFI_ALLOC_ALIGN ) -1 ; status =efi_bs_call (allocate_pages,EFI_ALLOCATE_MAX_ADDRESS , -EFI_LOADER_DATA , size /EFI_PAGE_SIZE + slack, +EFI_LOADER_DATA ,DIV_ROUND_UP (size,EFI_PAGE_SIZE ), &alloc_addr);if (status !=EFI_SUCCESS )return status; - *addr =ALIGN ((unsigned long )alloc_addr,EFI_ALLOC_ALIGN ); - -if (slack >0 ) { -int l = (alloc_addr %EFI_ALLOC_ALIGN ) /EFI_PAGE_SIZE ; - -if (l) { -efi_bs_call (free_pages, alloc_addr, slack - l +1 ); - slack = l -1 ; - } -if (slack) -efi_bs_call (free_pages, *addr + size, slack); - } + *addr = alloc_addr;return EFI_SUCCESS ; } +/** * efi_low_alloc_above() - allocate pages at or above given address * @size: size of the memory area to allocate
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 17/33 efi/gop: Allow specifying depth as well as resolution
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Extend the video mode argument to handle an optional color depth specification of the form
video=efifb:<xres>x<yres>[-(rgb|bgr|<bpp>)]
--- Documentation/fb/efifb.rst | 8 +++-- drivers/firmware/efi/libstub/gop.c | 48 ++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 8 deletions(-)
Documentation/fb/efifb.rst +5 -3
@@ -50,9 +50,11 @@ mode=n The EFI stub will set the mode of the display to mode number n if possible. -<xres>x<yres> +<xres>x<yres>[-(rgb|bgr|<bpp>)] The EFI stub will search for a display mode that matches the specified - horizontal and vertical resolution, and set the mode of the display to - it if one is found. + horizontal and vertical resolution, and optionally bit depth, and set + the mode of the display to it if one is found. The bit depth can either + "rgb" or "bgr" to match specifically those pixel formats, or a number + for a mode with matching bits per pixel. Edgar Hucek <[email protected]>
drivers/firmware/efi/libstub/gop.c +43 -5
102 lines not on this page · raw message
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 11/33 efi/gop: Use helper macros for populating lfb_base
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Use the lower/upper_32_bits macros from kernel.h to initialize si->lfb_base and si->ext_lfb_base.
--- drivers/firmware/efi/libstub/gop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/firmware/efi/libstub/gop.c +2 -2
@@ -158,8 +158,8 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, si->lfb_height = info->vertical_resolution; fb_base =efi_table_attr (mode, frame_buffer_base); - si->lfb_base = fb_base; - si->ext_lfb_base = (u64 )(unsigned long )fb_base >>32 ; + si->lfb_base =lower_32_bits (fb_base); + si->ext_lfb_base =upper_32_bits (fb_base);if (si->ext_lfb_base) si->capabilities |=VIDEO_CAPABILITY_64BIT_BASE ;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 8/33 efi/gop: Factor out locating the gop into a function
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
Move the loop to find a gop into its own function.
--- drivers/firmware/efi/libstub/gop.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
drivers/firmware/efi/libstub/gop.c +17 -6
@@ -85,19 +85,17 @@ setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line, } } -static efi_status_t setup_gop (struct screen_info *si,efi_guid_t *proto, -unsigned long size,void **handles) +static efi_graphics_output_protocol_t * +find_gop (efi_guid_t *proto,unsigned long size,void **handles) {efi_graphics_output_protocol_t *gop, *first_gop;efi_graphics_output_protocol_mode_t *mode;efi_graphics_output_mode_info_t *info =NULL ; -efi_physical_addr_t fb_base;efi_status_t status;efi_handle_t h;int i; first_gop =NULL ; - gop =NULL ;for_each_efi_handle (h, handles, size, i) {efi_guid_t conout_proto =EFI_CONSOLE_OUT_DEVICE_GUID ;
@@ -134,12 +132,25 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, } } +return first_gop; +} + +static efi_status_t setup_gop (struct screen_info *si,efi_guid_t *proto, +unsigned long size,void **handles) +{ +efi_graphics_output_protocol_t *gop; +efi_graphics_output_protocol_mode_t *mode; +efi_graphics_output_mode_info_t *info =NULL ; +efi_physical_addr_t fb_base; + + gop =find_gop (proto, size, handles); +/* Did we find any GOPs? */ -if (!first_gop) +if (!gop)return EFI_NOT_FOUND ;/* EFI framebuffer */ - mode =efi_table_attr (first_gop, mode); + mode =efi_table_attr (gop, mode); info =efi_table_attr (mode, info); si->orig_video_isVGA =VIDEO_TYPE_EFI ;
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH 5/33 efi/gop: Remove redundant current_fb_base
In reply to Ard BiesheuvelFrom: Arvind Sankar <[email protected]>
current_fb_base isn't used for anything except assigning to fb_base if we locate a suitable gop.
--- drivers/firmware/efi/libstub/gop.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/firmware/efi/libstub/gop.c +1 -3
@@ -108,7 +108,6 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,efi_guid_t conout_proto =EFI_CONSOLE_OUT_DEVICE_GUID ;bool conout_found = false;void *dummy =NULL ; -efi_physical_addr_t current_fb_base; status =efi_bs_call (handle_protocol, h, proto, (void **)&gop);if (status !=EFI_SUCCESS )
@@ -120,7 +119,6 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, mode =efi_table_attr (gop, mode); info =efi_table_attr (mode, info); - current_fb_base =efi_table_attr (mode, frame_buffer_base);if ((!first_gop || conout_found) && info->pixel_format !=PIXEL_BLT_ONLY ) {
@@ -136,7 +134,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, pixel_format = info->pixel_format; pixel_info = info->pixel_information; pixels_per_scan_line = info->pixels_per_scan_line; - fb_base = current_fb_base; + fb_base =efi_table_attr (mode, frame_buffer_base);/* * Once we've found a GOP supporting ConOut,
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerRe: [PATCH 02/33] efi/libstub: Make initrd file loader configurable
In reply to Ard BiesheuvelQuoted 19 lines · Ard Biesheuvel
Loading an initrd passed via the kernel command line is deprecated: it is limited to files that reside in the same volume as the one the kernel itself was loaded from, and we have more flexible ways to achieve the same. So make it configurable so new architectures can decide not to enable it.
Signed-off-by Ard Biesheuvel <[email protected]>--- drivers/firmware/efi/Kconfig | 11 ++++++++ drivers/firmware/efi/libstub/efistub.h | 38 ++++++++++++++++++++------ drivers/firmware/efi/libstub/file.c | 32 +++++----------------- 3 files changed, 47 insertions(+), 34 deletions(-)drivers/firmware/efi/Kconfig +0
-0
drivers/firmware/efi/Kconfig config EFI_ARMSTUB_DTB_LOADER · line 129
Quoted 6 lines
drivers/firmware/efi/Kconfig +3
-0@@ -124,6 +124,17 @@ config EFI_ARMSTUB_DTB_LOADER functionality for bootloaders that do not have such support this option is necessary. +config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER + bool "Enable the command line initrd loader" + depends on EFI_GENERIC_STUB
Right after hitting send, I realised this should be
depends on EFI_GENERIC_STUB || X86
Care to fix that up before applying, please?
Quoted 110 lines
drivers/firmware/efi/Kconfig +8
-0+ default y + help + Select this config option to add support for the initrd= command + line parameter, allowing an initrd that resides on the same volume + as the kernel image to be loaded into memory. + + This method is deprecated. + config EFI_BOOTLOADER_CONTROL tristate "EFI Bootloader Control" depends on EFI_VARSdrivers/firmware/efi/libstub/efistub.h +29
-9@@ -651,15 +651,35 @@ efi_status_t efi_parse_options(char const *cmdline);efi_status_t efi_setup_gop (struct screen_info *si,efi_guid_t *proto,unsigned long size); -efi_status_t efi_load_dtb (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size); - -efi_status_t efi_load_initrd (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size, -unsigned long soft_limit, -unsigned long hard_limit); +efi_status_t handle_cmdline_files (efi_loaded_image_t *image, +const efi_char16_t *optstr, +int optstr_size, +unsigned long soft_limit, +unsigned long hard_limit, +unsigned long *load_addr, +unsigned long *load_size); + + +static inline efi_status_t efi_load_dtb (efi_loaded_image_t *image, +unsigned long *load_addr, +unsigned long *load_size) +{ +return handle_cmdline_files (image,L"dtb=" ,sizeof (L"dtb=" ) -2 , +ULONG_MAX ,ULONG_MAX , load_addr, load_size); +} + +static inline efi_status_t efi_load_initrd (efi_loaded_image_t *image, +unsigned long *load_addr, +unsigned long *load_size, +unsigned long soft_limit, +unsigned long hard_limit) +{ +if (!IS_ENABLED (CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER )) +return EFI_SUCCESS ; + +return handle_cmdline_files (image,L"initrd=" ,sizeof (L"initrd=" ) -2 , + soft_limit, hard_limit, load_addr, load_size); +} efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr, unsigned long *load_size,drivers/firmware/efi/libstub/file.c +7
-26@@ -121,13 +121,13 @@ static int find_file_option(const efi_char16_t *cmdline, int cmdline_len,* We only support loading a file from the same filesystem as * the kernel image. */ -static efi_status_t handle_cmdline_files (efi_loaded_image_t *image, -const efi_char16_t *optstr, -int optstr_size, -unsigned long soft_limit, -unsigned long hard_limit, -unsigned long *load_addr, -unsigned long *load_size) +efi_status_t handle_cmdline_files (efi_loaded_image_t *image, +const efi_char16_t *optstr, +int optstr_size, +unsigned long soft_limit, +unsigned long hard_limit, +unsigned long *load_addr, +unsigned long *load_size) {const efi_char16_t *cmdline = image->load_options;int cmdline_len = image->load_options_size /2 ;@@ -239,21 +239,3 @@ static efi_status_t handle_cmdline_files(efi_loaded_image_t *image,efi_free (alloc_size, alloc_addr);return status; } - -efi_status_t efi_load_dtb (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size) -{ -return handle_cmdline_files (image,L"dtb=" ,sizeof (L"dtb=" ) -2 , -ULONG_MAX ,ULONG_MAX , load_addr, load_size); -} - -efi_status_t efi_load_initrd (efi_loaded_image_t *image, -unsigned long *load_addr, -unsigned long *load_size, -unsigned long soft_limit, -unsigned long hard_limit) -{ -return handle_cmdline_files (image,L"initrd=" ,sizeof (L"initrd=" ) -2 , - soft_limit, hard_limit, load_addr, load_size); -} --2.17.1
Quoted 30 lines · Ard Biesheuvel
Hello Ingo, Thomas,
Please pull the attached changes into tip/efi/next. There is some coordination going on with the RISC-V tree this time, so please take the patches in this exact order, and apply them onto v5.7-rc2 so the first three patches can serve as a shared stable base between the efi/core branch and the riscv tree.
The following changes since commit
ae83d0b416db002fe95601e7f97f64b59514d936:Linux 5.7-rc2 (2020-04-19 14:35:30 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.gittags/efi-nextfor you to fetch changes up to
4eb8320bd1aaa7e69d039f2c251735e3ef0b9a38:efi: Move
arch_tablescheck to caller (2020-04-24 14:52:16 +0200)----------------------------------------------------------------
EFI changes for v5.8:
- preliminary changes for RISC-V
- add support for setting the resolution on the EFI framebuffer
- simplify kernel image loading for arm64
- Move .bss into .data via the linker script instead of relying on symbol annotations.
- Get rid of__puregetters to access global variables
- Clean up the config table matching arrays
Quoted 4 lines
27 files changed, 895 insertions(+), 574 deletions(-)
create mode 100644 drivers/firmware/efi/libstub/alignedmem.c
rename drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c} (96%)
create mode 100644 drivers/firmware/efi/libstub/relocate.cPulled into tip:efi/core, thanks a lot Ard!
Ingo
Ard Biesheuvel
maintainerQuoted 34 lines · Ingo Molnar
Quoted 29 lines · Ard Biesheuvel
Hello Ingo, Thomas,
Please pull the attached changes into tip/efi/next. There is some coordination going on with the RISC-V tree this time, so please take the patches in this exact order, and apply them onto v5.7-rc2 so the first three patches can serve as a shared stable base between the efi/core branch and the riscv tree.
The following changes since commit
ae83d0b416db002fe95601e7f97f64b59514d936:Linux 5.7-rc2 (2020-04-19 14:35:30 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.gittags/efi-nextfor you to fetch changes up to
4eb8320bd1aaa7e69d039f2c251735e3ef0b9a38:efi: Move
arch_tablescheck to caller (2020-04-24 14:52:16 +0200)----------------------------------------------------------------
EFI changes for v5.8:
- preliminary changes for RISC-V
- add support for setting the resolution on the EFI framebuffer
- simplify kernel image loading for arm64
- Move .bss into .data via the linker script instead of relying on symbol annotations.
- Get rid of__puregetters to access global variables
- Clean up the config table matching arrays
Quoted 7 lines
Quoted 4 lines
27 files changed, 895 insertions(+), 574 deletions(-) create mode 100644 drivers/firmware/efi/libstub/alignedmem.c rename drivers/firmware/efi/libstub/{arm-stub.c => efi-stub.c} (96%) create mode 100644 drivers/firmware/efi/libstub/relocate.cPulled into tip:efi/core, thanks a lot Ard!
Thanks Ingo
I guess this means you didn't spot my remark regarding patch #3, which needs a Kconfig depends tweak for x86. I'll send that out as a followup patch.
Re: [PATCH 03/33] efi/libstub: Unify EFI call wrappers for non-x86
In reply to Ard BiesheuvelHi,
Quoted 8 lines · Ard Biesheuvel
We have wrappers around EFI calls so that x86 can define special versions for mixed mode, while all other architectures can use the same simple definition that just issues the call directly. In preparation for the arrival of yet another architecture that doesn't need anything special here (RISC-V), let's move the default definition into a shared header.
Signed-off-by Ard Biesheuvel <[email protected]>
This patch causes an immediate reboot in linux-next when booting in qemu with an efi32 bios. Bisect log attached.
Qemu command line:
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -m 1G \ -no-reboot -snapshot \ -bios OVMF-pure-efi-32.fd \ -drive file=rootfs.ext2,format=raw \ --append 'earlycon=uart8250,io,0x3f8,9600n8 panic=-1 root=/dev/sda console=ttyS0' \ -nographic
The same command succeeds with OVMF-pure-efi-64.fd.
Bisect log attached.
File locations:
https://github.com/groeck/linux-build-test/blob/master/rootfs/firmware/OVMF-pure-efi-32.fd https://github.com/groeck/linux-build-test/blob/master/rootfs/x86_64/rootfs.ext2.gz
Guenter
---
# bad: [fb9d670f57e3f6478602328bbbf71138be06ca4f] Add linux-next specific files for 20200501
# good: [6a8b55ed4056ea5559ebe4f6a4b247f627870d4c] Linux 5.7-rc3
git bisect start 'HEAD' 'v5.7-rc3'
# good: [068b80b68a670f0b17288c8a3d1ee751f35162ab] Merge remote-tracking branch 'drm/drm-next'
git bisect good 068b80b68a670f0b17288c8a3d1ee751f35162ab
# bad: [46c70fc6a3ac35cd72ddad248dcbe4eee716d2a5] Merge remote-tracking branch 'drivers-x86/for-next' git bisect bad 46c70fc6a3ac35cd72ddad248dcbe4eee716d2a5
# good: [3fc893798e1ca8276eaf2b0e3210f2ff927f0c80] Merge remote-tracking branch 'integrity/next-integrity' git bisect good 3fc893798e1ca8276eaf2b0e3210f2ff927f0c80
# bad: [88188475d4d3fd10edabb172a7dc71e4bf997c19] Merge remote-tracking branch 'tip/auto-latest'
git bisect bad 88188475d4d3fd10edabb172a7dc71e4bf997c19
# good: [a51a8decbc07a511d9a05b2aff93bd8b10bfe812] Merge branch 'objtool/core'
git bisect good a51a8decbc07a511d9a05b2aff93bd8b10bfe812
# good: [12414a49ebe9d6584f4942a4bfd98ce5c34e034b] Merge remote-tracking branch 'spi/for-next'
git bisect good 12414a49ebe9d6584f4942a4bfd98ce5c34e034b
# good: [703b321501c95c658275fd76775282fe45989641] kcsan: Introduce ASSERT_EXCLUSIVE_BITS(var, mask) git bisect good 703b321501c95c658275fd76775282fe45989641
# bad: [e71356fe29e7bd5cd5e07800d4940a7481fb0854] efi/libstub/arm64: Switch to ordinary page allocator for kernel image git bisect bad e71356fe29e7bd5cd5e07800d4940a7481fb0854
# bad: [9867fc9de6a6a7a54edb2c43540c6db226e84a14] efi/gop: Use helper macros for find_bits
git bisect bad 9867fc9de6a6a7a54edb2c43540c6db226e84a14
# bad: [8cd207973c37175bf44727e28aa9c74fcf18de5e] efi/gop: Move check for framebuffer before con_out git bisect bad 8cd207973c37175bf44727e28aa9c74fcf18de5e
# bad: [22090f84bc3f8081e0ec180ccaedc85820085376] efi/libstub: unify EFI call wrappers for non-x86 git bisect bad 22090f84bc3f8081e0ec180ccaedc85820085376
# good: [cf6b83664895a5c7e97710df282e220bd047f0f5] efi/libstub: Make initrd file loader configurable git bisect good cf6b83664895a5c7e97710df282e220bd047f0f5
# first bad commit: [22090f84bc3f8081e0ec180ccaedc85820085376] efi/libstub: unify EFI call wrappers for non-x86
Re: [PATCH 03/33] efi/libstub: Unify EFI call wrappers for non-x86
Quoted 26 lines · Guenter Roeck
Hi,
Quoted 8 lines · Ard Biesheuvel
We have wrappers around EFI calls so that x86 can define special versions for mixed mode, while all other architectures can use the same simple definition that just issues the call directly. In preparation for the arrival of yet another architecture that doesn't need anything special here (RISC-V), let's move the default definition into a shared header.
Signed-off-by Ard Biesheuvel <[email protected]>This patch causes an immediate reboot in linux-next when booting in qemu with an efi32 bios. Bisect log attached.
Qemu command line:
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -m 1G \ -no-reboot -snapshot \ -bios OVMF-pure-efi-32.fd \ -drive file=rootfs.ext2,format=raw \ --append 'earlycon=uart8250,io,0x3f8,9600n8 panic=-1 root=/dev/sda console=ttyS0' \ -nographicThe same command succeeds with OVMF-pure-efi-64.fd.
Quoted 8 lines
Bisect log attached.
File locations:
https://github.com/groeck/linux-build-test/blob/master/rootfs/firmware/OVMF-pure-efi-32.fd https://github.com/groeck/linux-build-test/blob/master/rootfs/x86_64/rootfs.ext2.gzGuenter
The issue is that efi_is_native is an inline function on x86, not a macro, so the #ifndef efi_is_native is broken.
We can either turn it into a macro, or add
#define efi_is_native efi_is_native
in arch/x86/include/asm/efi.h.
Ard Biesheuvel
maintainerRe: [PATCH 03/33] efi/libstub: Unify EFI call wrappers for non-x86
Quoted 37 lines · Arvind Sankar
Quoted 26 lines · Guenter Roeck
Hi,
Quoted 8 lines · Ard Biesheuvel
We have wrappers around EFI calls so that x86 can define special versions for mixed mode, while all other architectures can use the same simple definition that just issues the call directly. In preparation for the arrival of yet another architecture that doesn't need anything special here (RISC-V), let's move the default definition into a shared header.
Signed-off-by Ard Biesheuvel <[email protected]>This patch causes an immediate reboot in linux-next when booting in qemu with an efi32 bios. Bisect log attached.
Qemu command line:
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -m 1G \ -no-reboot -snapshot \ -bios OVMF-pure-efi-32.fd \ -drive file=rootfs.ext2,format=raw \ --append 'earlycon=uart8250,io,0x3f8,9600n8 panic=-1 root=/dev/sda console=ttyS0' \ -nographicThe same command succeeds with OVMF-pure-efi-64.fd.
Quoted 8 lines
Bisect log attached.
File locations:
https://github.com/groeck/linux-build-test/blob/master/rootfs/firmware/OVMF-pure-efi-32.fd https://github.com/groeck/linux-build-test/blob/master/rootfs/x86_64/rootfs.ext2.gzGuenter
Quoted 6 lines
The issue is that
efi_is_nativeis an inline function on x86, not a macro, so the #ifndefefi_is_nativeis broken.We can either turn it into a macro, or add
#define efi_is_native efi_is_nativein
arch/x86/include/asm/efi.h.
Indeed. Fix here: