Skip to content

Commit 0e47076

Browse files
committed
Merge tag 'efi-next-for-v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI updates from Ard Biesheuvel: "A bit more going on than usual in the EFI subsystem. The main driver for this has been the introduction of the LoonArch architecture last cycle, which inspired some cleanup and refactoring of the EFI code. Another driver for EFI changes this cycle and in the future is confidential compute. The LoongArch architecture does not use either struct bootparams or DT natively [yet], and so passing information between the EFI stub and the core kernel using either of those is undesirable. And in general, overloading DT has been a source of issues on arm64, so using DT for this on new architectures is a to avoid for the time being (even if we might converge on something DT based for non-x86 architectures in the future). For this reason, in addition to the patch that enables EFI boot for LoongArch, there are a number of refactoring patches applied on top of which separate the DT bits from the generic EFI stub bits. These changes are on a separate topich branch that has been shared with the LoongArch maintainers, who will include it in their pull request as well. This is not ideal, but the best way to manage the conflicts without stalling LoongArch for another cycle. Another development inspired by LoongArch is the newly added support for EFI based decompressors. Instead of adding yet another arch-specific incarnation of this pattern for LoongArch, we are introducing an EFI app based on the existing EFI libstub infrastructure that encapulates the decompression code we use on other architectures, but in a way that is fully generic. This has been developed and tested in collaboration with distro and systemd folks, who are eager to start using this for systemd-boot and also for arm64 secure boot on Fedora. Note that the EFI zimage files this introduces can also be decompressed by non-EFI bootloaders if needed, as the image header describes the location of the payload inside the image, and the type of compression that was used. (Note that Fedora's arm64 GRUB is buggy [0] so you'll need a recent version or switch to systemd-boot in order to use this.) Finally, we are adding TPM measurement of the kernel command line provided by EFI. There is an oversight in the TCG spec which results in a blind spot for command line arguments passed to loaded images, which means that either the loader or the stub needs to take the measurement. Given the combinatorial explosion I am anticipating when it comes to firmware/bootloader stacks and firmware based attestation protocols (SEV-SNP, TDX, DICE, DRTM), it is good to set a baseline now when it comes to EFI measured boot, which is that the kernel measures the initrd and command line. Intermediate loaders can measure additional assets if needed, but with the baseline in place, we can deploy measured boot in a meaningful way even if you boot into Linux straight from the EFI firmware. Summary: - implement EFI boot support for LoongArch - implement generic EFI compressed boot support for arm64, RISC-V and LoongArch, none of which implement a decompressor today - measure the kernel command line into the TPM if measured boot is in effect - refactor the EFI stub code in order to isolate DT dependencies for architectures other than x86 - avoid calling SetVirtualAddressMap() on arm64 if the configured size of the VA space guarantees that doing so is unnecessary - move some ARM specific code out of the generic EFI source files - unmap kernel code from the x86 mixed mode 1:1 page tables" * tag 'efi-next-for-v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: (24 commits) efi/arm64: libstub: avoid SetVirtualAddressMap() when possible efi: zboot: create MemoryMapped() device path for the parent if needed efi: libstub: fix up the last remaining open coded boot service call efi/arm: libstub: move ARM specific code out of generic routines efi/libstub: measure EFI LoadOptions efi/libstub: refactor the initrd measuring functions efi/loongarch: libstub: remove dependency on flattened DT efi: libstub: install boot-time memory map as config table efi: libstub: remove DT dependency from generic stub efi: libstub: unify initrd loading between architectures efi: libstub: remove pointless goto kludge efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap efi: libstub: avoid efi_get_memory_map() for allocating the virt map efi: libstub: drop pointless get_memory_map() call efi: libstub: fix type confusion for load_options_size arm64: efi: enable generic EFI compressed boot loongarch: efi: enable generic EFI compressed boot riscv: efi: enable generic EFI compressed boot efi/libstub: implement generic EFI zboot efi/libstub: move efi_system_table global var into separate object ...
2 parents a6afa41 + d3549a9 commit 0e47076

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1638
-563
lines changed

Documentation/arm/uefi.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI
6565

6666
linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format.
6767

68-
linux,initrd-start 64-bit Physical start address of an initrd
69-
70-
linux,initrd-end 64-bit Physical end address of an initrd
71-
7268
kaslr-seed 64-bit Entropy used to randomize the kernel image
7369
base address location.
7470
========================== ====== ===========================================

arch/arm/include/asm/efi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#ifdef CONFIG_EFI
1919
void efi_init(void);
20+
void arm_efi_init(void);
2021

2122
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
2223
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
@@ -37,7 +38,7 @@ void efi_virtmap_load(void);
3738
void efi_virtmap_unload(void);
3839

3940
#else
40-
#define efi_init()
41+
#define arm_efi_init()
4142
#endif /* CONFIG_EFI */
4243

4344
/* arch specific definitions used by the stub code */

arch/arm/kernel/efi.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
#include <linux/efi.h>
7+
#include <linux/memblock.h>
78
#include <asm/efi.h>
89
#include <asm/mach/map.h>
910
#include <asm/mmu_context.h>
@@ -73,3 +74,81 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
7374
return efi_set_mapping_permissions(mm, md);
7475
return 0;
7576
}
77+
78+
static unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
79+
static unsigned long __initdata cpu_state_table = EFI_INVALID_TABLE_ADDR;
80+
81+
const efi_config_table_type_t efi_arch_tables[] __initconst = {
82+
{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table},
83+
{LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table},
84+
{}
85+
};
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+
110+
static void __init load_cpu_state_table(void)
111+
{
112+
if (cpu_state_table != EFI_INVALID_TABLE_ADDR) {
113+
struct efi_arm_entry_state *state;
114+
bool dump_state = true;
115+
116+
state = early_memremap_ro(cpu_state_table,
117+
sizeof(struct efi_arm_entry_state));
118+
if (state == NULL) {
119+
pr_warn("Unable to map CPU entry state table.\n");
120+
return;
121+
}
122+
123+
if ((state->sctlr_before_ebs & 1) == 0)
124+
pr_warn(FW_BUG "EFI stub was entered with MMU and Dcache disabled, please fix your firmware!\n");
125+
else if ((state->sctlr_after_ebs & 1) == 0)
126+
pr_warn(FW_BUG "ExitBootServices() returned with MMU and Dcache disabled, please fix your firmware!\n");
127+
else
128+
dump_state = false;
129+
130+
if (dump_state || efi_enabled(EFI_DBG)) {
131+
pr_info("CPSR at EFI stub entry : 0x%08x\n",
132+
state->cpsr_before_ebs);
133+
pr_info("SCTLR at EFI stub entry : 0x%08x\n",
134+
state->sctlr_before_ebs);
135+
pr_info("CPSR after ExitBootServices() : 0x%08x\n",
136+
state->cpsr_after_ebs);
137+
pr_info("SCTLR after ExitBootServices(): 0x%08x\n",
138+
state->sctlr_after_ebs);
139+
}
140+
early_memunmap(state, sizeof(struct efi_arm_entry_state));
141+
}
142+
}
143+
144+
void __init arm_efi_init(void)
145+
{
146+
efi_init();
147+
148+
load_screen_info_table();
149+
150+
/* ARM does not permit early mappings to persist across paging_init() */
151+
efi_memmap_unmap();
152+
153+
load_cpu_state_table();
154+
}

arch/arm/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ void __init setup_arch(char **cmdline_p)
11411141
#endif
11421142
setup_dma_zone(mdesc);
11431143
xen_early_init();
1144-
efi_init();
1144+
arm_efi_init();
11451145
/*
11461146
* Make sure the calculation for lowmem/highmem is set appropriately
11471147
* before reserving/allocating any memory

arch/arm64/Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,17 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
151151

152152
# Default target when executing plain make
153153
boot := arch/arm64/boot
154+
155+
ifeq ($(CONFIG_EFI_ZBOOT),)
154156
KBUILD_IMAGE := $(boot)/Image.gz
157+
else
158+
KBUILD_IMAGE := $(boot)/vmlinuz.efi
159+
endif
155160

156-
all: Image.gz
161+
all: $(notdir $(KBUILD_IMAGE))
157162

158163

159-
Image: vmlinux
164+
Image vmlinuz.efi: vmlinux
160165
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
161166

162167
Image.%: Image

arch/arm64/boot/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
Image
33
Image.gz
4+
vmlinuz*

arch/arm64/boot/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,9 @@ $(obj)/Image.lzo: $(obj)/Image FORCE
3838

3939
$(obj)/Image.zst: $(obj)/Image FORCE
4040
$(call if_changed,zstd)
41+
42+
EFI_ZBOOT_PAYLOAD := Image
43+
EFI_ZBOOT_BFD_TARGET := elf64-littleaarch64
44+
EFI_ZBOOT_MACH_TYPE := ARM64
45+
46+
include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot

arch/arm64/kernel/image-vars.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ PROVIDE(__efistub_primary_entry_offset = primary_entry - _text);
2424
*/
2525
PROVIDE(__efistub_memcmp = __pi_memcmp);
2626
PROVIDE(__efistub_memchr = __pi_memchr);
27-
PROVIDE(__efistub_memcpy = __pi_memcpy);
28-
PROVIDE(__efistub_memmove = __pi_memmove);
29-
PROVIDE(__efistub_memset = __pi_memset);
3027
PROVIDE(__efistub_strlen = __pi_strlen);
3128
PROVIDE(__efistub_strnlen = __pi_strnlen);
3229
PROVIDE(__efistub_strcmp = __pi_strcmp);
@@ -40,16 +37,6 @@ PROVIDE(__efistub__edata = _edata);
4037
PROVIDE(__efistub_screen_info = screen_info);
4138
PROVIDE(__efistub__ctype = _ctype);
4239

43-
/*
44-
* The __ prefixed memcpy/memset/memmove symbols are provided by KASAN, which
45-
* instruments the conventional ones. Therefore, any references from the EFI
46-
* stub or other position independent, low level C code should be redirected to
47-
* the non-instrumented versions as well.
48-
*/
49-
PROVIDE(__efistub___memcpy = __pi_memcpy);
50-
PROVIDE(__efistub___memmove = __pi_memmove);
51-
PROVIDE(__efistub___memset = __pi_memset);
52-
5340
PROVIDE(__pi___memcpy = __pi_memcpy);
5441
PROVIDE(__pi___memmove = __pi_memmove);
5542
PROVIDE(__pi___memset = __pi_memset);

arch/loongarch/Kconfig

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ config LOONGARCH
105105
select MODULES_USE_ELF_RELA if MODULES
106106
select NEED_PER_CPU_EMBED_FIRST_CHUNK
107107
select NEED_PER_CPU_PAGE_FIRST_CHUNK
108-
select OF
109-
select OF_EARLY_FLATTREE
110108
select PCI
111109
select PCI_DOMAINS_GENERIC
112110
select PCI_ECAM if ACPI
@@ -313,12 +311,20 @@ config DMI
313311
config EFI
314312
bool "EFI runtime service support"
315313
select UCS2_STRING
316-
select EFI_PARAMS_FROM_FDT
317314
select EFI_RUNTIME_WRAPPERS
318315
help
319316
This enables the kernel to use EFI runtime services that are
320317
available (such as the EFI variable services).
321318

319+
config EFI_STUB
320+
bool "EFI boot stub support"
321+
default y
322+
depends on EFI
323+
select EFI_GENERIC_STUB
324+
help
325+
This kernel feature allows the kernel to be loaded directly by
326+
EFI firmware without the use of a bootloader.
327+
322328
config SMP
323329
bool "Multi-Processing support"
324330
help

arch/loongarch/Makefile

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@ boot := arch/loongarch/boot
77

88
KBUILD_DEFCONFIG := loongson3_defconfig
99

10-
KBUILD_IMAGE = $(boot)/vmlinux
10+
image-name-y := vmlinux
11+
image-name-$(CONFIG_EFI_ZBOOT) := vmlinuz
12+
13+
ifndef CONFIG_EFI_STUB
14+
KBUILD_IMAGE := $(boot)/vmlinux.elf
15+
else
16+
KBUILD_IMAGE := $(boot)/$(image-name-y).efi
17+
endif
1118

1219
#
1320
# Select the object file format to substitute into the linker script.
@@ -75,6 +82,7 @@ endif
7582
head-y := arch/loongarch/kernel/head.o
7683

7784
libs-y += arch/loongarch/lib/
85+
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
7886

7987
ifeq ($(KBUILD_EXTMOD),)
8088
prepare: vdso_prepare
@@ -86,13 +94,13 @@ PHONY += vdso_install
8694
vdso_install:
8795
$(Q)$(MAKE) $(build)=arch/loongarch/vdso $@
8896

89-
all: $(KBUILD_IMAGE)
97+
all: $(notdir $(KBUILD_IMAGE))
9098

91-
$(KBUILD_IMAGE): vmlinux
92-
$(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $@
99+
vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux
100+
$(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@
93101

94102
install:
95-
$(Q)install -D -m 755 $(KBUILD_IMAGE) $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
103+
$(Q)install -D -m 755 $(KBUILD_IMAGE) $(INSTALL_PATH)/$(image-name-y)-$(KERNELRELEASE)
96104
$(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
97105
$(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
98106

0 commit comments

Comments
 (0)