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

Merge tag 'efi-zboot-direct-for-v6.2' into efi/next

+987 -927
-1
MAINTAINERS
··· 7789 7789 F: arch/*/include/asm/efi.h 7790 7790 F: arch/*/kernel/efi.c 7791 7791 F: arch/arm/boot/compressed/efi-header.S 7792 - F: arch/arm64/kernel/efi-entry.S 7793 7792 F: arch/x86/platform/efi/ 7794 7793 F: drivers/firmware/efi/ 7795 7794 F: include/linux/efi*.h
-3
arch/arm/include/asm/efi.h
··· 43 43 44 44 /* arch specific definitions used by the stub code */ 45 45 46 - struct screen_info *alloc_screen_info(void); 47 - void free_screen_info(struct screen_info *si); 48 - 49 46 /* 50 47 * A reasonable upper bound for the uncompressed kernel size is 32 MBytes, 51 48 * so we will reserve that amount of memory. We have no easy way to tell what
+5 -26
arch/arm/kernel/efi.c
··· 75 75 return 0; 76 76 } 77 77 78 - static unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; 79 78 static unsigned long __initdata cpu_state_table = EFI_INVALID_TABLE_ADDR; 80 79 81 80 const efi_config_table_type_t efi_arch_tables[] __initconst = { 82 - {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table}, 83 81 {LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table}, 84 82 {} 85 83 }; 86 - 87 - static void __init load_screen_info_table(void) 88 - { 89 - struct screen_info *si; 90 - 91 - if (screen_info_table != EFI_INVALID_TABLE_ADDR) { 92 - si = early_memremap_ro(screen_info_table, sizeof(*si)); 93 - if (!si) { 94 - pr_err("Could not map screen_info config table\n"); 95 - return; 96 - } 97 - screen_info = *si; 98 - early_memunmap(si, sizeof(*si)); 99 - 100 - /* dummycon on ARM needs non-zero values for columns/lines */ 101 - screen_info.orig_video_cols = 80; 102 - screen_info.orig_video_lines = 25; 103 - 104 - if (memblock_is_map_memory(screen_info.lfb_base)) 105 - memblock_mark_nomap(screen_info.lfb_base, 106 - screen_info.lfb_size); 107 - } 108 - } 109 84 110 85 static void __init load_cpu_state_table(void) 111 86 { ··· 120 145 { 121 146 efi_init(); 122 147 123 - load_screen_info_table(); 148 + if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) { 149 + /* dummycon on ARM needs non-zero values for columns/lines */ 150 + screen_info.orig_video_cols = 80; 151 + screen_info.orig_video_lines = 25; 152 + } 124 153 125 154 /* ARM does not permit early mappings to persist across paging_init() */ 126 155 efi_memmap_unmap();
+12 -3
arch/arm64/include/asm/efi.h
··· 84 84 return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1)); 85 85 } 86 86 87 - #define alloc_screen_info(x...) &screen_info 88 - 89 - static inline void free_screen_info(struct screen_info *si) 87 + static inline unsigned long efi_get_kimg_min_align(void) 90 88 { 89 + extern bool efi_nokaslr; 90 + 91 + /* 92 + * Although relocatable kernels can fix up the misalignment with 93 + * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are 94 + * subtly out of sync with those recorded in the vmlinux when kaslr is 95 + * disabled but the image required relocation anyway. Therefore retain 96 + * 2M alignment if KASLR was explicitly disabled, even if it was not 97 + * going to be activated to begin with. 98 + */ 99 + return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; 91 100 } 92 101 93 102 #define EFI_ALLOC_ALIGN SZ_64K
+1 -8
arch/arm64/kernel/Makefile
··· 36 36 syscall.o proton-pack.o idreg-override.o idle.o \ 37 37 patching.o 38 38 39 - targets += efi-entry.o 40 - 41 - OBJCOPYFLAGS := --prefix-symbols=__efistub_ 42 - $(obj)/%.stub.o: $(obj)/%.o FORCE 43 - $(call if_changed,objcopy) 44 - 45 39 obj-$(CONFIG_COMPAT) += sys32.o signal32.o \ 46 40 sys_compat.o 47 41 obj-$(CONFIG_COMPAT) += sigreturn32.o ··· 51 57 obj-$(CONFIG_CPU_IDLE) += cpuidle.o 52 58 obj-$(CONFIG_JUMP_LABEL) += jump_label.o 53 59 obj-$(CONFIG_KGDB) += kgdb.o 54 - obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o \ 55 - efi-rt-wrapper.o 60 + obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o 56 61 obj-$(CONFIG_PCI) += pci.o 57 62 obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o 58 63 obj-$(CONFIG_ACPI) += acpi.o
-69
arch/arm64/kernel/efi-entry.S
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * EFI entry point. 4 - * 5 - * Copyright (C) 2013, 2014 Red Hat, Inc. 6 - * Author: Mark Salter <msalter@redhat.com> 7 - */ 8 - #include <linux/linkage.h> 9 - #include <linux/init.h> 10 - 11 - #include <asm/assembler.h> 12 - 13 - __INIT 14 - 15 - SYM_CODE_START(efi_enter_kernel) 16 - /* 17 - * efi_pe_entry() will have copied the kernel image if necessary and we 18 - * end up here with device tree address in x1 and the kernel entry 19 - * point stored in x0. Save those values in registers which are 20 - * callee preserved. 21 - */ 22 - ldr w2, =primary_entry_offset 23 - add x19, x0, x2 // relocated Image entrypoint 24 - mov x20, x1 // DTB address 25 - 26 - /* 27 - * Clean the copied Image to the PoC, and ensure it is not shadowed by 28 - * stale icache entries from before relocation. 29 - */ 30 - ldr w1, =kernel_size 31 - add x1, x0, x1 32 - bl dcache_clean_poc 33 - ic ialluis 34 - 35 - /* 36 - * Clean the remainder of this routine to the PoC 37 - * so that we can safely disable the MMU and caches. 38 - */ 39 - adr x0, 0f 40 - adr x1, 3f 41 - bl dcache_clean_poc 42 - 0: 43 - /* Turn off Dcache and MMU */ 44 - mrs x0, CurrentEL 45 - cmp x0, #CurrentEL_EL2 46 - b.ne 1f 47 - mrs x0, sctlr_el2 48 - bic x0, x0, #1 << 0 // clear SCTLR.M 49 - bic x0, x0, #1 << 2 // clear SCTLR.C 50 - pre_disable_mmu_workaround 51 - msr sctlr_el2, x0 52 - isb 53 - b 2f 54 - 1: 55 - mrs x0, sctlr_el1 56 - bic x0, x0, #1 << 0 // clear SCTLR.M 57 - bic x0, x0, #1 << 2 // clear SCTLR.C 58 - pre_disable_mmu_workaround 59 - msr sctlr_el1, x0 60 - isb 61 - 2: 62 - /* Jump to kernel entry point */ 63 - mov x0, x20 64 - mov x1, xzr 65 - mov x2, xzr 66 - mov x3, xzr 67 - br x19 68 - 3: 69 - SYM_CODE_END(efi_enter_kernel)
-8
arch/arm64/kernel/image-vars.h
··· 10 10 #error This file should only be included in vmlinux.lds.S 11 11 #endif 12 12 13 - PROVIDE(__efistub_kernel_size = _edata - _text); 14 13 PROVIDE(__efistub_primary_entry_offset = primary_entry - _text); 15 14 16 15 /* ··· 21 22 * linked at. The routines below are all implemented in assembler in a 22 23 * position independent manner 23 24 */ 24 - PROVIDE(__efistub_memcmp = __pi_memcmp); 25 - PROVIDE(__efistub_memchr = __pi_memchr); 26 - PROVIDE(__efistub_strlen = __pi_strlen); 27 - PROVIDE(__efistub_strnlen = __pi_strnlen); 28 - PROVIDE(__efistub_strcmp = __pi_strcmp); 29 - PROVIDE(__efistub_strncmp = __pi_strncmp); 30 - PROVIDE(__efistub_strrchr = __pi_strrchr); 31 25 PROVIDE(__efistub_dcache_clean_poc = __pi_dcache_clean_poc); 32 26 33 27 PROVIDE(__efistub__text = _text);
+9 -9
arch/loongarch/include/asm/efi.h
··· 19 19 #define EFI_ALLOC_ALIGN SZ_64K 20 20 #define EFI_RT_VIRTUAL_OFFSET CSR_DMW0_BASE 21 21 22 - static inline struct screen_info *alloc_screen_info(void) 23 - { 24 - return &screen_info; 25 - } 26 - 27 - static inline void free_screen_info(struct screen_info *si) 28 - { 29 - } 30 - 31 22 static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) 32 23 { 33 24 return ULONG_MAX; 34 25 } 26 + 27 + static inline unsigned long efi_get_kimg_min_align(void) 28 + { 29 + return SZ_2M; 30 + } 31 + 32 + #define EFI_KIMG_PREFERRED_ADDRESS PHYSADDR(VMLINUX_LOAD_ADDRESS) 33 + 34 + unsigned long kernel_entry_address(void); 35 35 36 36 #endif /* _ASM_LOONGARCH_EFI_H */
+22 -2
arch/loongarch/kernel/efi.c
··· 52 52 set_bit(EFI_RUNTIME_SERVICES, &efi.flags); 53 53 } 54 54 55 + unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; 56 + 57 + static void __init init_screen_info(void) 58 + { 59 + struct screen_info *si; 60 + 61 + if (screen_info_table == EFI_INVALID_TABLE_ADDR) 62 + return; 63 + 64 + si = early_memremap(screen_info_table, sizeof(*si)); 65 + if (!si) { 66 + pr_err("Could not map screen_info config table\n"); 67 + return; 68 + } 69 + screen_info = *si; 70 + memset(si, 0, sizeof(*si)); 71 + early_memunmap(si, sizeof(*si)); 72 + 73 + memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); 74 + } 75 + 55 76 void __init efi_init(void) 56 77 { 57 78 int size; ··· 101 80 102 81 set_bit(EFI_CONFIG_TABLES, &efi.flags); 103 82 104 - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) 105 - memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); 83 + init_screen_info(); 106 84 107 85 if (boot_memmap == EFI_INVALID_TABLE_ADDR) 108 86 return;
-8
arch/loongarch/kernel/image-vars.h
··· 7 7 8 8 #ifdef CONFIG_EFI_STUB 9 9 10 - __efistub_memcmp = memcmp; 11 - __efistub_memchr = memchr; 12 - __efistub_strcat = strcat; 13 10 __efistub_strcmp = strcmp; 14 - __efistub_strlen = strlen; 15 - __efistub_strncat = strncat; 16 - __efistub_strnstr = strnstr; 17 - __efistub_strnlen = strnlen; 18 - __efistub_strrchr = strrchr; 19 11 __efistub_kernel_entry = kernel_entry; 20 12 __efistub_kernel_asize = kernel_asize; 21 13 __efistub_kernel_fsize = kernel_fsize;
+10 -3
arch/riscv/include/asm/efi.h
··· 31 31 return ULONG_MAX; 32 32 } 33 33 34 - #define alloc_screen_info(x...) (&screen_info) 35 - 36 - static inline void free_screen_info(struct screen_info *si) 34 + static inline unsigned long efi_get_kimg_min_align(void) 37 35 { 36 + /* 37 + * RISC-V requires the kernel image to placed 2 MB aligned base for 64 38 + * bit and 4MB for 32 bit. 39 + */ 40 + return IS_ENABLED(CONFIG_64BIT) ? SZ_2M : SZ_4M; 38 41 } 42 + 43 + #define EFI_KIMG_PREFERRED_ADDRESS efi_get_kimg_min_align() 39 44 40 45 void efi_virtmap_load(void); 41 46 void efi_virtmap_unload(void); 47 + 48 + unsigned long stext_offset(void); 42 49 43 50 #endif /* _ASM_EFI_H */
-6
arch/riscv/kernel/image-vars.h
··· 23 23 * linked at. The routines below are all implemented in assembler in a 24 24 * position independent manner 25 25 */ 26 - __efistub_memcmp = memcmp; 27 - __efistub_memchr = memchr; 28 - __efistub_strlen = strlen; 29 - __efistub_strnlen = strnlen; 30 26 __efistub_strcmp = strcmp; 31 - __efistub_strncmp = strncmp; 32 - __efistub_strrchr = strrchr; 33 27 34 28 __efistub__start = _start; 35 29 __efistub__start_kernel = _start_kernel;
+18 -3
drivers/firmware/efi/efi-init.c
··· 22 22 23 23 #include <asm/efi.h> 24 24 25 + unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; 26 + 25 27 static int __init is_memory(efi_memory_desc_t *md) 26 28 { 27 29 if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC)) ··· 57 55 58 56 static void __init init_screen_info(void) 59 57 { 60 - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && 61 - memblock_is_map_memory(screen_info.lfb_base)) 62 - memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size); 58 + struct screen_info *si; 59 + 60 + if (screen_info_table != EFI_INVALID_TABLE_ADDR) { 61 + si = early_memremap(screen_info_table, sizeof(*si)); 62 + if (!si) { 63 + pr_err("Could not map screen_info config table\n"); 64 + return; 65 + } 66 + screen_info = *si; 67 + memset(si, 0, sizeof(*si)); 68 + early_memunmap(si, sizeof(*si)); 69 + 70 + if (memblock_is_map_memory(screen_info.lfb_base)) 71 + memblock_mark_nomap(screen_info.lfb_base, 72 + screen_info.lfb_size); 73 + } 63 74 } 64 75 65 76 static int __init uefi_init(u64 efi_system_table)
+5
drivers/firmware/efi/efi.c
··· 58 58 static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR; 59 59 static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR; 60 60 61 + extern unsigned long screen_info_table; 62 + 61 63 struct mm_struct efi_mm = { 62 64 .mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock), 63 65 .mm_users = ATOMIC_INIT(2), ··· 548 546 #endif 549 547 #ifdef CONFIG_EFI_COCO_SECRET 550 548 {LINUX_EFI_COCO_SECRET_AREA_GUID, &efi.coco_secret, "CocoSecret" }, 549 + #endif 550 + #ifdef CONFIG_EFI_GENERIC_STUB 551 + {LINUX_EFI_SCREEN_INFO_TABLE_GUID, &screen_info_table }, 551 552 #endif 552 553 {}, 553 554 };
+19 -15
drivers/firmware/efi/libstub/Makefile
··· 5 5 # things like ftrace and stack-protector are likely to cause trouble if left 6 6 # enabled, even if doing so doesn't break the build. 7 7 # 8 + 9 + # non-x86 reuses KBUILD_CFLAGS, x86 does not 10 + cflags-y := $(KBUILD_CFLAGS) 11 + 8 12 cflags-$(CONFIG_X86_32) := -march=i386 9 13 cflags-$(CONFIG_X86_64) := -mcmodel=small 10 14 cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ ··· 22 18 23 19 # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly 24 20 # disable the stackleak plugin 25 - cflags-$(CONFIG_ARM64) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ 26 - -fpie $(DISABLE_STACKLEAK_PLUGIN) \ 21 + cflags-$(CONFIG_ARM64) += -fpie $(DISABLE_STACKLEAK_PLUGIN) \ 27 22 $(call cc-option,-mbranch-protection=none) 28 - cflags-$(CONFIG_ARM) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ 29 - -fno-builtin -fpic \ 23 + cflags-$(CONFIG_ARM) += -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \ 24 + -DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \ 25 + -DEFI_HAVE_STRCMP -fno-builtin -fpic \ 30 26 $(call cc-option,-mno-single-pic-base) 31 - cflags-$(CONFIG_RISCV) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ 32 - -fpic 33 - cflags-$(CONFIG_LOONGARCH) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ 34 - -fpie 27 + cflags-$(CONFIG_RISCV) += -fpic 28 + cflags-$(CONFIG_LOONGARCH) += -fpie 35 29 36 30 cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt 37 31 38 - KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ 32 + KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(cflags-y)) \ 33 + -Os -DDISABLE_BRANCH_PROFILING \ 39 34 -include $(srctree)/include/linux/hidden.h \ 40 35 -D__NO_FORTIFY \ 41 36 -ffreestanding \ ··· 70 67 lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ 71 68 file.o mem.o random.o randomalloc.o pci.o \ 72 69 skip_spaces.o lib-cmdline.o lib-ctype.o \ 73 - alignedmem.o relocate.o vsprintf.o 70 + alignedmem.o relocate.o printk.o vsprintf.o 74 71 75 72 # include the stub's libfdt dependencies from lib/ when needed 76 73 libfdt-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c \ ··· 82 79 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE 83 80 $(call if_changed_rule,cc_o_c) 84 81 85 - lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o 82 + lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \ 83 + screen_info.o efi-stub-entry.o 86 84 87 85 lib-$(CONFIG_ARM) += arm32-stub.o 88 - lib-$(CONFIG_ARM64) += arm64-stub.o smbios.o 86 + lib-$(CONFIG_ARM64) += arm64.o arm64-stub.o arm64-entry.o smbios.o 89 87 lib-$(CONFIG_X86) += x86-stub.o 90 - lib-$(CONFIG_RISCV) += riscv-stub.o 91 - lib-$(CONFIG_LOONGARCH) += loongarch-stub.o 88 + lib-$(CONFIG_RISCV) += riscv.o riscv-stub.o 89 + lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o 92 90 93 91 CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) 94 92 ··· 140 136 # 141 137 STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \ 142 138 --prefix-symbols=__efistub_ 143 - STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS 139 + STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS64 144 140 145 141 # For RISC-V, we don't need anything special other than arm64. Keep all the 146 142 # symbols in .init section and make sure that no absolute symbols references
+10 -12
drivers/firmware/efi/libstub/Makefile.zboot
··· 10 10 comp-type-$(CONFIG_KERNEL_XZ) := xzkern 11 11 comp-type-$(CONFIG_KERNEL_ZSTD) := zstd22 12 12 13 - # in GZIP, the appended le32 carrying the uncompressed size is part of the 14 - # format, but in other cases, we just append it at the end for convenience, 15 - # causing the original tools to complain when checking image integrity. 16 - # So disregard it when calculating the payload size in the zimage header. 17 - zboot-method-y := $(comp-type-y)_with_size 18 - zboot-size-len-y := 4 19 - 20 - zboot-method-$(CONFIG_KERNEL_GZIP) := gzip 21 - zboot-size-len-$(CONFIG_KERNEL_GZIP) := 0 13 + # Copy the SizeOfHeaders, SizeOfCode and SizeOfImage fields from the payload to 14 + # the end of the compressed image. Note that this presupposes a PE header 15 + # offset of 64 bytes, which is what arm64, RISC-V and LoongArch use. 16 + quiet_cmd_compwithsize = $(quiet_cmd_$(comp-type-y)) 17 + cmd_compwithsize = $(cmd_$(comp-type-y)) && ( \ 18 + dd status=none if=$< bs=4 count=1 skip=37 ; \ 19 + dd status=none if=$< bs=4 count=1 skip=23 ; \ 20 + dd status=none if=$< bs=4 count=1 skip=36 ) >> $@ 22 21 23 22 $(obj)/vmlinuz: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE 24 - $(call if_changed,$(zboot-method-y)) 23 + $(call if_changed,compwithsize) 25 24 26 25 OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \ 27 26 --rename-section .data=.gzdata,load,alloc,readonly,contents ··· 29 30 30 31 AFLAGS_zboot-header.o += -DMACHINE_TYPE=IMAGE_FILE_MACHINE_$(EFI_ZBOOT_MACH_TYPE) \ 31 32 -DZBOOT_EFI_PATH="\"$(realpath $(obj)/vmlinuz.efi.elf)\"" \ 32 - -DZBOOT_SIZE_LEN=$(zboot-size-len-y) \ 33 33 -DCOMP_TYPE="\"$(comp-type-y)\"" 34 34 35 35 $(obj)/zboot-header.o: $(srctree)/drivers/firmware/efi/libstub/zboot-header.S FORCE ··· 44 46 $(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.elf FORCE 45 47 $(call if_changed,objcopy) 46 48 47 - targets += zboot-header.o vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi 49 + targets += zboot-header.o vmlinuz.o vmlinuz.efi.elf vmlinuz.efi
-37
drivers/firmware/efi/libstub/arm32-stub.c
··· 76 76 &efi_entry_state->sctlr_after_ebs); 77 77 } 78 78 79 - static efi_guid_t screen_info_guid = LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID; 80 - 81 - struct screen_info *alloc_screen_info(void) 82 - { 83 - struct screen_info *si; 84 - efi_status_t status; 85 - 86 - /* 87 - * Unlike on arm64, where we can directly fill out the screen_info 88 - * structure from the stub, we need to allocate a buffer to hold 89 - * its contents while we hand over to the kernel proper from the 90 - * decompressor. 91 - */ 92 - status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA, 93 - sizeof(*si), (void **)&si); 94 - 95 - if (status != EFI_SUCCESS) 96 - return NULL; 97 - 98 - status = efi_bs_call(install_configuration_table, 99 - &screen_info_guid, si); 100 - if (status == EFI_SUCCESS) 101 - return si; 102 - 103 - efi_bs_call(free_pool, si); 104 - return NULL; 105 - } 106 - 107 - void free_screen_info(struct screen_info *si) 108 - { 109 - if (!si) 110 - return; 111 - 112 - efi_bs_call(install_configuration_table, &screen_info_guid, NULL); 113 - efi_bs_call(free_pool, si); 114 - } 115 - 116 79 efi_status_t handle_kernel_image(unsigned long *image_addr, 117 80 unsigned long *image_size, 118 81 unsigned long *reserve_addr,
+67
drivers/firmware/efi/libstub/arm64-entry.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * EFI entry point. 4 + * 5 + * Copyright (C) 2013, 2014 Red Hat, Inc. 6 + * Author: Mark Salter <msalter@redhat.com> 7 + */ 8 + #include <linux/linkage.h> 9 + #include <asm/assembler.h> 10 + 11 + /* 12 + * The entrypoint of a arm64 bare metal image is at offset #0 of the 13 + * image, so this is a reasonable default for primary_entry_offset. 14 + * Only when the EFI stub is integrated into the core kernel, it is not 15 + * guaranteed that the PE/COFF header has been copied to memory too, so 16 + * in this case, primary_entry_offset should be overridden by the 17 + * linker and point to primary_entry() directly. 18 + */ 19 + .weak primary_entry_offset 20 + 21 + SYM_CODE_START(efi_enter_kernel) 22 + /* 23 + * efi_pe_entry() will have copied the kernel image if necessary and we 24 + * end up here with device tree address in x1 and the kernel entry 25 + * point stored in x0. Save those values in registers which are 26 + * callee preserved. 27 + */ 28 + ldr w2, =primary_entry_offset 29 + add x19, x0, x2 // relocated Image entrypoint 30 + 31 + mov x0, x1 // DTB address 32 + mov x1, xzr 33 + mov x2, xzr 34 + mov x3, xzr 35 + 36 + /* 37 + * Clean the remainder of this routine to the PoC 38 + * so that we can safely disable the MMU and caches. 39 + */ 40 + adr x4, 1f 41 + dc civac, x4 42 + dsb sy 43 + 44 + /* Turn off Dcache and MMU */ 45 + mrs x4, CurrentEL 46 + cmp x4, #CurrentEL_EL2 47 + mrs x4, sctlr_el1 48 + b.ne 0f 49 + mrs x4, sctlr_el2 50 + 0: bic x4, x4, #SCTLR_ELx_M 51 + bic x4, x4, #SCTLR_ELx_C 52 + b.eq 1f 53 + b 2f 54 + 55 + .balign 32 56 + 1: pre_disable_mmu_workaround 57 + msr sctlr_el2, x4 58 + isb 59 + br x19 // jump to kernel entrypoint 60 + 61 + 2: pre_disable_mmu_workaround 62 + msr sctlr_el1, x4 63 + isb 64 + br x19 // jump to kernel entrypoint 65 + 66 + .org 1b + 32 67 + SYM_CODE_END(efi_enter_kernel)
+10 -54
drivers/firmware/efi/libstub/arm64-stub.c
··· 11 11 #include <asm/efi.h> 12 12 #include <asm/memory.h> 13 13 #include <asm/sections.h> 14 - #include <asm/sysreg.h> 15 14 16 15 #include "efistub.h" 17 - 18 - static bool system_needs_vamap(void) 19 - { 20 - const u8 *type1_family = efi_get_smbios_string(1, family); 21 - 22 - /* 23 - * Ampere Altra machines crash in SetTime() if SetVirtualAddressMap() 24 - * has not been called prior. 25 - */ 26 - if (!type1_family || strcmp(type1_family, "Altra")) 27 - return false; 28 - 29 - efi_warn("Working around broken SetVirtualAddressMap()\n"); 30 - return true; 31 - } 32 - 33 - efi_status_t check_platform_features(void) 34 - { 35 - u64 tg; 36 - 37 - /* 38 - * If we have 48 bits of VA space for TTBR0 mappings, we can map the 39 - * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is 40 - * unnecessary. 41 - */ 42 - if (VA_BITS_MIN >= 48 && !system_needs_vamap()) 43 - efi_novamap = true; 44 - 45 - /* UEFI mandates support for 4 KB granularity, no need to check */ 46 - if (IS_ENABLED(CONFIG_ARM64_4K_PAGES)) 47 - return EFI_SUCCESS; 48 - 49 - tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_EL1_TGRAN_SHIFT) & 0xf; 50 - if (tg < ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX) { 51 - if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) 52 - efi_err("This 64 KB granular kernel is not supported by your CPU\n"); 53 - else 54 - efi_err("This 16 KB granular kernel is not supported by your CPU\n"); 55 - return EFI_UNSUPPORTED; 56 - } 57 - return EFI_SUCCESS; 58 - } 59 16 60 17 /* 61 18 * Distro versions of GRUB may ignore the BSS allocation entirely (i.e., fail ··· 60 103 efi_status_t status; 61 104 unsigned long kernel_size, kernel_memsize = 0; 62 105 u32 phys_seed = 0; 63 - 64 - /* 65 - * Although relocatable kernels can fix up the misalignment with 66 - * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are 67 - * subtly out of sync with those recorded in the vmlinux when kaslr is 68 - * disabled but the image required relocation anyway. Therefore retain 69 - * 2M alignment if KASLR was explicitly disabled, even if it was not 70 - * going to be activated to begin with. 71 - */ 72 - u64 min_kimg_align = efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; 106 + u64 min_kimg_align = efi_get_kimg_min_align(); 73 107 74 108 if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { 75 109 efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID; ··· 119 171 */ 120 172 *image_addr = (u64)_text; 121 173 *reserve_size = 0; 122 - return EFI_SUCCESS; 174 + goto clean_image_to_poc; 123 175 } 124 176 125 177 status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, ··· 134 186 135 187 *image_addr = *reserve_addr; 136 188 memcpy((void *)*image_addr, _text, kernel_size); 189 + 190 + clean_image_to_poc: 191 + /* 192 + * Clean the copied Image to the PoC, and ensure it is not shadowed by 193 + * stale icache entries from before relocation. 194 + */ 195 + dcache_clean_poc(*image_addr, *image_addr + kernel_size); 196 + asm("ic ialluis"); 137 197 138 198 return EFI_SUCCESS; 139 199 }
+76
drivers/firmware/efi/libstub/arm64.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2013, 2014 Linaro Ltd; <roy.franz@linaro.org> 4 + * 5 + * This file implements the EFI boot stub for the arm64 kernel. 6 + * Adapted from ARM version by Mark Salter <msalter@redhat.com> 7 + */ 8 + 9 + 10 + #include <linux/efi.h> 11 + #include <asm/efi.h> 12 + #include <asm/memory.h> 13 + #include <asm/sysreg.h> 14 + 15 + #include "efistub.h" 16 + 17 + static bool system_needs_vamap(void) 18 + { 19 + const u8 *type1_family = efi_get_smbios_string(1, family); 20 + 21 + /* 22 + * Ampere Altra machines crash in SetTime() if SetVirtualAddressMap() 23 + * has not been called prior. 24 + */ 25 + if (!type1_family || strcmp(type1_family, "Altra")) 26 + return false; 27 + 28 + efi_warn("Working around broken SetVirtualAddressMap()\n"); 29 + return true; 30 + } 31 + 32 + efi_status_t check_platform_features(void) 33 + { 34 + u64 tg; 35 + 36 + /* 37 + * If we have 48 bits of VA space for TTBR0 mappings, we can map the 38 + * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is 39 + * unnecessary. 40 + */ 41 + if (VA_BITS_MIN >= 48 && !system_needs_vamap()) 42 + efi_novamap = true; 43 + 44 + /* UEFI mandates support for 4 KB granularity, no need to check */ 45 + if (IS_ENABLED(CONFIG_ARM64_4K_PAGES)) 46 + return EFI_SUCCESS; 47 + 48 + tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_EL1_TGRAN_SHIFT) & 0xf; 49 + if (tg < ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX) { 50 + if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) 51 + efi_err("This 64 KB granular kernel is not supported by your CPU\n"); 52 + else 53 + efi_err("This 16 KB granular kernel is not supported by your CPU\n"); 54 + return EFI_UNSUPPORTED; 55 + } 56 + return EFI_SUCCESS; 57 + } 58 + 59 + void efi_cache_sync_image(unsigned long image_base, 60 + unsigned long alloc_size, 61 + unsigned long code_size) 62 + { 63 + u32 ctr = read_cpuid_effective_cachetype(); 64 + u64 lsize = 4 << cpuid_feature_extract_unsigned_field(ctr, 65 + CTR_EL0_DminLine_SHIFT); 66 + 67 + do { 68 + asm("dc civac, %0" :: "r"(image_base)); 69 + image_base += lsize; 70 + alloc_size -= lsize; 71 + } while (alloc_size >= lsize); 72 + 73 + asm("ic ialluis"); 74 + dsb(ish); 75 + isb(); 76 + }
+65
drivers/firmware/efi/libstub/efi-stub-entry.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/efi.h> 4 + #include <asm/efi.h> 5 + 6 + #include "efistub.h" 7 + 8 + /* 9 + * EFI entry point for the generic EFI stub used by ARM, arm64, RISC-V and 10 + * LoongArch. This is the entrypoint that is described in the PE/COFF header 11 + * of the core kernel. 12 + */ 13 + efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 14 + efi_system_table_t *systab) 15 + { 16 + efi_loaded_image_t *image; 17 + efi_status_t status; 18 + unsigned long image_addr; 19 + unsigned long image_size = 0; 20 + /* addr/point and size pairs for memory management*/ 21 + char *cmdline_ptr = NULL; 22 + efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID; 23 + unsigned long reserve_addr = 0; 24 + unsigned long reserve_size = 0; 25 + 26 + WRITE_ONCE(efi_system_table, systab); 27 + 28 + /* Check if we were booted by the EFI firmware */ 29 + if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 30 + return EFI_INVALID_PARAMETER; 31 + 32 + /* 33 + * Get a handle to the loaded image protocol. This is used to get 34 + * information about the running image, such as size and the command 35 + * line. 36 + */ 37 + status = efi_bs_call(handle_protocol, handle, &loaded_image_proto, 38 + (void *)&image); 39 + if (status != EFI_SUCCESS) { 40 + efi_err("Failed to get loaded image protocol\n"); 41 + return status; 42 + } 43 + 44 + status = efi_handle_cmdline(image, &cmdline_ptr); 45 + if (status != EFI_SUCCESS) 46 + return status; 47 + 48 + efi_info("Booting Linux Kernel...\n"); 49 + 50 + status = handle_kernel_image(&image_addr, &image_size, 51 + &reserve_addr, 52 + &reserve_size, 53 + image, handle); 54 + if (status != EFI_SUCCESS) { 55 + efi_err("Failed to relocate kernel\n"); 56 + return status; 57 + } 58 + 59 + status = efi_stub_common(handle, image, image_addr, cmdline_ptr); 60 + 61 + efi_free(image_size, image_addr); 62 + efi_free(reserve_size, reserve_addr); 63 + 64 + return status; 65 + }
-143
drivers/firmware/efi/libstub/efi-stub-helper.c
··· 9 9 10 10 #include <linux/stdarg.h> 11 11 12 - #include <linux/ctype.h> 13 12 #include <linux/efi.h> 14 13 #include <linux/kernel.h> 15 - #include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */ 16 14 #include <asm/efi.h> 17 15 #include <asm/setup.h> 18 16 ··· 18 20 19 21 bool efi_nochunk; 20 22 bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE); 21 - int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; 22 23 bool efi_novamap; 23 24 24 25 static bool efi_noinitrd; ··· 27 30 bool __pure __efi_soft_reserve_enabled(void) 28 31 { 29 32 return !efi_nosoftreserve; 30 - } 31 - 32 - /** 33 - * efi_char16_puts() - Write a UCS-2 encoded string to the console 34 - * @str: UCS-2 encoded string 35 - */ 36 - void efi_char16_puts(efi_char16_t *str) 37 - { 38 - efi_call_proto(efi_table_attr(efi_system_table, con_out), 39 - output_string, str); 40 - } 41 - 42 - static 43 - u32 utf8_to_utf32(const u8 **s8) 44 - { 45 - u32 c32; 46 - u8 c0, cx; 47 - size_t clen, i; 48 - 49 - c0 = cx = *(*s8)++; 50 - /* 51 - * The position of the most-significant 0 bit gives us the length of 52 - * a multi-octet encoding. 53 - */ 54 - for (clen = 0; cx & 0x80; ++clen) 55 - cx <<= 1; 56 - /* 57 - * If the 0 bit is in position 8, this is a valid single-octet 58 - * encoding. If the 0 bit is in position 7 or positions 1-3, the 59 - * encoding is invalid. 60 - * In either case, we just return the first octet. 61 - */ 62 - if (clen < 2 || clen > 4) 63 - return c0; 64 - /* Get the bits from the first octet. */ 65 - c32 = cx >> clen--; 66 - for (i = 0; i < clen; ++i) { 67 - /* Trailing octets must have 10 in most significant bits. */ 68 - cx = (*s8)[i] ^ 0x80; 69 - if (cx & 0xc0) 70 - return c0; 71 - c32 = (c32 << 6) | cx; 72 - } 73 - /* 74 - * Check for validity: 75 - * - The character must be in the Unicode range. 76 - * - It must not be a surrogate. 77 - * - It must be encoded using the correct number of octets. 78 - */ 79 - if (c32 > 0x10ffff || 80 - (c32 & 0xf800) == 0xd800 || 81 - clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000)) 82 - return c0; 83 - *s8 += clen; 84 - return c32; 85 - } 86 - 87 - /** 88 - * efi_puts() - Write a UTF-8 encoded string to the console 89 - * @str: UTF-8 encoded string 90 - */ 91 - void efi_puts(const char *str) 92 - { 93 - efi_char16_t buf[128]; 94 - size_t pos = 0, lim = ARRAY_SIZE(buf); 95 - const u8 *s8 = (const u8 *)str; 96 - u32 c32; 97 - 98 - while (*s8) { 99 - if (*s8 == '\n') 100 - buf[pos++] = L'\r'; 101 - c32 = utf8_to_utf32(&s8); 102 - if (c32 < 0x10000) { 103 - /* Characters in plane 0 use a single word. */ 104 - buf[pos++] = c32; 105 - } else { 106 - /* 107 - * Characters in other planes encode into a surrogate 108 - * pair. 109 - */ 110 - buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10); 111 - buf[pos++] = 0xdc00 + (c32 & 0x3ff); 112 - } 113 - if (*s8 == '\0' || pos >= lim - 2) { 114 - buf[pos] = L'\0'; 115 - efi_char16_puts(buf); 116 - pos = 0; 117 - } 118 - } 119 - } 120 - 121 - /** 122 - * efi_printk() - Print a kernel message 123 - * @fmt: format string 124 - * 125 - * The first letter of the format string is used to determine the logging level 126 - * of the message. If the level is less then the current EFI logging level, the 127 - * message is suppressed. The message will be truncated to 255 bytes. 128 - * 129 - * Return: number of printed characters 130 - */ 131 - int efi_printk(const char *fmt, ...) 132 - { 133 - char printf_buf[256]; 134 - va_list args; 135 - int printed; 136 - int loglevel = printk_get_level(fmt); 137 - 138 - switch (loglevel) { 139 - case '0' ... '9': 140 - loglevel -= '0'; 141 - break; 142 - default: 143 - /* 144 - * Use loglevel -1 for cases where we just want to print to 145 - * the screen. 146 - */ 147 - loglevel = -1; 148 - break; 149 - } 150 - 151 - if (loglevel >= efi_loglevel) 152 - return 0; 153 - 154 - if (loglevel >= 0) 155 - efi_puts("EFI stub: "); 156 - 157 - fmt = printk_skip_level(fmt); 158 - 159 - va_start(args, fmt); 160 - printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args); 161 - va_end(args); 162 - 163 - efi_puts(printf_buf); 164 - if (printed >= sizeof(printf_buf)) { 165 - efi_puts("[Message truncated]\n"); 166 - return -1; 167 - } 168 - 169 - return printed; 170 33 } 171 34 172 35 /**
+35 -105
drivers/firmware/efi/libstub/efi-stub.c
··· 35 35 * as well to minimize the code churn. 36 36 */ 37 37 #define EFI_RT_VIRTUAL_BASE SZ_512M 38 - #define EFI_RT_VIRTUAL_SIZE SZ_512M 39 - 40 - #ifdef CONFIG_ARM64 41 - # define EFI_RT_VIRTUAL_LIMIT DEFAULT_MAP_WINDOW_64 42 - #elif defined(CONFIG_RISCV) || defined(CONFIG_LOONGARCH) 43 - # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE_MIN 44 - #else /* Only if TASK_SIZE is a constant */ 45 - # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE 46 - #endif 47 38 48 39 /* 49 40 * Some architectures map the EFI regions into the kernel's linear map using a ··· 46 55 47 56 static u64 virtmap_base = EFI_RT_VIRTUAL_BASE; 48 57 static bool flat_va_mapping = (EFI_RT_VIRTUAL_OFFSET != 0); 58 + 59 + struct screen_info * __weak alloc_screen_info(void) 60 + { 61 + return &screen_info; 62 + } 63 + 64 + void __weak free_screen_info(struct screen_info *si) 65 + { 66 + } 49 67 50 68 static struct screen_info *setup_graphics(void) 51 69 { ··· 115 115 return supported; 116 116 } 117 117 118 - /* 119 - * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint 120 - * that is described in the PE/COFF header. Most of the code is the same 121 - * for both archictectures, with the arch-specific code provided in the 122 - * handle_kernel_image() function. 123 - */ 124 - efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 125 - efi_system_table_t *sys_table_arg) 118 + efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr) 126 119 { 127 - efi_loaded_image_t *image; 128 - efi_status_t status; 129 - unsigned long image_addr; 130 - unsigned long image_size = 0; 131 - /* addr/point and size pairs for memory management*/ 132 - char *cmdline_ptr = NULL; 133 120 int cmdline_size = 0; 134 - efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID; 135 - unsigned long reserve_addr = 0; 136 - unsigned long reserve_size = 0; 137 - struct screen_info *si; 138 - efi_properties_table_t *prop_tbl; 139 - 140 - efi_system_table = sys_table_arg; 141 - 142 - /* Check if we were booted by the EFI firmware */ 143 - if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) { 144 - status = EFI_INVALID_PARAMETER; 145 - goto fail; 146 - } 147 - 148 - status = check_platform_features(); 149 - if (status != EFI_SUCCESS) 150 - goto fail; 151 - 152 - /* 153 - * Get a handle to the loaded image protocol. This is used to get 154 - * information about the running image, such as size and the command 155 - * line. 156 - */ 157 - status = efi_bs_call(handle_protocol, handle, &loaded_image_proto, 158 - (void *)&image); 159 - if (status != EFI_SUCCESS) { 160 - efi_err("Failed to get loaded image protocol\n"); 161 - goto fail; 162 - } 121 + efi_status_t status; 122 + char *cmdline; 163 123 164 124 /* 165 125 * Get the command line from EFI, using the LOADED_IMAGE 166 126 * protocol. We are going to copy the command line into the 167 127 * device tree, so this can be allocated anywhere. 168 128 */ 169 - cmdline_ptr = efi_convert_cmdline(image, &cmdline_size); 170 - if (!cmdline_ptr) { 129 + cmdline = efi_convert_cmdline(image, &cmdline_size); 130 + if (!cmdline) { 171 131 efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n"); 172 - status = EFI_OUT_OF_RESOURCES; 173 - goto fail; 132 + return EFI_OUT_OF_RESOURCES; 174 133 } 175 134 176 135 if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || ··· 143 184 } 144 185 145 186 if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0) { 146 - status = efi_parse_options(cmdline_ptr); 187 + status = efi_parse_options(cmdline); 147 188 if (status != EFI_SUCCESS) { 148 189 efi_err("Failed to parse options\n"); 149 190 goto fail_free_cmdline; 150 191 } 151 192 } 152 193 153 - efi_info("Booting Linux Kernel...\n"); 194 + *cmdline_ptr = cmdline; 195 + return EFI_SUCCESS; 196 + 197 + fail_free_cmdline: 198 + efi_bs_call(free_pool, cmdline_ptr); 199 + return status; 200 + } 201 + 202 + efi_status_t efi_stub_common(efi_handle_t handle, 203 + efi_loaded_image_t *image, 204 + unsigned long image_addr, 205 + char *cmdline_ptr) 206 + { 207 + struct screen_info *si; 208 + efi_status_t status; 209 + 210 + status = check_platform_features(); 211 + if (status != EFI_SUCCESS) 212 + return status; 154 213 155 214 si = setup_graphics(); 156 - 157 - status = handle_kernel_image(&image_addr, &image_size, 158 - &reserve_addr, 159 - &reserve_size, 160 - image, handle); 161 - if (status != EFI_SUCCESS) { 162 - efi_err("Failed to relocate kernel\n"); 163 - goto fail_free_screeninfo; 164 - } 165 215 166 216 efi_retrieve_tpm2_eventlog(); 167 217 ··· 182 214 183 215 efi_random_get_seed(); 184 216 185 - /* 186 - * If the NX PE data feature is enabled in the properties table, we 187 - * should take care not to create a virtual mapping that changes the 188 - * relative placement of runtime services code and data regions, as 189 - * they may belong to the same PE/COFF executable image in memory. 190 - * The easiest way to achieve that is to simply use a 1:1 mapping. 191 - */ 192 - prop_tbl = get_efi_config_table(EFI_PROPERTIES_TABLE_GUID); 193 - flat_va_mapping |= prop_tbl && 194 - (prop_tbl->memory_protection_attribute & 195 - EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); 196 - 197 217 /* force efi_novamap if SetVirtualAddressMap() is unsupported */ 198 218 efi_novamap |= !(get_supported_rt_services() & 199 219 EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP); 200 - 201 - /* hibernation expects the runtime regions to stay in the same place */ 202 - if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) { 203 - /* 204 - * Randomize the base of the UEFI runtime services region. 205 - * Preserve the 2 MB alignment of the region by taking a 206 - * shift of 21 bit positions into account when scaling 207 - * the headroom value using a 32-bit random value. 208 - */ 209 - static const u64 headroom = EFI_RT_VIRTUAL_LIMIT - 210 - EFI_RT_VIRTUAL_BASE - 211 - EFI_RT_VIRTUAL_SIZE; 212 - u32 rnd; 213 - 214 - status = efi_get_random_bytes(sizeof(rnd), (u8 *)&rnd); 215 - if (status == EFI_SUCCESS) { 216 - virtmap_base = EFI_RT_VIRTUAL_BASE + 217 - (((headroom >> 21) * rnd) >> (32 - 21)); 218 - } 219 - } 220 220 221 221 install_memreserve_table(); 222 222 223 223 status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr); 224 224 225 - efi_free(image_size, image_addr); 226 - efi_free(reserve_size, reserve_addr); 227 - fail_free_screeninfo: 228 225 free_screen_info(si); 229 - fail_free_cmdline: 230 - efi_bs_call(free_pool, cmdline_ptr); 231 - fail: 232 226 return status; 233 227 } 234 228
+15
drivers/firmware/efi/libstub/efistub.h
··· 958 958 efi_loaded_image_t *image, 959 959 efi_handle_t image_handle); 960 960 961 + /* shared entrypoint between the normal stub and the zboot stub */ 962 + efi_status_t efi_stub_common(efi_handle_t handle, 963 + efi_loaded_image_t *image, 964 + unsigned long image_addr, 965 + char *cmdline_ptr); 966 + 967 + efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr); 968 + 961 969 asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint, 962 970 unsigned long fdt_addr, 963 971 unsigned long fdt_size); ··· 982 974 #endif 983 975 984 976 void efi_retrieve_tpm2_eventlog(void); 977 + 978 + struct screen_info *alloc_screen_info(void); 979 + void free_screen_info(struct screen_info *si); 980 + 981 + void efi_cache_sync_image(unsigned long image_base, 982 + unsigned long alloc_size, 983 + unsigned long code_size); 985 984 986 985 struct efi_smbios_record { 987 986 u8 type;
-18
drivers/firmware/efi/libstub/file.c
··· 66 66 static efi_status_t efi_open_volume(efi_loaded_image_t *image, 67 67 efi_file_protocol_t **fh) 68 68 { 69 - struct efi_vendor_dev_path *dp = image->file_path; 70 - efi_guid_t li_proto = LOADED_IMAGE_PROTOCOL_GUID; 71 69 efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; 72 70 efi_simple_file_system_protocol_t *io; 73 71 efi_status_t status; 74 - 75 - // If we are using EFI zboot, we should look for the file system 76 - // protocol on the parent image's handle instead 77 - if (IS_ENABLED(CONFIG_EFI_ZBOOT) && 78 - image->parent_handle != NULL && 79 - dp != NULL && 80 - dp->header.type == EFI_DEV_MEDIA && 81 - dp->header.sub_type == EFI_DEV_MEDIA_VENDOR && 82 - !efi_guidcmp(dp->vendorguid, LINUX_EFI_ZBOOT_MEDIA_GUID)) { 83 - status = efi_bs_call(handle_protocol, image->parent_handle, 84 - &li_proto, (void *)&image); 85 - if (status != EFI_SUCCESS) { 86 - efi_err("Failed to locate parent image handle\n"); 87 - return status; 88 - } 89 - } 90 72 91 73 status = efi_bs_call(handle_protocol, image->device_handle, &fs_proto, 92 74 (void **)&io);
+18
drivers/firmware/efi/libstub/intrinsics.c
··· 28 28 efi_bs_call(set_mem, dst, len, c & U8_MAX); 29 29 return dst; 30 30 } 31 + 32 + /** 33 + * memcmp - Compare two areas of memory 34 + * @cs: One area of memory 35 + * @ct: Another area of memory 36 + * @count: The size of the area. 37 + */ 38 + #undef memcmp 39 + int memcmp(const void *cs, const void *ct, size_t count) 40 + { 41 + const unsigned char *su1, *su2; 42 + int res = 0; 43 + 44 + for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) 45 + if ((res = *su1 - *su2) != 0) 46 + break; 47 + return res; 48 + }
+20 -69
drivers/firmware/efi/libstub/loongarch-stub.c
··· 9 9 #include <asm/addrspace.h> 10 10 #include "efistub.h" 11 11 12 - typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long cmdline, 13 - unsigned long systab); 14 - 15 12 extern int kernel_asize; 16 13 extern int kernel_fsize; 17 14 extern int kernel_offset; 18 - extern kernel_entry_t kernel_entry; 19 - 20 - efi_status_t check_platform_features(void) 21 - { 22 - return EFI_SUCCESS; 23 - } 15 + extern int kernel_entry; 24 16 25 17 efi_status_t handle_kernel_image(unsigned long *image_addr, 26 18 unsigned long *image_size, ··· 21 29 efi_loaded_image_t *image, 22 30 efi_handle_t image_handle) 23 31 { 32 + int nr_pages = round_up(kernel_asize, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE; 33 + efi_physical_addr_t kernel_addr = EFI_KIMG_PREFERRED_ADDRESS; 24 34 efi_status_t status; 25 - unsigned long kernel_addr = 0; 26 35 27 - kernel_addr = (unsigned long)&kernel_offset - kernel_offset; 36 + /* 37 + * Allocate space for the kernel image at the preferred offset. This is 38 + * the only location in memory from where we can execute the image, so 39 + * no point in falling back to another allocation. 40 + */ 41 + status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS, 42 + EFI_LOADER_DATA, nr_pages, &kernel_addr); 43 + if (status != EFI_SUCCESS) 44 + return status; 28 45 29 - status = efi_relocate_kernel(&kernel_addr, kernel_fsize, kernel_asize, 30 - PHYSADDR(VMLINUX_LOAD_ADDRESS), SZ_2M, 0x0); 31 - 32 - *image_addr = kernel_addr; 46 + *image_addr = EFI_KIMG_PREFERRED_ADDRESS; 33 47 *image_size = kernel_asize; 48 + 49 + memcpy((void *)EFI_KIMG_PREFERRED_ADDRESS, 50 + (void *)&kernel_offset - kernel_offset, 51 + kernel_fsize); 34 52 35 53 return status; 36 54 } 37 55 38 - struct exit_boot_struct { 39 - efi_memory_desc_t *runtime_map; 40 - int runtime_entry_count; 41 - }; 42 - 43 - static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) 56 + unsigned long kernel_entry_address(void) 44 57 { 45 - struct exit_boot_struct *p = priv; 58 + unsigned long base = (unsigned long)&kernel_offset - kernel_offset; 46 59 47 - /* 48 - * Update the memory map with virtual addresses. The function will also 49 - * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME 50 - * entries so that we can pass it straight to SetVirtualAddressMap() 51 - */ 52 - efi_get_virtmap(map->map, map->map_size, map->desc_size, 53 - p->runtime_map, &p->runtime_entry_count); 54 - 55 - return EFI_SUCCESS; 56 - } 57 - 58 - efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image, 59 - unsigned long kernel_addr, char *cmdline_ptr) 60 - { 61 - kernel_entry_t real_kernel_entry; 62 - struct exit_boot_struct priv; 63 - unsigned long desc_size; 64 - efi_status_t status; 65 - u32 desc_ver; 66 - 67 - status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver); 68 - if (status != EFI_SUCCESS) { 69 - efi_err("Unable to retrieve UEFI memory map.\n"); 70 - return status; 71 - } 72 - 73 - efi_info("Exiting boot services\n"); 74 - 75 - efi_novamap = false; 76 - status = efi_exit_boot_services(handle, &priv, exit_boot_func); 77 - if (status != EFI_SUCCESS) 78 - return status; 79 - 80 - /* Install the new virtual address map */ 81 - efi_rt_call(set_virtual_address_map, 82 - priv.runtime_entry_count * desc_size, desc_size, 83 - desc_ver, priv.runtime_map); 84 - 85 - /* Config Direct Mapping */ 86 - csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0); 87 - csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1); 88 - 89 - real_kernel_entry = (kernel_entry_t) 90 - ((unsigned long)&kernel_entry - kernel_addr + VMLINUX_LOAD_ADDRESS); 91 - 92 - real_kernel_entry(true, (unsigned long)cmdline_ptr, 93 - (unsigned long)efi_system_table); 60 + return (unsigned long)&kernel_entry - base + VMLINUX_LOAD_ADDRESS; 94 61 }
+80
drivers/firmware/efi/libstub/loongarch.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Author: Yun Liu <liuyun@loongson.cn> 4 + * Huacai Chen <chenhuacai@loongson.cn> 5 + * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 6 + */ 7 + 8 + #include <asm/efi.h> 9 + #include <asm/addrspace.h> 10 + #include "efistub.h" 11 + 12 + typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long cmdline, 13 + unsigned long systab); 14 + 15 + efi_status_t check_platform_features(void) 16 + { 17 + return EFI_SUCCESS; 18 + } 19 + 20 + struct exit_boot_struct { 21 + efi_memory_desc_t *runtime_map; 22 + int runtime_entry_count; 23 + }; 24 + 25 + static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) 26 + { 27 + struct exit_boot_struct *p = priv; 28 + 29 + /* 30 + * Update the memory map with virtual addresses. The function will also 31 + * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME 32 + * entries so that we can pass it straight to SetVirtualAddressMap() 33 + */ 34 + efi_get_virtmap(map->map, map->map_size, map->desc_size, 35 + p->runtime_map, &p->runtime_entry_count); 36 + 37 + return EFI_SUCCESS; 38 + } 39 + 40 + unsigned long __weak kernel_entry_address(void) 41 + { 42 + return *(unsigned long *)(PHYSADDR(VMLINUX_LOAD_ADDRESS) + 8); 43 + } 44 + 45 + efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image, 46 + unsigned long kernel_addr, char *cmdline_ptr) 47 + { 48 + kernel_entry_t real_kernel_entry; 49 + struct exit_boot_struct priv; 50 + unsigned long desc_size; 51 + efi_status_t status; 52 + u32 desc_ver; 53 + 54 + status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver); 55 + if (status != EFI_SUCCESS) { 56 + efi_err("Unable to retrieve UEFI memory map.\n"); 57 + return status; 58 + } 59 + 60 + efi_info("Exiting boot services\n"); 61 + 62 + efi_novamap = false; 63 + status = efi_exit_boot_services(handle, &priv, exit_boot_func); 64 + if (status != EFI_SUCCESS) 65 + return status; 66 + 67 + /* Install the new virtual address map */ 68 + efi_rt_call(set_virtual_address_map, 69 + priv.runtime_entry_count * desc_size, desc_size, 70 + desc_ver, priv.runtime_map); 71 + 72 + /* Config Direct Mapping */ 73 + csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0); 74 + csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1); 75 + 76 + real_kernel_entry = (void *)kernel_entry_address(); 77 + 78 + real_kernel_entry(true, (unsigned long)cmdline_ptr, 79 + (unsigned long)efi_system_table); 80 + }
+154
drivers/firmware/efi/libstub/printk.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/stdarg.h> 4 + 5 + #include <linux/ctype.h> 6 + #include <linux/efi.h> 7 + #include <linux/kernel.h> 8 + #include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */ 9 + #include <asm/efi.h> 10 + #include <asm/setup.h> 11 + 12 + #include "efistub.h" 13 + 14 + int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; 15 + 16 + /** 17 + * efi_char16_puts() - Write a UCS-2 encoded string to the console 18 + * @str: UCS-2 encoded string 19 + */ 20 + void efi_char16_puts(efi_char16_t *str) 21 + { 22 + efi_call_proto(efi_table_attr(efi_system_table, con_out), 23 + output_string, str); 24 + } 25 + 26 + static 27 + u32 utf8_to_utf32(const u8 **s8) 28 + { 29 + u32 c32; 30 + u8 c0, cx; 31 + size_t clen, i; 32 + 33 + c0 = cx = *(*s8)++; 34 + /* 35 + * The position of the most-significant 0 bit gives us the length of 36 + * a multi-octet encoding. 37 + */ 38 + for (clen = 0; cx & 0x80; ++clen) 39 + cx <<= 1; 40 + /* 41 + * If the 0 bit is in position 8, this is a valid single-octet 42 + * encoding. If the 0 bit is in position 7 or positions 1-3, the 43 + * encoding is invalid. 44 + * In either case, we just return the first octet. 45 + */ 46 + if (clen < 2 || clen > 4) 47 + return c0; 48 + /* Get the bits from the first octet. */ 49 + c32 = cx >> clen--; 50 + for (i = 0; i < clen; ++i) { 51 + /* Trailing octets must have 10 in most significant bits. */ 52 + cx = (*s8)[i] ^ 0x80; 53 + if (cx & 0xc0) 54 + return c0; 55 + c32 = (c32 << 6) | cx; 56 + } 57 + /* 58 + * Check for validity: 59 + * - The character must be in the Unicode range. 60 + * - It must not be a surrogate. 61 + * - It must be encoded using the correct number of octets. 62 + */ 63 + if (c32 > 0x10ffff || 64 + (c32 & 0xf800) == 0xd800 || 65 + clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000)) 66 + return c0; 67 + *s8 += clen; 68 + return c32; 69 + } 70 + 71 + /** 72 + * efi_puts() - Write a UTF-8 encoded string to the console 73 + * @str: UTF-8 encoded string 74 + */ 75 + void efi_puts(const char *str) 76 + { 77 + efi_char16_t buf[128]; 78 + size_t pos = 0, lim = ARRAY_SIZE(buf); 79 + const u8 *s8 = (const u8 *)str; 80 + u32 c32; 81 + 82 + while (*s8) { 83 + if (*s8 == '\n') 84 + buf[pos++] = L'\r'; 85 + c32 = utf8_to_utf32(&s8); 86 + if (c32 < 0x10000) { 87 + /* Characters in plane 0 use a single word. */ 88 + buf[pos++] = c32; 89 + } else { 90 + /* 91 + * Characters in other planes encode into a surrogate 92 + * pair. 93 + */ 94 + buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10); 95 + buf[pos++] = 0xdc00 + (c32 & 0x3ff); 96 + } 97 + if (*s8 == '\0' || pos >= lim - 2) { 98 + buf[pos] = L'\0'; 99 + efi_char16_puts(buf); 100 + pos = 0; 101 + } 102 + } 103 + } 104 + 105 + /** 106 + * efi_printk() - Print a kernel message 107 + * @fmt: format string 108 + * 109 + * The first letter of the format string is used to determine the logging level 110 + * of the message. If the level is less then the current EFI logging level, the 111 + * message is suppressed. The message will be truncated to 255 bytes. 112 + * 113 + * Return: number of printed characters 114 + */ 115 + int efi_printk(const char *fmt, ...) 116 + { 117 + char printf_buf[256]; 118 + va_list args; 119 + int printed; 120 + int loglevel = printk_get_level(fmt); 121 + 122 + switch (loglevel) { 123 + case '0' ... '9': 124 + loglevel -= '0'; 125 + break; 126 + default: 127 + /* 128 + * Use loglevel -1 for cases where we just want to print to 129 + * the screen. 130 + */ 131 + loglevel = -1; 132 + break; 133 + } 134 + 135 + if (loglevel >= efi_loglevel) 136 + return 0; 137 + 138 + if (loglevel >= 0) 139 + efi_puts("EFI stub: "); 140 + 141 + fmt = printk_skip_level(fmt); 142 + 143 + va_start(args, fmt); 144 + printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args); 145 + va_end(args); 146 + 147 + efi_puts(printf_buf); 148 + if (printed >= sizeof(printf_buf)) { 149 + efi_puts("[Message truncated]\n"); 150 + return -1; 151 + } 152 + 153 + return printed; 154 + }
+10 -86
drivers/firmware/efi/libstub/riscv-stub.c
··· 4 4 */ 5 5 6 6 #include <linux/efi.h> 7 - #include <linux/libfdt.h> 8 7 9 8 #include <asm/efi.h> 10 9 #include <asm/sections.h> ··· 11 12 12 13 #include "efistub.h" 13 14 14 - /* 15 - * RISC-V requires the kernel image to placed 2 MB aligned base for 64 bit and 16 - * 4MB for 32 bit. 17 - */ 18 - #ifdef CONFIG_64BIT 19 - #define MIN_KIMG_ALIGN SZ_2M 20 - #else 21 - #define MIN_KIMG_ALIGN SZ_4M 22 - #endif 23 - 24 - typedef void __noreturn (*jump_kernel_func)(unsigned long, unsigned long); 25 - 26 - static unsigned long hartid; 27 - 28 - static int get_boot_hartid_from_fdt(void) 15 + unsigned long stext_offset(void) 29 16 { 30 - const void *fdt; 31 - int chosen_node, len; 32 - const void *prop; 33 - 34 - fdt = get_efi_config_table(DEVICE_TREE_GUID); 35 - if (!fdt) 36 - return -EINVAL; 37 - 38 - chosen_node = fdt_path_offset(fdt, "/chosen"); 39 - if (chosen_node < 0) 40 - return -EINVAL; 41 - 42 - prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len); 43 - if (!prop) 44 - return -EINVAL; 45 - 46 - if (len == sizeof(u32)) 47 - hartid = (unsigned long) fdt32_to_cpu(*(fdt32_t *)prop); 48 - else if (len == sizeof(u64)) 49 - hartid = (unsigned long) fdt64_to_cpu(__get_unaligned_t(fdt64_t, prop)); 50 - else 51 - return -EINVAL; 52 - 53 - return 0; 54 - } 55 - 56 - static efi_status_t get_boot_hartid_from_efi(void) 57 - { 58 - efi_guid_t boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID; 59 - struct riscv_efi_boot_protocol *boot_protocol; 60 - efi_status_t status; 61 - 62 - status = efi_bs_call(locate_protocol, &boot_protocol_guid, NULL, 63 - (void **)&boot_protocol); 64 - if (status != EFI_SUCCESS) 65 - return status; 66 - return efi_call_proto(boot_protocol, get_boot_hartid, &hartid); 67 - } 68 - 69 - efi_status_t check_platform_features(void) 70 - { 71 - efi_status_t status; 72 - int ret; 73 - 74 - status = get_boot_hartid_from_efi(); 75 - if (status != EFI_SUCCESS) { 76 - ret = get_boot_hartid_from_fdt(); 77 - if (ret) { 78 - efi_err("Failed to get boot hartid!\n"); 79 - return EFI_UNSUPPORTED; 80 - } 81 - } 82 - return EFI_SUCCESS; 83 - } 84 - 85 - void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt, 86 - unsigned long fdt_size) 87 - { 88 - unsigned long stext_offset = _start_kernel - _start; 89 - unsigned long kernel_entry = entrypoint + stext_offset; 90 - jump_kernel_func jump_kernel = (jump_kernel_func)kernel_entry; 91 - 92 17 /* 93 - * Jump to real kernel here with following constraints. 94 - * 1. MMU should be disabled. 95 - * 2. a0 should contain hartid 96 - * 3. a1 should DT address 18 + * When built as part of the kernel, the EFI stub cannot branch to the 19 + * kernel proper via the image header, as the PE/COFF header is 20 + * strictly not part of the in-memory presentation of the image, only 21 + * of the file representation. So instead, we need to jump to the 22 + * actual entrypoint in the .text region of the image. 97 23 */ 98 - csr_write(CSR_SATP, 0); 99 - jump_kernel(hartid, fdt); 24 + return _start_kernel - _start; 100 25 } 101 26 102 27 efi_status_t handle_kernel_image(unsigned long *image_addr, ··· 48 125 * lowest possible memory region as long as the address and size meets 49 126 * the alignment constraints. 50 127 */ 51 - preferred_addr = MIN_KIMG_ALIGN; 128 + preferred_addr = EFI_KIMG_PREFERRED_ADDRESS; 52 129 status = efi_relocate_kernel(image_addr, kernel_size, *image_size, 53 - preferred_addr, MIN_KIMG_ALIGN, 0x0); 130 + preferred_addr, efi_get_kimg_min_align(), 131 + 0x0); 54 132 55 133 if (status != EFI_SUCCESS) { 56 134 efi_err("Failed to relocate kernel\n");
+98
drivers/firmware/efi/libstub/riscv.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2020 Western Digital Corporation or its affiliates. 4 + */ 5 + 6 + #include <linux/efi.h> 7 + #include <linux/libfdt.h> 8 + 9 + #include <asm/efi.h> 10 + #include <asm/unaligned.h> 11 + 12 + #include "efistub.h" 13 + 14 + typedef void __noreturn (*jump_kernel_func)(unsigned long, unsigned long); 15 + 16 + static unsigned long hartid; 17 + 18 + static int get_boot_hartid_from_fdt(void) 19 + { 20 + const void *fdt; 21 + int chosen_node, len; 22 + const void *prop; 23 + 24 + fdt = get_efi_config_table(DEVICE_TREE_GUID); 25 + if (!fdt) 26 + return -EINVAL; 27 + 28 + chosen_node = fdt_path_offset(fdt, "/chosen"); 29 + if (chosen_node < 0) 30 + return -EINVAL; 31 + 32 + prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len); 33 + if (!prop) 34 + return -EINVAL; 35 + 36 + if (len == sizeof(u32)) 37 + hartid = (unsigned long) fdt32_to_cpu(*(fdt32_t *)prop); 38 + else if (len == sizeof(u64)) 39 + hartid = (unsigned long) fdt64_to_cpu(__get_unaligned_t(fdt64_t, prop)); 40 + else 41 + return -EINVAL; 42 + 43 + return 0; 44 + } 45 + 46 + static efi_status_t get_boot_hartid_from_efi(void) 47 + { 48 + efi_guid_t boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID; 49 + struct riscv_efi_boot_protocol *boot_protocol; 50 + efi_status_t status; 51 + 52 + status = efi_bs_call(locate_protocol, &boot_protocol_guid, NULL, 53 + (void **)&boot_protocol); 54 + if (status != EFI_SUCCESS) 55 + return status; 56 + return efi_call_proto(boot_protocol, get_boot_hartid, &hartid); 57 + } 58 + 59 + efi_status_t check_platform_features(void) 60 + { 61 + efi_status_t status; 62 + int ret; 63 + 64 + status = get_boot_hartid_from_efi(); 65 + if (status != EFI_SUCCESS) { 66 + ret = get_boot_hartid_from_fdt(); 67 + if (ret) { 68 + efi_err("Failed to get boot hartid!\n"); 69 + return EFI_UNSUPPORTED; 70 + } 71 + } 72 + return EFI_SUCCESS; 73 + } 74 + 75 + unsigned long __weak stext_offset(void) 76 + { 77 + /* 78 + * This fallback definition is used by the EFI zboot stub, which loads 79 + * the entire image so it can branch via the image header at offset #0. 80 + */ 81 + return 0; 82 + } 83 + 84 + void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt, 85 + unsigned long fdt_size) 86 + { 87 + unsigned long kernel_entry = entrypoint + stext_offset(); 88 + jump_kernel_func jump_kernel = (jump_kernel_func)kernel_entry; 89 + 90 + /* 91 + * Jump to real kernel here with following constraints. 92 + * 1. MMU should be disabled. 93 + * 2. a0 should contain hartid 94 + * 3. a1 should DT address 95 + */ 96 + csr_write(CSR_SATP, 0); 97 + jump_kernel(hartid, fdt); 98 + }
+56
drivers/firmware/efi/libstub/screen_info.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/efi.h> 4 + #include <asm/efi.h> 5 + 6 + #include "efistub.h" 7 + 8 + /* 9 + * There are two ways of populating the core kernel's struct screen_info via the stub: 10 + * - using a configuration table, like below, which relies on the EFI init code 11 + * to locate the table and copy the contents; 12 + * - by linking directly to the core kernel's copy of the global symbol. 13 + * 14 + * The latter is preferred because it makes the EFIFB earlycon available very 15 + * early, but it only works if the EFI stub is part of the core kernel image 16 + * itself. The zboot decompressor can only use the configuration table 17 + * approach. 18 + * 19 + * In order to support both methods from the same build of the EFI stub 20 + * library, provide this dummy global definition of struct screen_info. If it 21 + * is required to satisfy a link dependency, it means we need to override the 22 + * __weak alloc and free methods with the ones below, and those will be pulled 23 + * in as well. 24 + */ 25 + struct screen_info screen_info; 26 + 27 + static efi_guid_t screen_info_guid = LINUX_EFI_SCREEN_INFO_TABLE_GUID; 28 + 29 + struct screen_info *alloc_screen_info(void) 30 + { 31 + struct screen_info *si; 32 + efi_status_t status; 33 + 34 + status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, 35 + sizeof(*si), (void **)&si); 36 + 37 + if (status != EFI_SUCCESS) 38 + return NULL; 39 + 40 + status = efi_bs_call(install_configuration_table, 41 + &screen_info_guid, si); 42 + if (status == EFI_SUCCESS) 43 + return si; 44 + 45 + efi_bs_call(free_pool, si); 46 + return NULL; 47 + } 48 + 49 + void free_screen_info(struct screen_info *si) 50 + { 51 + if (!si) 52 + return; 53 + 54 + efi_bs_call(install_configuration_table, &screen_info_guid, NULL); 55 + efi_bs_call(free_pool, si); 56 + }
+92 -3
drivers/firmware/efi/libstub/string.c
··· 11 11 #include <linux/types.h> 12 12 #include <linux/string.h> 13 13 14 - #ifndef __HAVE_ARCH_STRSTR 14 + #ifndef EFI_HAVE_STRLEN 15 + /** 16 + * strlen - Find the length of a string 17 + * @s: The string to be sized 18 + */ 19 + size_t strlen(const char *s) 20 + { 21 + const char *sc; 22 + 23 + for (sc = s; *sc != '\0'; ++sc) 24 + /* nothing */; 25 + return sc - s; 26 + } 27 + #endif 28 + 29 + #ifndef EFI_HAVE_STRNLEN 30 + /** 31 + * strnlen - Find the length of a length-limited string 32 + * @s: The string to be sized 33 + * @count: The maximum number of bytes to search 34 + */ 35 + size_t strnlen(const char *s, size_t count) 36 + { 37 + const char *sc; 38 + 39 + for (sc = s; count-- && *sc != '\0'; ++sc) 40 + /* nothing */; 41 + return sc - s; 42 + } 43 + #endif 44 + 15 45 /** 16 46 * strstr - Find the first substring in a %NUL terminated string 17 47 * @s1: The string to be searched ··· 63 33 } 64 34 return NULL; 65 35 } 36 + 37 + #ifndef EFI_HAVE_STRCMP 38 + /** 39 + * strcmp - Compare two strings 40 + * @cs: One string 41 + * @ct: Another string 42 + */ 43 + int strcmp(const char *cs, const char *ct) 44 + { 45 + unsigned char c1, c2; 46 + 47 + while (1) { 48 + c1 = *cs++; 49 + c2 = *ct++; 50 + if (c1 != c2) 51 + return c1 < c2 ? -1 : 1; 52 + if (!c1) 53 + break; 54 + } 55 + return 0; 56 + } 66 57 #endif 67 58 68 - #ifndef __HAVE_ARCH_STRNCMP 69 59 /** 70 60 * strncmp - Compare two length-limited strings 71 61 * @cs: One string ··· 107 57 } 108 58 return 0; 109 59 } 110 - #endif 111 60 112 61 /* Works only for digits and letters, but small and fast */ 113 62 #define TOLOWER(x) ((x) | 0x20) ··· 162 113 163 114 return simple_strtoull(cp, endp, base); 164 115 } 116 + 117 + #ifdef CONFIG_EFI_PARAMS_FROM_FDT 118 + #ifndef EFI_HAVE_STRRCHR 119 + /** 120 + * strrchr - Find the last occurrence of a character in a string 121 + * @s: The string to be searched 122 + * @c: The character to search for 123 + */ 124 + char *strrchr(const char *s, int c) 125 + { 126 + const char *last = NULL; 127 + do { 128 + if (*s == (char)c) 129 + last = s; 130 + } while (*s++); 131 + return (char *)last; 132 + } 133 + #endif 134 + #ifndef EFI_HAVE_MEMCHR 135 + /** 136 + * memchr - Find a character in an area of memory. 137 + * @s: The memory area 138 + * @c: The byte to search for 139 + * @n: The size of the area. 140 + * 141 + * returns the address of the first occurrence of @c, or %NULL 142 + * if @c is not found 143 + */ 144 + void *memchr(const void *s, int c, size_t n) 145 + { 146 + const unsigned char *p = s; 147 + while (n-- != 0) { 148 + if ((unsigned char)c == *p++) { 149 + return (void *)(p - 1); 150 + } 151 + } 152 + return NULL; 153 + } 154 + #endif 155 + #endif
+1 -1
drivers/firmware/efi/libstub/zboot-header.S
··· 17 17 .long MZ_MAGIC 18 18 .ascii "zimg" // image type 19 19 .long __efistub__gzdata_start - .Ldoshdr // payload offset 20 - .long __efistub__gzdata_size - ZBOOT_SIZE_LEN // payload size 20 + .long __efistub__gzdata_size - 12 // payload size 21 21 .long 0, 0 // reserved 22 22 .asciz COMP_TYPE // compression type 23 23 .org .Ldoshdr + 0x3c
+78 -233
drivers/firmware/efi/libstub/zboot.c
··· 32 32 extern char efi_zboot_header[]; 33 33 extern char _gzdata_start[], _gzdata_end[]; 34 34 35 - static void log(efi_char16_t str[]) 36 - { 37 - efi_call_proto(efi_table_attr(efi_system_table, con_out), 38 - output_string, L"EFI decompressor: "); 39 - efi_call_proto(efi_table_attr(efi_system_table, con_out), 40 - output_string, str); 41 - efi_call_proto(efi_table_attr(efi_system_table, con_out), 42 - output_string, L"\n"); 43 - } 44 - 45 35 static void error(char *x) 46 36 { 47 - log(L"error() called from decompressor library\n"); 37 + efi_err("EFI decompressor: %s\n", x); 48 38 } 49 39 50 - // Local version to avoid pulling in memcmp() 51 - static bool guids_eq(const efi_guid_t *a, const efi_guid_t *b) 40 + static unsigned long alloc_preferred_address(unsigned long alloc_size) 52 41 { 53 - const u32 *l = (u32 *)a; 54 - const u32 *r = (u32 *)b; 42 + #ifdef EFI_KIMG_PREFERRED_ADDRESS 43 + efi_physical_addr_t efi_addr = EFI_KIMG_PREFERRED_ADDRESS; 55 44 56 - return l[0] == r[0] && l[1] == r[1] && l[2] == r[2] && l[3] == r[3]; 45 + if (efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 46 + alloc_size / EFI_PAGE_SIZE, &efi_addr) == EFI_SUCCESS) 47 + return efi_addr; 48 + #endif 49 + return ULONG_MAX; 57 50 } 58 51 59 - static efi_status_t __efiapi 60 - load_file(efi_load_file_protocol_t *this, efi_device_path_protocol_t *rem, 61 - bool boot_policy, unsigned long *bufsize, void *buffer) 52 + void __weak efi_cache_sync_image(unsigned long image_base, 53 + unsigned long alloc_size, 54 + unsigned long code_size) 62 55 { 63 - unsigned long compressed_size = _gzdata_end - _gzdata_start; 64 - struct efi_vendor_dev_path *vendor_dp; 65 - bool decompress = false; 66 - unsigned long size; 67 - int ret; 68 - 69 - if (rem == NULL || bufsize == NULL) 70 - return EFI_INVALID_PARAMETER; 71 - 72 - if (boot_policy) 73 - return EFI_UNSUPPORTED; 74 - 75 - // Look for our vendor media device node in the remaining file path 76 - if (rem->type == EFI_DEV_MEDIA && 77 - rem->sub_type == EFI_DEV_MEDIA_VENDOR) { 78 - vendor_dp = container_of(rem, struct efi_vendor_dev_path, header); 79 - if (!guids_eq(&vendor_dp->vendorguid, &LINUX_EFI_ZBOOT_MEDIA_GUID)) 80 - return EFI_NOT_FOUND; 81 - 82 - decompress = true; 83 - rem = (void *)(vendor_dp + 1); 84 - } 85 - 86 - if (rem->type != EFI_DEV_END_PATH || 87 - rem->sub_type != EFI_DEV_END_ENTIRE) 88 - return EFI_NOT_FOUND; 89 - 90 - // The uncompressed size of the payload is appended to the raw bit 91 - // stream, and may therefore appear misaligned in memory 92 - size = decompress ? get_unaligned_le32(_gzdata_end - 4) 93 - : compressed_size; 94 - if (buffer == NULL || *bufsize < size) { 95 - *bufsize = size; 96 - return EFI_BUFFER_TOO_SMALL; 97 - } 98 - 99 - if (decompress) { 100 - ret = __decompress(_gzdata_start, compressed_size, NULL, NULL, 101 - buffer, size, NULL, error); 102 - if (ret < 0) { 103 - log(L"Decompression failed"); 104 - return EFI_DEVICE_ERROR; 105 - } 106 - } else { 107 - memcpy(buffer, _gzdata_start, compressed_size); 108 - } 109 - 110 - return EFI_SUCCESS; 111 - } 112 - 113 - // Return the length in bytes of the device path up to the first end node. 114 - static int device_path_length(const efi_device_path_protocol_t *dp) 115 - { 116 - int len = 0; 117 - 118 - while (dp->type != EFI_DEV_END_PATH) { 119 - len += dp->length; 120 - dp = (void *)((u8 *)dp + dp->length); 121 - } 122 - return len; 123 - } 124 - 125 - static void append_rel_offset_node(efi_device_path_protocol_t **dp, 126 - unsigned long start, unsigned long end) 127 - { 128 - struct efi_rel_offset_dev_path *rodp = (void *)*dp; 129 - 130 - rodp->header.type = EFI_DEV_MEDIA; 131 - rodp->header.sub_type = EFI_DEV_MEDIA_REL_OFFSET; 132 - rodp->header.length = sizeof(struct efi_rel_offset_dev_path); 133 - rodp->reserved = 0; 134 - rodp->starting_offset = start; 135 - rodp->ending_offset = end; 136 - 137 - *dp = (void *)(rodp + 1); 138 - } 139 - 140 - static void append_ven_media_node(efi_device_path_protocol_t **dp, 141 - efi_guid_t *guid) 142 - { 143 - struct efi_vendor_dev_path *vmdp = (void *)*dp; 144 - 145 - vmdp->header.type = EFI_DEV_MEDIA; 146 - vmdp->header.sub_type = EFI_DEV_MEDIA_VENDOR; 147 - vmdp->header.length = sizeof(struct efi_vendor_dev_path); 148 - vmdp->vendorguid = *guid; 149 - 150 - *dp = (void *)(vmdp + 1); 151 - } 152 - 153 - static void append_end_node(efi_device_path_protocol_t **dp) 154 - { 155 - (*dp)->type = EFI_DEV_END_PATH; 156 - (*dp)->sub_type = EFI_DEV_END_ENTIRE; 157 - (*dp)->length = sizeof(struct efi_generic_dev_path); 158 - 159 - ++*dp; 56 + // Provided by the arch to perform the cache maintenance necessary for 57 + // executable code loaded into memory to be safe for execution. 160 58 } 161 59 162 60 asmlinkage efi_status_t __efiapi 163 61 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab) 164 62 { 165 - struct efi_mem_mapped_dev_path mmdp = { 166 - .header.type = EFI_DEV_HW, 167 - .header.sub_type = EFI_DEV_MEM_MAPPED, 168 - .header.length = sizeof(struct efi_mem_mapped_dev_path) 169 - }; 170 - efi_device_path_protocol_t *parent_dp, *dpp, *lf2_dp, *li_dp; 171 - efi_load_file2_protocol_t zboot_load_file2; 172 - efi_loaded_image_t *parent, *child; 173 - unsigned long exit_data_size; 174 - efi_handle_t child_handle; 175 - efi_handle_t zboot_handle; 176 - efi_char16_t *exit_data; 63 + unsigned long compressed_size = _gzdata_end - _gzdata_start; 64 + unsigned long image_base, alloc_size, code_size; 65 + efi_loaded_image_t *image; 177 66 efi_status_t status; 178 - void *dp_alloc; 179 - int dp_len; 67 + char *cmdline_ptr; 68 + int ret; 180 69 181 70 WRITE_ONCE(efi_system_table, systab); 182 71 183 72 free_mem_ptr = (unsigned long)&zboot_heap; 184 73 free_mem_end_ptr = free_mem_ptr + sizeof(zboot_heap); 185 74 186 - exit_data = NULL; 187 - exit_data_size = 0; 188 - 189 75 status = efi_bs_call(handle_protocol, handle, 190 - &LOADED_IMAGE_PROTOCOL_GUID, (void **)&parent); 76 + &LOADED_IMAGE_PROTOCOL_GUID, (void **)&image); 191 77 if (status != EFI_SUCCESS) { 192 - log(L"Failed to locate parent's loaded image protocol"); 78 + error("Failed to locate parent's loaded image protocol"); 193 79 return status; 194 80 } 195 81 196 - status = efi_bs_call(handle_protocol, handle, 197 - &LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID, 198 - (void **)&parent_dp); 199 - if (status != EFI_SUCCESS || parent_dp == NULL) { 200 - // Create a MemoryMapped() device path node to describe 201 - // the parent image if no device path was provided. 202 - mmdp.memory_type = parent->image_code_type; 203 - mmdp.starting_addr = (unsigned long)parent->image_base; 204 - mmdp.ending_addr = (unsigned long)parent->image_base + 205 - parent->image_size - 1; 206 - parent_dp = &mmdp.header; 207 - dp_len = sizeof(mmdp); 208 - } else { 209 - dp_len = device_path_length(parent_dp); 210 - } 211 - 212 - // Allocate some pool memory for device path protocol data 213 - status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, 214 - 2 * (dp_len + sizeof(struct efi_rel_offset_dev_path) + 215 - sizeof(struct efi_generic_dev_path)) + 216 - sizeof(struct efi_vendor_dev_path), 217 - (void **)&dp_alloc); 218 - if (status != EFI_SUCCESS) { 219 - log(L"Failed to allocate device path pool memory"); 82 + status = efi_handle_cmdline(image, &cmdline_ptr); 83 + if (status != EFI_SUCCESS) 220 84 return status; 85 + 86 + efi_info("Decompressing Linux Kernel...\n"); 87 + 88 + // SizeOfImage from the compressee's PE/COFF header 89 + alloc_size = round_up(get_unaligned_le32(_gzdata_end - 4), 90 + EFI_ALLOC_ALIGN); 91 + 92 + // SizeOfHeaders and SizeOfCode from the compressee's PE/COFF header 93 + code_size = get_unaligned_le32(_gzdata_end - 8) + 94 + get_unaligned_le32(_gzdata_end - 12); 95 + 96 + // If the architecture has a preferred address for the image, 97 + // try that first. 98 + image_base = alloc_preferred_address(alloc_size); 99 + if (image_base == ULONG_MAX) { 100 + unsigned long min_kimg_align = efi_get_kimg_min_align(); 101 + u32 seed = U32_MAX; 102 + 103 + if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { 104 + // Setting the random seed to 0x0 is the same as 105 + // allocating as low as possible 106 + seed = 0; 107 + } else if (efi_nokaslr) { 108 + efi_info("KASLR disabled on kernel command line\n"); 109 + } else { 110 + status = efi_get_random_bytes(sizeof(seed), (u8 *)&seed); 111 + if (status == EFI_NOT_FOUND) { 112 + efi_info("EFI_RNG_PROTOCOL unavailable\n"); 113 + efi_nokaslr = true; 114 + } else if (status != EFI_SUCCESS) { 115 + efi_err("efi_get_random_bytes() failed (0x%lx)\n", 116 + status); 117 + efi_nokaslr = true; 118 + } 119 + } 120 + 121 + status = efi_random_alloc(alloc_size, min_kimg_align, &image_base, 122 + seed, EFI_LOADER_CODE); 123 + if (status != EFI_SUCCESS) { 124 + efi_err("Failed to allocate memory\n"); 125 + goto free_cmdline; 126 + } 221 127 } 222 128 223 - // Create a device path describing the compressed payload in this image 224 - // <...parent_dp...>/Offset(<start>, <end>) 225 - lf2_dp = memcpy(dp_alloc, parent_dp, dp_len); 226 - dpp = (void *)((u8 *)lf2_dp + dp_len); 227 - append_rel_offset_node(&dpp, 228 - (unsigned long)(_gzdata_start - efi_zboot_header), 229 - (unsigned long)(_gzdata_end - efi_zboot_header - 1)); 230 - append_end_node(&dpp); 231 - 232 - // Create a device path describing the decompressed payload in this image 233 - // <...parent_dp...>/Offset(<start>, <end>)/VenMedia(ZBOOT_MEDIA_GUID) 234 - dp_len += sizeof(struct efi_rel_offset_dev_path); 235 - li_dp = memcpy(dpp, lf2_dp, dp_len); 236 - dpp = (void *)((u8 *)li_dp + dp_len); 237 - append_ven_media_node(&dpp, &LINUX_EFI_ZBOOT_MEDIA_GUID); 238 - append_end_node(&dpp); 239 - 240 - zboot_handle = NULL; 241 - zboot_load_file2.load_file = load_file; 242 - status = efi_bs_call(install_multiple_protocol_interfaces, 243 - &zboot_handle, 244 - &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp, 245 - &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2, 246 - NULL); 247 - if (status != EFI_SUCCESS) { 248 - log(L"Failed to install LoadFile2 protocol and device path"); 249 - goto free_dpalloc; 129 + // Decompress the payload into the newly allocated buffer. 130 + ret = __decompress(_gzdata_start, compressed_size, NULL, NULL, 131 + (void *)image_base, alloc_size, NULL, error); 132 + if (ret < 0) { 133 + error("Decompression failed"); 134 + status = EFI_DEVICE_ERROR; 135 + goto free_image; 250 136 } 251 137 252 - status = efi_bs_call(load_image, false, handle, li_dp, NULL, 0, 253 - &child_handle); 254 - if (status != EFI_SUCCESS) { 255 - log(L"Failed to load image"); 256 - goto uninstall_lf2; 257 - } 138 + efi_cache_sync_image(image_base, alloc_size, code_size); 258 139 259 - status = efi_bs_call(handle_protocol, child_handle, 260 - &LOADED_IMAGE_PROTOCOL_GUID, (void **)&child); 261 - if (status != EFI_SUCCESS) { 262 - log(L"Failed to locate child's loaded image protocol"); 263 - goto unload_image; 264 - } 140 + status = efi_stub_common(handle, image, image_base, cmdline_ptr); 265 141 266 - // Copy the kernel command line 267 - child->load_options = parent->load_options; 268 - child->load_options_size = parent->load_options_size; 269 - 270 - status = efi_bs_call(start_image, child_handle, &exit_data_size, 271 - &exit_data); 272 - if (status != EFI_SUCCESS) { 273 - log(L"StartImage() returned with error"); 274 - if (exit_data_size > 0) 275 - log(exit_data); 276 - 277 - // If StartImage() returns EFI_SECURITY_VIOLATION, the image is 278 - // not unloaded so we need to do it by hand. 279 - if (status == EFI_SECURITY_VIOLATION) 280 - unload_image: 281 - efi_bs_call(unload_image, child_handle); 282 - } 283 - 284 - uninstall_lf2: 285 - efi_bs_call(uninstall_multiple_protocol_interfaces, 286 - zboot_handle, 287 - &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp, 288 - &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2, 289 - NULL); 290 - 291 - free_dpalloc: 292 - efi_bs_call(free_pool, dp_alloc); 293 - 294 - efi_bs_call(exit, handle, status, exit_data_size, exit_data); 295 - 296 - // Free ExitData in case Exit() returned with a failure code, 297 - // but return the original status code. 298 - log(L"Exit() returned with failure code"); 299 - if (exit_data != NULL) 300 - efi_bs_call(free_pool, exit_data); 142 + free_image: 143 + efi_free(alloc_size, image_base); 144 + free_cmdline: 145 + efi_bs_call(free_pool, cmdline_ptr); 301 146 return status; 302 147 }
+1 -2
include/linux/efi.h
··· 404 404 * structure that was populated by the stub based on the GOP protocol instance 405 405 * associated with ConOut 406 406 */ 407 - #define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) 407 + #define LINUX_EFI_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) 408 408 #define LINUX_EFI_ARM_CPU_STATE_TABLE_GUID EFI_GUID(0xef79e4aa, 0x3c3d, 0x4989, 0xb9, 0x02, 0x07, 0xa9, 0x43, 0xe5, 0x50, 0xd2) 409 409 #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) 410 410 #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) ··· 412 412 #define LINUX_EFI_TPM_FINAL_LOG_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25) 413 413 #define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2) 414 414 #define LINUX_EFI_INITRD_MEDIA_GUID EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68) 415 - #define LINUX_EFI_ZBOOT_MEDIA_GUID EFI_GUID(0xe565a30d, 0x47da, 0x4dbd, 0xb3, 0x54, 0x9b, 0xb5, 0xc8, 0x4f, 0x8b, 0xe2) 416 415 #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) 417 416 #define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47) 418 417 #define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)