linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/21] efi: Combine stub functionality with zboot decompressor
@ 2022-10-17 17:16 Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel() Ard Biesheuvel
                   ` (20 more replies)
  0 siblings, 21 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

The EFI zboot decompression code that has been merged into v6.1-rc1 is
fully generic, and relies on the EFI stub inside the encapsulated image
to implement the actual EFI boot sequence. While this works fine, it has
some drawbacks that we might prefer to fix:
- executing the EFI stub of the inner image requires that it is signed
  if secure boot is enabled, which is a bit of a hassle, given that
  signing the image must occur during the build;
- decompressing a PE/COFF image and calling LoadImage() on it means that
  it gets copied again, and potentially yet another time if the
  placement does not meet per-arch requirements.

Given that the zboot decompressor and the EFI stub are built from the
same set of objects in the libstub static library, we can make things a
bit simpler, by incorporating everything the stub does into the zboot
decompressor, and only handing off to the decompressed image after
ExitBootServices(). This removes the need for signing the inner image,
and allows us to decompress the image directly into the intended
location in memory.

This involves some refactoring, to remove the dependency on symbols that
are only defined when linking directly to vmlinux, such as string and
memory compare routines, and section boundaries of the core kernel.

While at it, remove some functionality if it's not worth the effort
making it work on both code paths, such as the EFI properties table, and
the randomization of the UEFI runtime regions.

Since image signing no longer needs to occur during the build, let's
also drop the support for invoking sbsign during the build on both the
inner image and the decompressor. (I intend to send that patch as a fix
for v6.1 so we don't add zombie Kconfig symbols to a LTS kernel)

Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Peter Jones <pjones@redhat.com>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Atish Patra <atishp@atishpatra.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Huacai Chen <chenhuacai@loongson.cn>
Cc: Xi Ruoyao <xry111@xry111.site>
Cc: Lennart Poettering <lennart@poettering.net>
Cc: Jeremy Linton <jeremy.linton@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>

Ard Biesheuvel (21):
  arm64: efi: Move dcache cleaning of loaded image out of
    efi_enter_kernel()
  arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel()
  arm64: efi: Move efi-entry.S into the libstub source directory
  efi: libstub: Remove zboot signing from build options
  efi: libstub: Drop randomization of runtime memory map
  efi: libstub: Drop handling of EFI properties table
  efi: libstub: Deduplicate ftrace command line argument filtering
  efi: libstub: Use local strncmp() implementation unconditionally
  efi: libstub: Clone memcmp() into the stub
  efi: libstub: Enable efi_printk() in zboot decompressor
  efi: loongarch: Drop exports of unused string routines
  efi: libstub: Move screen_info handling to common code
  efi: libstub: Provide local implementations of strrchr() and memchr()
  efi: libstub: Factor out EFI stub entrypoint into separate file
  efi: libstub: Add image code and data size to the zimage metadata
  efi: libstub: Factor out min alignment and preferred kernel load
    address
  efi/riscv: libstub: Split off kernel image relocation for builtin stub
  efi/arm64: libstub: Split off kernel image relocation for builtin stub
  efi/loongarch: Don't jump to kernel entry via the old image
  efi/loongarch: libstub: Split off kernel image relocation for builtin
    stub
  efi: libstub: Merge zboot decompressor with the ordinary stub

 arch/arm/include/asm/efi.h                     |   3 -
 arch/arm/kernel/efi.c                          |  31 +-
 arch/arm64/include/asm/efi.h                   |  15 +-
 arch/arm64/kernel/Makefile                     |   9 +-
 arch/arm64/kernel/efi-entry.S                  |  69 -----
 arch/arm64/kernel/image-vars.h                 |   8 -
 arch/loongarch/include/asm/efi.h               |  14 +-
 arch/loongarch/kernel/efi.c                    |  24 +-
 arch/loongarch/kernel/image-vars.h             |   8 -
 arch/riscv/include/asm/efi.h                   |  13 +-
 arch/riscv/kernel/image-vars.h                 |   6 -
 drivers/firmware/efi/Kconfig                   |  22 --
 drivers/firmware/efi/efi-init.c                |  21 +-
 drivers/firmware/efi/efi.c                     |   5 +
 drivers/firmware/efi/libstub/Makefile          |  30 +-
 drivers/firmware/efi/libstub/Makefile.zboot    |  53 +---
 drivers/firmware/efi/libstub/arm32-stub.c      |  37 ---
 drivers/firmware/efi/libstub/arm64-entry.S     |  69 +++++
 drivers/firmware/efi/libstub/arm64-stub.c      |  49 +---
 drivers/firmware/efi/libstub/arm64.c           |  61 ++++
 drivers/firmware/efi/libstub/efi-stub-entry.c  |  65 +++++
 drivers/firmware/efi/libstub/efi-stub-helper.c | 143 ---------
 drivers/firmware/efi/libstub/efi-stub.c        | 140 +++------
 drivers/firmware/efi/libstub/efistub.h         |  15 +
 drivers/firmware/efi/libstub/file.c            |  18 --
 drivers/firmware/efi/libstub/intrinsics.c      |  18 ++
 drivers/firmware/efi/libstub/loongarch-stub.c  |  89 ++----
 drivers/firmware/efi/libstub/loongarch.c       |  80 +++++
 drivers/firmware/efi/libstub/printk.c          | 154 ++++++++++
 drivers/firmware/efi/libstub/riscv-stub.c      |  96 +-----
 drivers/firmware/efi/libstub/riscv.c           |  98 +++++++
 drivers/firmware/efi/libstub/screen_info.c     |  56 ++++
 drivers/firmware/efi/libstub/string.c          |  95 +++++-
 drivers/firmware/efi/libstub/zboot-header.S    |   2 +-
 drivers/firmware/efi/libstub/zboot.c           | 307 +++++---------------
 include/linux/efi.h                            |   2 +-
 36 files changed, 972 insertions(+), 953 deletions(-)
 delete mode 100644 arch/arm64/kernel/efi-entry.S
 create mode 100644 drivers/firmware/efi/libstub/arm64-entry.S
 create mode 100644 drivers/firmware/efi/libstub/arm64.c
 create mode 100644 drivers/firmware/efi/libstub/efi-stub-entry.c
 create mode 100644 drivers/firmware/efi/libstub/loongarch.c
 create mode 100644 drivers/firmware/efi/libstub/printk.c
 create mode 100644 drivers/firmware/efi/libstub/riscv.c
 create mode 100644 drivers/firmware/efi/libstub/screen_info.c

-- 
2.35.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel()
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-18 11:27   ` Catalin Marinas
  2022-10-17 17:16 ` [PATCH 02/21] arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel() Ard Biesheuvel
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

The efi_enter_kernel() routine will be shared between the existing EFI
stub and the zboot decompressor, and the version of
dcache_clean_to_poc() that the core kernel exports to the stub will not
be available in the latter case.

So move the handling into the .c file which will remain part of the stub
build that integrates directly with the kernel proper.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/efi-entry.S             |  9 ---------
 arch/arm64/kernel/image-vars.h            |  1 -
 drivers/firmware/efi/libstub/arm64-stub.c | 10 +++++++++-
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
index 61a87fa1c305..1c1be004a271 100644
--- a/arch/arm64/kernel/efi-entry.S
+++ b/arch/arm64/kernel/efi-entry.S
@@ -23,15 +23,6 @@ SYM_CODE_START(efi_enter_kernel)
 	add	x19, x0, x2		// relocated Image entrypoint
 	mov	x20, x1			// DTB address
 
-	/*
-	 * Clean the copied Image to the PoC, and ensure it is not shadowed by
-	 * stale icache entries from before relocation.
-	 */
-	ldr	w1, =kernel_size
-	add	x1, x0, x1
-	bl	dcache_clean_poc
-	ic	ialluis
-
 	/*
 	 * Clean the remainder of this routine to the PoC
 	 * so that we can safely disable the MMU and caches.
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8151412653de..74d20835cf91 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -10,7 +10,6 @@
 #error This file should only be included in vmlinux.lds.S
 #endif
 
-PROVIDE(__efistub_kernel_size		= _edata - _text);
 PROVIDE(__efistub_primary_entry_offset	= primary_entry - _text);
 
 /*
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index 598c76c4bbaa..e767a5ac8c3d 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -157,7 +157,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 			 */
 			*image_addr = (u64)_text;
 			*reserve_size = 0;
-			return EFI_SUCCESS;
+			goto clean_image_to_poc;
 		}
 
 		status = efi_allocate_pages_aligned(*reserve_size, reserve_addr,
@@ -174,5 +174,13 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 	*image_addr = *reserve_addr;
 	memcpy((void *)*image_addr, _text, kernel_size);
 
+clean_image_to_poc:
+	/*
+	 * Clean the copied Image to the PoC, and ensure it is not shadowed by
+	 * stale icache entries from before relocation.
+	 */
+	dcache_clean_poc(*image_addr, *image_addr + kernel_size);
+	asm("ic ialluis");
+
 	return EFI_SUCCESS;
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/21] arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel()
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel() Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-18 11:57   ` Catalin Marinas
  2022-10-17 17:16 ` [PATCH 03/21] arm64: efi: Move efi-entry.S into the libstub source directory Ard Biesheuvel
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

To allow efi_enter_kernel() to be shared with the EFI zboot decompressor
build, drop another reference to dcache_clean_poc() and replace it with
a single DC CVAC instruction. To ensure that it covers the remainder of
efi_enter_kernel() as intended, reorganize the code a bit so it fits in
a 32-byte cacheline, and align it to 32 bytes. (Even though the
architecture defines 16 as the minimum D-cache line size, even the
chosen value of 32 is highly unlikely to ever be encountered on real
hardware, and this works with any line size >= 32)

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/efi-entry.S | 57 ++++++++++----------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
index 1c1be004a271..8bce13356e29 100644
--- a/arch/arm64/kernel/efi-entry.S
+++ b/arch/arm64/kernel/efi-entry.S
@@ -21,40 +21,41 @@ SYM_CODE_START(efi_enter_kernel)
 	 */
 	ldr	w2, =primary_entry_offset
 	add	x19, x0, x2		// relocated Image entrypoint
-	mov	x20, x1			// DTB address
+
+	mov	x0, x1			// DTB address
+	mov	x1, xzr
+	mov	x2, xzr
+	mov	x3, xzr
 
 	/*
 	 * Clean the remainder of this routine to the PoC
 	 * so that we can safely disable the MMU and caches.
 	 */
-	adr	x0, 0f
-	adr	x1, 3f
-	bl	dcache_clean_poc
-0:
+	adr	x4, 1f
+	dc	civac, x4
+	dsb	sy
+
 	/* Turn off Dcache and MMU */
-	mrs	x0, CurrentEL
-	cmp	x0, #CurrentEL_EL2
-	b.ne	1f
-	mrs	x0, sctlr_el2
-	bic	x0, x0, #1 << 0	// clear SCTLR.M
-	bic	x0, x0, #1 << 2	// clear SCTLR.C
-	pre_disable_mmu_workaround
-	msr	sctlr_el2, x0
-	isb
+	mrs	x4, CurrentEL
+	cmp	x4, #CurrentEL_EL2
+	mrs	x4, sctlr_el1
+	b.ne	0f
+	mrs	x4, sctlr_el2
+0:	bic	x4, x4, #SCTLR_ELx_M
+	bic	x4, x4, #SCTLR_ELx_C
+	b.eq	1f
 	b	2f
-1:
-	mrs	x0, sctlr_el1
-	bic	x0, x0, #1 << 0	// clear SCTLR.M
-	bic	x0, x0, #1 << 2	// clear SCTLR.C
-	pre_disable_mmu_workaround
-	msr	sctlr_el1, x0
+
+	.balign	32
+1:	pre_disable_mmu_workaround
+	msr	sctlr_el2, x4
 	isb
-2:
-	/* Jump to kernel entry point */
-	mov	x0, x20
-	mov	x1, xzr
-	mov	x2, xzr
-	mov	x3, xzr
-	br	x19
-3:
+	br	x19		// jump to kernel entrypoint
+
+2:	pre_disable_mmu_workaround
+	msr	sctlr_el1, x4
+	isb
+	br	x19		// jump to kernel entrypoint
+
+	.org	1b + 32
 SYM_CODE_END(efi_enter_kernel)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/21] arm64: efi: Move efi-entry.S into the libstub source directory
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel() Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 02/21] arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel() Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-18 11:57   ` Catalin Marinas
  2022-10-17 17:16 ` [PATCH 04/21] efi: libstub: Remove zboot signing from build options Ard Biesheuvel
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

We will be sharing efi-entry.S with the zboot decompressor build, which
does not link against vmlinux directly. So move it into the libstub
source directory so we can include in the libstub static library.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/Makefile                                                  | 9 +--------
 drivers/firmware/efi/libstub/Makefile                                       | 4 ++--
 arch/arm64/kernel/efi-entry.S => drivers/firmware/efi/libstub/arm64-entry.S | 4 ----
 3 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2f361a883d8c..2a3b0e4950f2 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -36,12 +36,6 @@ obj-y			:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   syscall.o proton-pack.o idreg-override.o idle.o	\
 			   patching.o
 
-targets			+= efi-entry.o
-
-OBJCOPYFLAGS := --prefix-symbols=__efistub_
-$(obj)/%.stub.o: $(obj)/%.o FORCE
-	$(call if_changed,objcopy)
-
 obj-$(CONFIG_COMPAT)			+= sys32.o signal32.o			\
 					   sys_compat.o
 obj-$(CONFIG_COMPAT)			+= sigreturn32.o
@@ -57,8 +51,7 @@ obj-$(CONFIG_CPU_PM)			+= sleep.o suspend.o
 obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
 obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 obj-$(CONFIG_KGDB)			+= kgdb.o
-obj-$(CONFIG_EFI)			+= efi.o efi-entry.stub.o		\
-					   efi-rt-wrapper.o
+obj-$(CONFIG_EFI)			+= efi.o efi-rt-wrapper.o
 obj-$(CONFIG_PCI)			+= pci.o
 obj-$(CONFIG_ARMV8_DEPRECATED)		+= armv8_deprecated.o
 obj-$(CONFIG_ACPI)			+= acpi.o
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index b1601aad7e1a..efc8cefab889 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -82,7 +82,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o string.o intrinsics.o systable.o
 
 lib-$(CONFIG_ARM)		+= arm32-stub.o
-lib-$(CONFIG_ARM64)		+= arm64-stub.o
+lib-$(CONFIG_ARM64)		+= arm64-stub.o arm64-entry.o
 lib-$(CONFIG_X86)		+= x86-stub.o
 lib-$(CONFIG_RISCV)		+= riscv-stub.o
 lib-$(CONFIG_LOONGARCH)		+= loongarch-stub.o
@@ -136,7 +136,7 @@ STUBCOPY_RELOC-$(CONFIG_ARM)	:= R_ARM_ABS
 #
 STUBCOPY_FLAGS-$(CONFIG_ARM64)	+= --prefix-alloc-sections=.init \
 				   --prefix-symbols=__efistub_
-STUBCOPY_RELOC-$(CONFIG_ARM64)	:= R_AARCH64_ABS
+STUBCOPY_RELOC-$(CONFIG_ARM64)	:= R_AARCH64_ABS64
 
 # For RISC-V, we don't need anything special other than arm64. Keep all the
 # symbols in .init section and make sure that no absolute symbols references
diff --git a/arch/arm64/kernel/efi-entry.S b/drivers/firmware/efi/libstub/arm64-entry.S
similarity index 97%
rename from arch/arm64/kernel/efi-entry.S
rename to drivers/firmware/efi/libstub/arm64-entry.S
index 8bce13356e29..87082b222a87 100644
--- a/arch/arm64/kernel/efi-entry.S
+++ b/drivers/firmware/efi/libstub/arm64-entry.S
@@ -6,12 +6,8 @@
  * Author: Mark Salter <msalter@redhat.com>
  */
 #include <linux/linkage.h>
-#include <linux/init.h>
-
 #include <asm/assembler.h>
 
-	__INIT
-
 SYM_CODE_START(efi_enter_kernel)
 	/*
 	 * efi_pe_entry() will have copied the kernel image if necessary and we
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/21] efi: libstub: Remove zboot signing from build options
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 03/21] arm64: efi: Move efi-entry.S into the libstub source directory Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 05/21] efi: libstub: Drop randomization of runtime memory map Ard Biesheuvel
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

The zboot decompressor series introduced a feature to sign the PE/COFF
kernel image for secure boot as part of the kernel build. This was
necessary because there are actually two images that need to be signed:
the kernel with the EFI stub attached, and the decompressor application.

This is a bit of a burden, because it means that the images must be
signed on the the same system that performs the build, and this is not
realistic for distros.

During the next cycle, we will introduce changes to the zboot code so
that the inner image no longer needs to be signed. This means that the
outer PE/COFF image can be handled as usual, and be signed later in the
release process.

Let's remove the associated Kconfig options now so that they don't end
up in a LTS release while already being deprecated.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/Kconfig                | 22 ---------------
 drivers/firmware/efi/libstub/Makefile.zboot | 29 +++-----------------
 2 files changed, 4 insertions(+), 47 deletions(-)

diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index fceeea74522e..0d5201e49841 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -102,28 +102,6 @@ config EFI_ZBOOT
 	  is supported by the encapsulated image. (The compression algorithm
 	  used is described in the zboot image header)
 
-config EFI_ZBOOT_SIGNED
-	def_bool y
-	depends on EFI_ZBOOT_SIGNING_CERT != ""
-	depends on EFI_ZBOOT_SIGNING_KEY != ""
-
-config EFI_ZBOOT_SIGNING
-	bool "Sign the EFI decompressor for UEFI secure boot"
-	depends on EFI_ZBOOT
-	help
-	  Use the 'sbsign' command line tool (which must exist on the host
-	  path) to sign both the EFI decompressor PE/COFF image, as well as the
-	  encapsulated PE/COFF image, which is subsequently compressed and
-	  wrapped by the former image.
-
-config EFI_ZBOOT_SIGNING_CERT
-	string "Certificate to use for signing the compressed EFI boot image"
-	depends on EFI_ZBOOT_SIGNING
-
-config EFI_ZBOOT_SIGNING_KEY
-	string "Private key to use for signing the compressed EFI boot image"
-	depends on EFI_ZBOOT_SIGNING
-
 config EFI_ARMSTUB_DTB_LOADER
 	bool "Enable the DTB loader"
 	depends on EFI_GENERIC_STUB && !RISCV && !LOONGARCH
diff --git a/drivers/firmware/efi/libstub/Makefile.zboot b/drivers/firmware/efi/libstub/Makefile.zboot
index 35f234ad8738..3340b385a05b 100644
--- a/drivers/firmware/efi/libstub/Makefile.zboot
+++ b/drivers/firmware/efi/libstub/Makefile.zboot
@@ -20,22 +20,11 @@ zboot-size-len-y			:= 4
 zboot-method-$(CONFIG_KERNEL_GZIP)	:= gzip
 zboot-size-len-$(CONFIG_KERNEL_GZIP)	:= 0
 
-quiet_cmd_sbsign = SBSIGN  $@
-      cmd_sbsign = sbsign --out $@ $< \
-		   --key $(CONFIG_EFI_ZBOOT_SIGNING_KEY) \
-		   --cert $(CONFIG_EFI_ZBOOT_SIGNING_CERT)
-
-$(obj)/$(EFI_ZBOOT_PAYLOAD).signed: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE
-	$(call if_changed,sbsign)
-
-ZBOOT_PAYLOAD-y				 := $(EFI_ZBOOT_PAYLOAD)
-ZBOOT_PAYLOAD-$(CONFIG_EFI_ZBOOT_SIGNED) := $(EFI_ZBOOT_PAYLOAD).signed
-
-$(obj)/vmlinuz: $(obj)/$(ZBOOT_PAYLOAD-y) FORCE
+$(obj)/vmlinuz: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE
 	$(call if_changed,$(zboot-method-y))
 
 OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \
-			 --rename-section .data=.gzdata,load,alloc,readonly,contents
+			  --rename-section .data=.gzdata,load,alloc,readonly,contents
 $(obj)/vmlinuz.o: $(obj)/vmlinuz FORCE
 	$(call if_changed,objcopy)
 
@@ -53,18 +42,8 @@ LDFLAGS_vmlinuz.efi.elf := -T $(srctree)/drivers/firmware/efi/libstub/zboot.lds
 $(obj)/vmlinuz.efi.elf: $(obj)/vmlinuz.o $(ZBOOT_DEPS) FORCE
 	$(call if_changed,ld)
 
-ZBOOT_EFI-y				:= vmlinuz.efi
-ZBOOT_EFI-$(CONFIG_EFI_ZBOOT_SIGNED)	:= vmlinuz.efi.unsigned
-
-OBJCOPYFLAGS_$(ZBOOT_EFI-y) := -O binary
-$(obj)/$(ZBOOT_EFI-y): $(obj)/vmlinuz.efi.elf FORCE
+OBJCOPYFLAGS_vmlinuz.efi := -O binary
+$(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.elf FORCE
 	$(call if_changed,objcopy)
 
 targets += zboot-header.o vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi
-
-ifneq ($(CONFIG_EFI_ZBOOT_SIGNED),)
-$(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.unsigned FORCE
-	$(call if_changed,sbsign)
-endif
-
-targets += $(EFI_ZBOOT_PAYLOAD).signed vmlinuz.efi.unsigned
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/21] efi: libstub: Drop randomization of runtime memory map
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (3 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 04/21] efi: libstub: Remove zboot signing from build options Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 06/21] efi: libstub: Drop handling of EFI properties table Ard Biesheuvel
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Randomizing the UEFI runtime memory map requires the use of the
SetVirtualAddressMap() EFI boot service, which we prefer to avoid. So
let's drop randomization, which was already problematic in combination
with hibernation, which means that distro kernels never enabled it in
the first place.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/efi-stub.c | 29 --------------------
 1 file changed, 29 deletions(-)

diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index cf474f0dd261..0ebfa2d9628a 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -35,15 +35,6 @@
  * as well to minimize the code churn.
  */
 #define EFI_RT_VIRTUAL_BASE	SZ_512M
-#define EFI_RT_VIRTUAL_SIZE	SZ_512M
-
-#ifdef CONFIG_ARM64
-# define EFI_RT_VIRTUAL_LIMIT	DEFAULT_MAP_WINDOW_64
-#elif defined(CONFIG_RISCV) || defined(CONFIG_LOONGARCH)
-# define EFI_RT_VIRTUAL_LIMIT	TASK_SIZE_MIN
-#else /* Only if TASK_SIZE is a constant */
-# define EFI_RT_VIRTUAL_LIMIT	TASK_SIZE
-#endif
 
 /*
  * Some architectures map the EFI regions into the kernel's linear map using a
@@ -230,26 +221,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 	efi_novamap |= !(get_supported_rt_services() &
 			 EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP);
 
-	/* hibernation expects the runtime regions to stay in the same place */
-	if (!IS_ENABLED(CONFIG_HIBERNATION) && !efi_nokaslr && !flat_va_mapping) {
-		/*
-		 * Randomize the base of the UEFI runtime services region.
-		 * Preserve the 2 MB alignment of the region by taking a
-		 * shift of 21 bit positions into account when scaling
-		 * the headroom value using a 32-bit random value.
-		 */
-		static const u64 headroom = EFI_RT_VIRTUAL_LIMIT -
-					    EFI_RT_VIRTUAL_BASE -
-					    EFI_RT_VIRTUAL_SIZE;
-		u32 rnd;
-
-		status = efi_get_random_bytes(sizeof(rnd), (u8 *)&rnd);
-		if (status == EFI_SUCCESS) {
-			virtmap_base = EFI_RT_VIRTUAL_BASE +
-				       (((headroom >> 21) * rnd) >> (32 - 21));
-		}
-	}
-
 	install_memreserve_table();
 
 	status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/21] efi: libstub: Drop handling of EFI properties table
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (4 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 05/21] efi: libstub: Drop randomization of runtime memory map Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 07/21] efi: libstub: Deduplicate ftrace command line argument filtering Ard Biesheuvel
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

The EFI properties table was a short lived experiment that never saw the
light of day on non-x86 (if at all) so let's drop the handling of it.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/efi-stub.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 0ebfa2d9628a..b55d1009d4c8 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -126,7 +126,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 	unsigned long reserve_addr = 0;
 	unsigned long reserve_size = 0;
 	struct screen_info *si;
-	efi_properties_table_t *prop_tbl;
 
 	efi_system_table = sys_table_arg;
 
@@ -205,18 +204,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 
 	efi_random_get_seed();
 
-	/*
-	 * If the NX PE data feature is enabled in the properties table, we
-	 * should take care not to create a virtual mapping that changes the
-	 * relative placement of runtime services code and data regions, as
-	 * they may belong to the same PE/COFF executable image in memory.
-	 * The easiest way to achieve that is to simply use a 1:1 mapping.
-	 */
-	prop_tbl = get_efi_config_table(EFI_PROPERTIES_TABLE_GUID);
-	flat_va_mapping |= prop_tbl &&
-			   (prop_tbl->memory_protection_attribute &
-			   EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
-
 	/* force efi_novamap if SetVirtualAddressMap() is unsupported */
 	efi_novamap |= !(get_supported_rt_services() &
 			 EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/21] efi: libstub: Deduplicate ftrace command line argument filtering
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (5 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 06/21] efi: libstub: Drop handling of EFI properties table Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 08/21] efi: libstub: Use local strncmp() implementation unconditionally Ard Biesheuvel
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

No need for the same pattern to be used four times for each architecture
individually if we can just apply it once later.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/Makefile | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index efc8cefab889..5246d69d9abf 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -18,20 +18,17 @@ cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ \
 
 # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly
 # disable the stackleak plugin
-cflags-$(CONFIG_ARM64)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
-				   -fpie $(DISABLE_STACKLEAK_PLUGIN) \
+cflags-$(CONFIG_ARM64)		:= -fpie $(DISABLE_STACKLEAK_PLUGIN) \
 				   $(call cc-option,-mbranch-protection=none)
-cflags-$(CONFIG_ARM)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
-				   -fno-builtin -fpic \
+cflags-$(CONFIG_ARM)		:= -fno-builtin -fpic \
 				   $(call cc-option,-mno-single-pic-base)
-cflags-$(CONFIG_RISCV)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
-				   -fpic
-cflags-$(CONFIG_LOONGARCH)	:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
-				   -fpie
+cflags-$(CONFIG_RISCV)		:= -fpic
+cflags-$(CONFIG_LOONGARCH)	:= -fpie
 
 cflags-$(CONFIG_EFI_PARAMS_FROM_FDT)	+= -I$(srctree)/scripts/dtc/libfdt
 
-KBUILD_CFLAGS			:= $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \
+KBUILD_CFLAGS			:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
+				   $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \
 				   -include $(srctree)/include/linux/hidden.h \
 				   -D__NO_FORTIFY \
 				   -ffreestanding \
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/21] efi: libstub: Use local strncmp() implementation unconditionally
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (6 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 07/21] efi: libstub: Deduplicate ftrace command line argument filtering Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 09/21] efi: libstub: Clone memcmp() into the stub Ard Biesheuvel
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

In preparation for moving the EFI stub functionality into the zboot
decompressor, switch to the stub's implementation of strncmp()
unconditionally.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/image-vars.h        | 1 -
 arch/riscv/kernel/image-vars.h        | 1 -
 drivers/firmware/efi/libstub/string.c | 2 --
 3 files changed, 4 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 74d20835cf91..5a12ca2d7158 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -26,7 +26,6 @@ PROVIDE(__efistub_memchr		= __pi_memchr);
 PROVIDE(__efistub_strlen		= __pi_strlen);
 PROVIDE(__efistub_strnlen		= __pi_strnlen);
 PROVIDE(__efistub_strcmp		= __pi_strcmp);
-PROVIDE(__efistub_strncmp		= __pi_strncmp);
 PROVIDE(__efistub_strrchr		= __pi_strrchr);
 PROVIDE(__efistub_dcache_clean_poc	= __pi_dcache_clean_poc);
 
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index d6e5f739905e..b46322cb5864 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -28,7 +28,6 @@ __efistub_memchr		= memchr;
 __efistub_strlen		= strlen;
 __efistub_strnlen		= strnlen;
 __efistub_strcmp		= strcmp;
-__efistub_strncmp		= strncmp;
 __efistub_strrchr		= strrchr;
 
 __efistub__start		= _start;
diff --git a/drivers/firmware/efi/libstub/string.c b/drivers/firmware/efi/libstub/string.c
index 5d13e43869ee..9f5810d86646 100644
--- a/drivers/firmware/efi/libstub/string.c
+++ b/drivers/firmware/efi/libstub/string.c
@@ -35,7 +35,6 @@ char *strstr(const char *s1, const char *s2)
 }
 #endif
 
-#ifndef __HAVE_ARCH_STRNCMP
 /**
  * strncmp - Compare two length-limited strings
  * @cs: One string
@@ -57,7 +56,6 @@ int strncmp(const char *cs, const char *ct, size_t count)
 	}
 	return 0;
 }
-#endif
 
 /* Works only for digits and letters, but small and fast */
 #define TOLOWER(x) ((x) | 0x20)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/21] efi: libstub: Clone memcmp() into the stub
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (7 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 08/21] efi: libstub: Use local strncmp() implementation unconditionally Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 10/21] efi: libstub: Enable efi_printk() in zboot decompressor Ard Biesheuvel
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

We will no longer be able to call into the kernel image once we merge
the decompressor with the EFI stub, so we need our own implementation of
memcmp(). Let's add the one from lib/string.c and simplify it.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/image-vars.h            |  1 -
 arch/loongarch/kernel/image-vars.h        |  1 -
 arch/riscv/kernel/image-vars.h            |  1 -
 drivers/firmware/efi/libstub/intrinsics.c | 18 ++++++++++++++++++
 drivers/firmware/efi/libstub/zboot.c      | 11 +----------
 5 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 5a12ca2d7158..f7c8cdf0c302 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -21,7 +21,6 @@ PROVIDE(__efistub_primary_entry_offset	= primary_entry - _text);
  * linked at. The routines below are all implemented in assembler in a
  * position independent manner
  */
-PROVIDE(__efistub_memcmp		= __pi_memcmp);
 PROVIDE(__efistub_memchr		= __pi_memchr);
 PROVIDE(__efistub_strlen		= __pi_strlen);
 PROVIDE(__efistub_strnlen		= __pi_strnlen);
diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h
index 88f5d81702df..5b6c7f079942 100644
--- a/arch/loongarch/kernel/image-vars.h
+++ b/arch/loongarch/kernel/image-vars.h
@@ -7,7 +7,6 @@
 
 #ifdef CONFIG_EFI_STUB
 
-__efistub_memcmp		= memcmp;
 __efistub_memchr		= memchr;
 __efistub_strcat		= strcat;
 __efistub_strcmp		= strcmp;
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index b46322cb5864..9229cfe0754d 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -23,7 +23,6 @@
  * linked at. The routines below are all implemented in assembler in a
  * position independent manner
  */
-__efistub_memcmp		= memcmp;
 __efistub_memchr		= memchr;
 __efistub_strlen		= strlen;
 __efistub_strnlen		= strnlen;
diff --git a/drivers/firmware/efi/libstub/intrinsics.c b/drivers/firmware/efi/libstub/intrinsics.c
index a04ab39292b6..965e734f6f98 100644
--- a/drivers/firmware/efi/libstub/intrinsics.c
+++ b/drivers/firmware/efi/libstub/intrinsics.c
@@ -28,3 +28,21 @@ void *memset(void *dst, int c, size_t len)
 	efi_bs_call(set_mem, dst, len, c & U8_MAX);
 	return dst;
 }
+
+/**
+ * memcmp - Compare two areas of memory
+ * @cs: One area of memory
+ * @ct: Another area of memory
+ * @count: The size of the area.
+ */
+#undef memcmp
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+	const unsigned char *su1, *su2;
+	int res = 0;
+
+	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+		if ((res = *su1 - *su2) != 0)
+			break;
+	return res;
+}
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index ea72c8f27da6..38173ec29cd5 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -47,15 +47,6 @@ static void error(char *x)
 	log(L"error() called from decompressor library\n");
 }
 
-// Local version to avoid pulling in memcmp()
-static bool guids_eq(const efi_guid_t *a, const efi_guid_t *b)
-{
-	const u32 *l = (u32 *)a;
-	const u32 *r = (u32 *)b;
-
-	return l[0] == r[0] && l[1] == r[1] && l[2] == r[2] && l[3] == r[3];
-}
-
 static efi_status_t __efiapi
 load_file(efi_load_file_protocol_t *this, efi_device_path_protocol_t *rem,
 	  bool boot_policy, unsigned long *bufsize, void *buffer)
@@ -76,7 +67,7 @@ load_file(efi_load_file_protocol_t *this, efi_device_path_protocol_t *rem,
 	if (rem->type == EFI_DEV_MEDIA &&
 	    rem->sub_type == EFI_DEV_MEDIA_VENDOR) {
 		vendor_dp = container_of(rem, struct efi_vendor_dev_path, header);
-		if (!guids_eq(&vendor_dp->vendorguid, &LINUX_EFI_ZBOOT_MEDIA_GUID))
+		if (efi_guidcmp(vendor_dp->vendorguid, LINUX_EFI_ZBOOT_MEDIA_GUID))
 			return EFI_NOT_FOUND;
 
 		decompress = true;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/21] efi: libstub: Enable efi_printk() in zboot decompressor
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (8 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 09/21] efi: libstub: Clone memcmp() into the stub Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 11/21] efi: loongarch: Drop exports of unused string routines Ard Biesheuvel
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Split the efi_printk() routine into its own source file, and provide
local implementations of strlen() and strnlen() so that the standalone
zboot app can efi_err and efi_info etc.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/image-vars.h                 |   2 -
 arch/loongarch/kernel/image-vars.h             |   2 -
 arch/riscv/kernel/image-vars.h                 |   2 -
 drivers/firmware/efi/libstub/Makefile          |   5 +-
 drivers/firmware/efi/libstub/efi-stub-helper.c | 143 ------------------
 drivers/firmware/efi/libstub/printk.c          | 154 ++++++++++++++++++++
 drivers/firmware/efi/libstub/string.c          |  33 ++++-
 drivers/firmware/efi/libstub/zboot.c           |  30 ++--
 8 files changed, 198 insertions(+), 173 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index f7c8cdf0c302..ace584e0b065 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -22,8 +22,6 @@ PROVIDE(__efistub_primary_entry_offset	= primary_entry - _text);
  * position independent manner
  */
 PROVIDE(__efistub_memchr		= __pi_memchr);
-PROVIDE(__efistub_strlen		= __pi_strlen);
-PROVIDE(__efistub_strnlen		= __pi_strnlen);
 PROVIDE(__efistub_strcmp		= __pi_strcmp);
 PROVIDE(__efistub_strrchr		= __pi_strrchr);
 PROVIDE(__efistub_dcache_clean_poc	= __pi_dcache_clean_poc);
diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h
index 5b6c7f079942..28bc632ec296 100644
--- a/arch/loongarch/kernel/image-vars.h
+++ b/arch/loongarch/kernel/image-vars.h
@@ -10,10 +10,8 @@
 __efistub_memchr		= memchr;
 __efistub_strcat		= strcat;
 __efistub_strcmp		= strcmp;
-__efistub_strlen		= strlen;
 __efistub_strncat		= strncat;
 __efistub_strnstr		= strnstr;
-__efistub_strnlen		= strnlen;
 __efistub_strrchr		= strrchr;
 __efistub_kernel_entry		= kernel_entry;
 __efistub_kernel_asize		= kernel_asize;
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index 9229cfe0754d..4913abd6dd10 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -24,8 +24,6 @@
  * position independent manner
  */
 __efistub_memchr		= memchr;
-__efistub_strlen		= strlen;
-__efistub_strnlen		= strnlen;
 __efistub_strcmp		= strcmp;
 __efistub_strrchr		= strrchr;
 
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 5246d69d9abf..cb600c7a14de 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -20,7 +20,8 @@ cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ \
 # disable the stackleak plugin
 cflags-$(CONFIG_ARM64)		:= -fpie $(DISABLE_STACKLEAK_PLUGIN) \
 				   $(call cc-option,-mbranch-protection=none)
-cflags-$(CONFIG_ARM)		:= -fno-builtin -fpic \
+cflags-$(CONFIG_ARM)		:= -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \
+				   -fno-builtin -fpic \
 				   $(call cc-option,-mno-single-pic-base)
 cflags-$(CONFIG_RISCV)		:= -fpic
 cflags-$(CONFIG_LOONGARCH)	:= -fpie
@@ -64,7 +65,7 @@ KCOV_INSTRUMENT			:= n
 lib-y				:= efi-stub-helper.o gop.o secureboot.o tpm.o \
 				   file.o mem.o random.o randomalloc.o pci.o \
 				   skip_spaces.o lib-cmdline.o lib-ctype.o \
-				   alignedmem.o relocate.o vsprintf.o
+				   alignedmem.o relocate.o printk.o vsprintf.o
 
 # include the stub's libfdt dependencies from lib/ when needed
 libfdt-deps			:= fdt_rw.c fdt_ro.c fdt_wip.c fdt.c \
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 54ab9638477b..01680b11d46d 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -9,10 +9,8 @@
 
 #include <linux/stdarg.h>
 
-#include <linux/ctype.h>
 #include <linux/efi.h>
 #include <linux/kernel.h>
-#include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
 #include <asm/efi.h>
 #include <asm/setup.h>
 
@@ -20,7 +18,6 @@
 
 bool efi_nochunk;
 bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE);
-int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
 bool efi_novamap;
 
 static bool efi_noinitrd;
@@ -32,146 +29,6 @@ bool __pure __efi_soft_reserve_enabled(void)
 	return !efi_nosoftreserve;
 }
 
-/**
- * efi_char16_puts() - Write a UCS-2 encoded string to the console
- * @str:	UCS-2 encoded string
- */
-void efi_char16_puts(efi_char16_t *str)
-{
-	efi_call_proto(efi_table_attr(efi_system_table, con_out),
-		       output_string, str);
-}
-
-static
-u32 utf8_to_utf32(const u8 **s8)
-{
-	u32 c32;
-	u8 c0, cx;
-	size_t clen, i;
-
-	c0 = cx = *(*s8)++;
-	/*
-	 * The position of the most-significant 0 bit gives us the length of
-	 * a multi-octet encoding.
-	 */
-	for (clen = 0; cx & 0x80; ++clen)
-		cx <<= 1;
-	/*
-	 * If the 0 bit is in position 8, this is a valid single-octet
-	 * encoding. If the 0 bit is in position 7 or positions 1-3, the
-	 * encoding is invalid.
-	 * In either case, we just return the first octet.
-	 */
-	if (clen < 2 || clen > 4)
-		return c0;
-	/* Get the bits from the first octet. */
-	c32 = cx >> clen--;
-	for (i = 0; i < clen; ++i) {
-		/* Trailing octets must have 10 in most significant bits. */
-		cx = (*s8)[i] ^ 0x80;
-		if (cx & 0xc0)
-			return c0;
-		c32 = (c32 << 6) | cx;
-	}
-	/*
-	 * Check for validity:
-	 * - The character must be in the Unicode range.
-	 * - It must not be a surrogate.
-	 * - It must be encoded using the correct number of octets.
-	 */
-	if (c32 > 0x10ffff ||
-	    (c32 & 0xf800) == 0xd800 ||
-	    clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000))
-		return c0;
-	*s8 += clen;
-	return c32;
-}
-
-/**
- * efi_puts() - Write a UTF-8 encoded string to the console
- * @str:	UTF-8 encoded string
- */
-void efi_puts(const char *str)
-{
-	efi_char16_t buf[128];
-	size_t pos = 0, lim = ARRAY_SIZE(buf);
-	const u8 *s8 = (const u8 *)str;
-	u32 c32;
-
-	while (*s8) {
-		if (*s8 == '\n')
-			buf[pos++] = L'\r';
-		c32 = utf8_to_utf32(&s8);
-		if (c32 < 0x10000) {
-			/* Characters in plane 0 use a single word. */
-			buf[pos++] = c32;
-		} else {
-			/*
-			 * Characters in other planes encode into a surrogate
-			 * pair.
-			 */
-			buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10);
-			buf[pos++] = 0xdc00 + (c32 & 0x3ff);
-		}
-		if (*s8 == '\0' || pos >= lim - 2) {
-			buf[pos] = L'\0';
-			efi_char16_puts(buf);
-			pos = 0;
-		}
-	}
-}
-
-/**
- * efi_printk() - Print a kernel message
- * @fmt:	format string
- *
- * The first letter of the format string is used to determine the logging level
- * of the message. If the level is less then the current EFI logging level, the
- * message is suppressed. The message will be truncated to 255 bytes.
- *
- * Return:	number of printed characters
- */
-int efi_printk(const char *fmt, ...)
-{
-	char printf_buf[256];
-	va_list args;
-	int printed;
-	int loglevel = printk_get_level(fmt);
-
-	switch (loglevel) {
-	case '0' ... '9':
-		loglevel -= '0';
-		break;
-	default:
-		/*
-		 * Use loglevel -1 for cases where we just want to print to
-		 * the screen.
-		 */
-		loglevel = -1;
-		break;
-	}
-
-	if (loglevel >= efi_loglevel)
-		return 0;
-
-	if (loglevel >= 0)
-		efi_puts("EFI stub: ");
-
-	fmt = printk_skip_level(fmt);
-
-	va_start(args, fmt);
-	printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
-	va_end(args);
-
-	efi_puts(printf_buf);
-	if (printed >= sizeof(printf_buf)) {
-		efi_puts("[Message truncated]\n");
-		return -1;
-	}
-
-	return printed;
-}
-
 /**
  * efi_parse_options() - Parse EFI command line options
  * @cmdline:	kernel command line
diff --git a/drivers/firmware/efi/libstub/printk.c b/drivers/firmware/efi/libstub/printk.c
new file mode 100644
index 000000000000..3a67a2cea7bd
--- /dev/null
+++ b/drivers/firmware/efi/libstub/printk.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/stdarg.h>
+
+#include <linux/ctype.h>
+#include <linux/efi.h>
+#include <linux/kernel.h>
+#include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
+#include <asm/efi.h>
+#include <asm/setup.h>
+
+#include "efistub.h"
+
+int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
+
+/**
+ * efi_char16_puts() - Write a UCS-2 encoded string to the console
+ * @str:	UCS-2 encoded string
+ */
+void efi_char16_puts(efi_char16_t *str)
+{
+	efi_call_proto(efi_table_attr(efi_system_table, con_out),
+		       output_string, str);
+}
+
+static
+u32 utf8_to_utf32(const u8 **s8)
+{
+	u32 c32;
+	u8 c0, cx;
+	size_t clen, i;
+
+	c0 = cx = *(*s8)++;
+	/*
+	 * The position of the most-significant 0 bit gives us the length of
+	 * a multi-octet encoding.
+	 */
+	for (clen = 0; cx & 0x80; ++clen)
+		cx <<= 1;
+	/*
+	 * If the 0 bit is in position 8, this is a valid single-octet
+	 * encoding. If the 0 bit is in position 7 or positions 1-3, the
+	 * encoding is invalid.
+	 * In either case, we just return the first octet.
+	 */
+	if (clen < 2 || clen > 4)
+		return c0;
+	/* Get the bits from the first octet. */
+	c32 = cx >> clen--;
+	for (i = 0; i < clen; ++i) {
+		/* Trailing octets must have 10 in most significant bits. */
+		cx = (*s8)[i] ^ 0x80;
+		if (cx & 0xc0)
+			return c0;
+		c32 = (c32 << 6) | cx;
+	}
+	/*
+	 * Check for validity:
+	 * - The character must be in the Unicode range.
+	 * - It must not be a surrogate.
+	 * - It must be encoded using the correct number of octets.
+	 */
+	if (c32 > 0x10ffff ||
+	    (c32 & 0xf800) == 0xd800 ||
+	    clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000))
+		return c0;
+	*s8 += clen;
+	return c32;
+}
+
+/**
+ * efi_puts() - Write a UTF-8 encoded string to the console
+ * @str:	UTF-8 encoded string
+ */
+void efi_puts(const char *str)
+{
+	efi_char16_t buf[128];
+	size_t pos = 0, lim = ARRAY_SIZE(buf);
+	const u8 *s8 = (const u8 *)str;
+	u32 c32;
+
+	while (*s8) {
+		if (*s8 == '\n')
+			buf[pos++] = L'\r';
+		c32 = utf8_to_utf32(&s8);
+		if (c32 < 0x10000) {
+			/* Characters in plane 0 use a single word. */
+			buf[pos++] = c32;
+		} else {
+			/*
+			 * Characters in other planes encode into a surrogate
+			 * pair.
+			 */
+			buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10);
+			buf[pos++] = 0xdc00 + (c32 & 0x3ff);
+		}
+		if (*s8 == '\0' || pos >= lim - 2) {
+			buf[pos] = L'\0';
+			efi_char16_puts(buf);
+			pos = 0;
+		}
+	}
+}
+
+/**
+ * efi_printk() - Print a kernel message
+ * @fmt:	format string
+ *
+ * The first letter of the format string is used to determine the logging level
+ * of the message. If the level is less then the current EFI logging level, the
+ * message is suppressed. The message will be truncated to 255 bytes.
+ *
+ * Return:	number of printed characters
+ */
+int efi_printk(const char *fmt, ...)
+{
+	char printf_buf[256];
+	va_list args;
+	int printed;
+	int loglevel = printk_get_level(fmt);
+
+	switch (loglevel) {
+	case '0' ... '9':
+		loglevel -= '0';
+		break;
+	default:
+		/*
+		 * Use loglevel -1 for cases where we just want to print to
+		 * the screen.
+		 */
+		loglevel = -1;
+		break;
+	}
+
+	if (loglevel >= efi_loglevel)
+		return 0;
+
+	if (loglevel >= 0)
+		efi_puts("EFI stub: ");
+
+	fmt = printk_skip_level(fmt);
+
+	va_start(args, fmt);
+	printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
+	va_end(args);
+
+	efi_puts(printf_buf);
+	if (printed >= sizeof(printf_buf)) {
+		efi_puts("[Message truncated]\n");
+		return -1;
+	}
+
+	return printed;
+}
diff --git a/drivers/firmware/efi/libstub/string.c b/drivers/firmware/efi/libstub/string.c
index 9f5810d86646..5a1519d435bf 100644
--- a/drivers/firmware/efi/libstub/string.c
+++ b/drivers/firmware/efi/libstub/string.c
@@ -11,7 +11,37 @@
 #include <linux/types.h>
 #include <linux/string.h>
 
-#ifndef __HAVE_ARCH_STRSTR
+#ifndef EFI_HAVE_STRLEN
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char *s)
+{
+	const char *sc;
+
+	for (sc = s; *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+#endif
+
+#ifndef EFI_HAVE_STRNLEN
+/**
+ * strnlen - Find the length of a length-limited string
+ * @s: The string to be sized
+ * @count: The maximum number of bytes to search
+ */
+size_t strnlen(const char *s, size_t count)
+{
+	const char *sc;
+
+	for (sc = s; count-- && *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+#endif
+
 /**
  * strstr - Find the first substring in a %NUL terminated string
  * @s1: The string to be searched
@@ -33,7 +63,6 @@ char *strstr(const char *s1, const char *s2)
 	}
 	return NULL;
 }
-#endif
 
 /**
  * strncmp - Compare two length-limited strings
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 38173ec29cd5..5f41a5b17d6e 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -32,19 +32,9 @@ static unsigned long free_mem_ptr, free_mem_end_ptr;
 extern char efi_zboot_header[];
 extern char _gzdata_start[], _gzdata_end[];
 
-static void log(efi_char16_t str[])
-{
-	efi_call_proto(efi_table_attr(efi_system_table, con_out),
-		       output_string, L"EFI decompressor: ");
-	efi_call_proto(efi_table_attr(efi_system_table, con_out),
-		       output_string, str);
-	efi_call_proto(efi_table_attr(efi_system_table, con_out),
-		       output_string, L"\n");
-}
-
 static void error(char *x)
 {
-	log(L"error() called from decompressor library\n");
+	efi_err("EFI decompressor: %s\n", x);
 }
 
 static efi_status_t __efiapi
@@ -91,7 +81,7 @@ load_file(efi_load_file_protocol_t *this, efi_device_path_protocol_t *rem,
 		ret = __decompress(_gzdata_start, compressed_size, NULL, NULL,
 				   buffer, size, NULL, error);
 		if (ret	< 0) {
-			log(L"Decompression failed");
+			error("Decompression failed");
 			return EFI_DEVICE_ERROR;
 		}
 	} else {
@@ -180,7 +170,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 	status = efi_bs_call(handle_protocol, handle,
 			     &LOADED_IMAGE_PROTOCOL_GUID, (void **)&parent);
 	if (status != EFI_SUCCESS) {
-		log(L"Failed to locate parent's loaded image protocol");
+		error("Failed to locate parent's loaded image protocol");
 		return status;
 	}
 
@@ -207,7 +197,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 			     sizeof(struct efi_vendor_dev_path),
 			     (void **)&dp_alloc);
 	if (status != EFI_SUCCESS) {
-		log(L"Failed to allocate device path pool memory");
+		error("Failed to allocate device path pool memory");
 		return status;
 	}
 
@@ -236,21 +226,21 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 			     &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2,
 			     NULL);
 	if (status != EFI_SUCCESS) {
-		log(L"Failed to install LoadFile2 protocol and device path");
+		error("Failed to install LoadFile2 protocol and device path");
 		goto free_dpalloc;
 	}
 
 	status = efi_bs_call(load_image, false, handle, li_dp, NULL, 0,
 			     &child_handle);
 	if (status != EFI_SUCCESS) {
-		log(L"Failed to load image");
+		error("Failed to load image");
 		goto uninstall_lf2;
 	}
 
 	status = efi_bs_call(handle_protocol, child_handle,
 			     &LOADED_IMAGE_PROTOCOL_GUID, (void **)&child);
 	if (status != EFI_SUCCESS) {
-		log(L"Failed to locate child's loaded image protocol");
+		error("Failed to locate child's loaded image protocol");
 		goto unload_image;
 	}
 
@@ -261,9 +251,9 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 	status = efi_bs_call(start_image, child_handle, &exit_data_size,
 			     &exit_data);
 	if (status != EFI_SUCCESS) {
-		log(L"StartImage() returned with error");
+		error("StartImage() returned with error:");
 		if (exit_data_size > 0)
-			log(exit_data);
+			efi_err("%ls\n", exit_data);
 
 		// If StartImage() returns EFI_SECURITY_VIOLATION, the image is
 		// not unloaded so we need to do it by hand.
@@ -286,7 +276,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 
 	// Free ExitData in case Exit() returned with a failure code,
 	// but return the original status code.
-	log(L"Exit() returned with failure code");
+	error("Exit() returned with failure code");
 	if (exit_data != NULL)
 		efi_bs_call(free_pool, exit_data);
 	return status;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 11/21] efi: loongarch: Drop exports of unused string routines
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (9 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 10/21] efi: libstub: Enable efi_printk() in zboot decompressor Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 12/21] efi: libstub: Move screen_info handling to common code Ard Biesheuvel
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Drop the __efistub_ prefixed exports of various routines that the EFI
stub on LoongArch does not even use.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/loongarch/kernel/image-vars.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h
index 28bc632ec296..e561989d02de 100644
--- a/arch/loongarch/kernel/image-vars.h
+++ b/arch/loongarch/kernel/image-vars.h
@@ -7,12 +7,7 @@
 
 #ifdef CONFIG_EFI_STUB
 
-__efistub_memchr		= memchr;
-__efistub_strcat		= strcat;
 __efistub_strcmp		= strcmp;
-__efistub_strncat		= strncat;
-__efistub_strnstr		= strnstr;
-__efistub_strrchr		= strrchr;
 __efistub_kernel_entry		= kernel_entry;
 __efistub_kernel_asize		= kernel_asize;
 __efistub_kernel_fsize		= kernel_fsize;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 12/21] efi: libstub: Move screen_info handling to common code
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (10 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 11/21] efi: loongarch: Drop exports of unused string routines Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 13/21] efi: libstub: Provide local implementations of strrchr() and memchr() Ard Biesheuvel
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Currently, arm64, RISC-V and LoongArch rely on the fact that struct
screen_info can be accessed directly, due to the fact that the EFI stub
and the core kernel are part of the same image. This will change after a
future patch, so let's ensure that the screen_info handling is able to
deal with this, by adopting the arm32 approach of passing it as a
configuration table. While at it, switch to ACPI reclaim memory to hold
the screen_info data, which is more appropriate for this kind of
allocation.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm/include/asm/efi.h                 |  3 --
 arch/arm/kernel/efi.c                      | 31 ++---------
 arch/arm64/include/asm/efi.h               |  6 ---
 arch/loongarch/include/asm/efi.h           |  9 ----
 arch/loongarch/kernel/efi.c                | 24 ++++++++-
 arch/riscv/include/asm/efi.h               |  6 ---
 drivers/firmware/efi/efi-init.c            | 21 ++++++--
 drivers/firmware/efi/efi.c                 |  5 ++
 drivers/firmware/efi/libstub/Makefile      |  3 +-
 drivers/firmware/efi/libstub/arm32-stub.c  | 37 -------------
 drivers/firmware/efi/libstub/efi-stub.c    |  9 ++++
 drivers/firmware/efi/libstub/efistub.h     |  3 ++
 drivers/firmware/efi/libstub/screen_info.c | 56 ++++++++++++++++++++
 include/linux/efi.h                        |  2 +-
 14 files changed, 121 insertions(+), 94 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 4bdd930167c0..b95241b1ca65 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -43,9 +43,6 @@ void efi_virtmap_unload(void);
 
 /* arch specific definitions used by the stub code */
 
-struct screen_info *alloc_screen_info(void);
-void free_screen_info(struct screen_info *si);
-
 /*
  * A reasonable upper bound for the uncompressed kernel size is 32 MBytes,
  * so we will reserve that amount of memory. We have no easy way to tell what
diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
index e50ad7eefc02..882104f43b3b 100644
--- a/arch/arm/kernel/efi.c
+++ b/arch/arm/kernel/efi.c
@@ -75,38 +75,13 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
 	return 0;
 }
 
-static unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
 static unsigned long __initdata cpu_state_table = EFI_INVALID_TABLE_ADDR;
 
 const efi_config_table_type_t efi_arch_tables[] __initconst = {
-	{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table},
 	{LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table},
 	{}
 };
 
-static void __init load_screen_info_table(void)
-{
-	struct screen_info *si;
-
-	if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
-		si = early_memremap_ro(screen_info_table, sizeof(*si));
-		if (!si) {
-			pr_err("Could not map screen_info config table\n");
-			return;
-		}
-		screen_info = *si;
-		early_memunmap(si, sizeof(*si));
-
-		/* dummycon on ARM needs non-zero values for columns/lines */
-		screen_info.orig_video_cols = 80;
-		screen_info.orig_video_lines = 25;
-
-		if (memblock_is_map_memory(screen_info.lfb_base))
-			memblock_mark_nomap(screen_info.lfb_base,
-					    screen_info.lfb_size);
-	}
-}
-
 static void __init load_cpu_state_table(void)
 {
 	if (cpu_state_table != EFI_INVALID_TABLE_ADDR) {
@@ -145,7 +120,11 @@ void __init arm_efi_init(void)
 {
 	efi_init();
 
-	load_screen_info_table();
+	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) {
+		/* dummycon on ARM needs non-zero values for columns/lines */
+		screen_info.orig_video_cols = 80;
+		screen_info.orig_video_lines = 25;
+	}
 
 	/* ARM does not permit early mappings to persist across paging_init() */
 	efi_memmap_unmap();
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 439e2bc5d5d8..af35ad671754 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -76,12 +76,6 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 	return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
 }
 
-#define alloc_screen_info(x...)		&screen_info
-
-static inline void free_screen_info(struct screen_info *si)
-{
-}
-
 #define EFI_ALLOC_ALIGN		SZ_64K
 
 /*
diff --git a/arch/loongarch/include/asm/efi.h b/arch/loongarch/include/asm/efi.h
index 174567b00ddb..60d6a170c18d 100644
--- a/arch/loongarch/include/asm/efi.h
+++ b/arch/loongarch/include/asm/efi.h
@@ -19,15 +19,6 @@ void efifb_setup_from_dmi(struct screen_info *si, const char *opt);
 #define EFI_ALLOC_ALIGN		SZ_64K
 #define EFI_RT_VIRTUAL_OFFSET	CSR_DMW0_BASE
 
-static inline struct screen_info *alloc_screen_info(void)
-{
-	return &screen_info;
-}
-
-static inline void free_screen_info(struct screen_info *si)
-{
-}
-
 static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 {
 	return ULONG_MAX;
diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c
index a31329971133..d75ce73e8ff8 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -52,6 +52,27 @@ void __init efi_runtime_init(void)
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 }
 
+unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
+
+static void __init init_screen_info(void)
+{
+	struct screen_info *si;
+
+	if (screen_info_table == EFI_INVALID_TABLE_ADDR)
+		return;
+
+	si = early_memremap(screen_info_table, sizeof(*si));
+	if (!si) {
+		pr_err("Could not map screen_info config table\n");
+		return;
+	}
+	screen_info = *si;
+	memset(si, 0, sizeof(*si));
+	early_memunmap(si, sizeof(*si));
+
+	memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
+}
+
 void __init efi_init(void)
 {
 	int size;
@@ -80,8 +101,7 @@ void __init efi_init(void)
 
 	set_bit(EFI_CONFIG_TABLES, &efi.flags);
 
-	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI)
-		memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
+	init_screen_info();
 
 	if (boot_memmap == EFI_INVALID_TABLE_ADDR)
 		return;
diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h
index f74879a8f1ea..d0570936cb8c 100644
--- a/arch/riscv/include/asm/efi.h
+++ b/arch/riscv/include/asm/efi.h
@@ -31,12 +31,6 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 	return ULONG_MAX;
 }
 
-#define alloc_screen_info(x...)		(&screen_info)
-
-static inline void free_screen_info(struct screen_info *si)
-{
-}
-
 void efi_virtmap_load(void);
 void efi_virtmap_unload(void);
 
diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index 2fd770b499a3..1639159493e3 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -22,6 +22,8 @@
 
 #include <asm/efi.h>
 
+unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
+
 static int __init is_memory(efi_memory_desc_t *md)
 {
 	if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC))
@@ -55,9 +57,22 @@ extern __weak const efi_config_table_type_t efi_arch_tables[];
 
 static void __init init_screen_info(void)
 {
-	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI &&
-	    memblock_is_map_memory(screen_info.lfb_base))
-		memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size);
+	struct screen_info *si;
+
+	if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
+		si = early_memremap(screen_info_table, sizeof(*si));
+		if (!si) {
+			pr_err("Could not map screen_info config table\n");
+			return;
+		}
+		screen_info = *si;
+		memset(si, 0, sizeof(*si));
+		early_memunmap(si, sizeof(*si));
+
+		if (memblock_is_map_memory(screen_info.lfb_base))
+			memblock_mark_nomap(screen_info.lfb_base,
+					    screen_info.lfb_size);
+	}
 }
 
 static int __init uefi_init(u64 efi_system_table)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 9624735f1575..84a3e52fe888 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -58,6 +58,8 @@ static unsigned long __initdata mem_reserve = EFI_INVALID_TABLE_ADDR;
 static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR;
 static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;
 
+extern unsigned long screen_info_table;
+
 struct mm_struct efi_mm = {
 	.mm_mt			= MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock),
 	.mm_users		= ATOMIC_INIT(2),
@@ -544,6 +546,9 @@ static const efi_config_table_type_t common_tables[] __initconst = {
 #endif
 #ifdef CONFIG_EFI_COCO_SECRET
 	{LINUX_EFI_COCO_SECRET_AREA_GUID,	&efi.coco_secret,	"CocoSecret"	},
+#endif
+#ifdef CONFIG_EFI_GENERIC_STUB
+	{LINUX_EFI_SCREEN_INFO_TABLE_GUID,	&screen_info_table			},
 #endif
 	{},
 };
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index cb600c7a14de..53304e9c6778 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -77,7 +77,8 @@ lib-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdt.o \
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
-lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o string.o intrinsics.o systable.o
+lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o string.o intrinsics.o systable.o \
+				   screen_info.o
 
 lib-$(CONFIG_ARM)		+= arm32-stub.o
 lib-$(CONFIG_ARM64)		+= arm64-stub.o arm64-entry.o
diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c
index 0131e3aaa605..1073dd947516 100644
--- a/drivers/firmware/efi/libstub/arm32-stub.c
+++ b/drivers/firmware/efi/libstub/arm32-stub.c
@@ -76,43 +76,6 @@ void efi_handle_post_ebs_state(void)
 		      &efi_entry_state->sctlr_after_ebs);
 }
 
-static efi_guid_t screen_info_guid = LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID;
-
-struct screen_info *alloc_screen_info(void)
-{
-	struct screen_info *si;
-	efi_status_t status;
-
-	/*
-	 * Unlike on arm64, where we can directly fill out the screen_info
-	 * structure from the stub, we need to allocate a buffer to hold
-	 * its contents while we hand over to the kernel proper from the
-	 * decompressor.
-	 */
-	status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
-			     sizeof(*si), (void **)&si);
-
-	if (status != EFI_SUCCESS)
-		return NULL;
-
-	status = efi_bs_call(install_configuration_table,
-			     &screen_info_guid, si);
-	if (status == EFI_SUCCESS)
-		return si;
-
-	efi_bs_call(free_pool, si);
-	return NULL;
-}
-
-void free_screen_info(struct screen_info *si)
-{
-	if (!si)
-		return;
-
-	efi_bs_call(install_configuration_table, &screen_info_guid, NULL);
-	efi_bs_call(free_pool, si);
-}
-
 efi_status_t handle_kernel_image(unsigned long *image_addr,
 				 unsigned long *image_size,
 				 unsigned long *reserve_addr,
diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index b55d1009d4c8..8521dc09c6ae 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -47,6 +47,15 @@
 static u64 virtmap_base = EFI_RT_VIRTUAL_BASE;
 static bool flat_va_mapping = (EFI_RT_VIRTUAL_OFFSET != 0);
 
+struct screen_info * __weak alloc_screen_info(void)
+{
+	return &screen_info;
+}
+
+void __weak free_screen_info(struct screen_info *si)
+{
+}
+
 static struct screen_info *setup_graphics(void)
 {
 	efi_guid_t gop_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 313647b1c196..215186a29ab9 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1027,4 +1027,7 @@ efi_enable_reset_attack_mitigation(void) { }
 
 void efi_retrieve_tpm2_eventlog(void);
 
+struct screen_info *alloc_screen_info(void);
+void free_screen_info(struct screen_info *si);
+
 #endif
diff --git a/drivers/firmware/efi/libstub/screen_info.c b/drivers/firmware/efi/libstub/screen_info.c
new file mode 100644
index 000000000000..8e76a8b384ba
--- /dev/null
+++ b/drivers/firmware/efi/libstub/screen_info.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "efistub.h"
+
+/*
+ * There are two ways of populating the core kernel's struct screen_info via the stub:
+ * - using a configuration table, like below, which relies on the EFI init code
+ *   to locate the table and copy the contents;
+ * - by linking directly to the core kernel's copy of the global symbol.
+ *
+ * The latter is preferred because it makes the EFIFB earlycon available very
+ * early, but it only works if the EFI stub is part of the core kernel image
+ * itself. The zboot decompressor can only use the configuration table
+ * approach.
+ *
+ * In order to support both methods from the same build of the EFI stub
+ * library, provide this dummy global definition of struct screen_info. If it
+ * is required to satisfy a link dependency, it means we need to override the
+ * __weak alloc and free methods with the ones below, and those will be pulled
+ * in as well.
+ */
+struct screen_info screen_info;
+
+static efi_guid_t screen_info_guid = LINUX_EFI_SCREEN_INFO_TABLE_GUID;
+
+struct screen_info *alloc_screen_info(void)
+{
+	struct screen_info *si;
+	efi_status_t status;
+
+	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
+			     sizeof(*si), (void **)&si);
+
+	if (status != EFI_SUCCESS)
+		return NULL;
+
+	status = efi_bs_call(install_configuration_table,
+			     &screen_info_guid, si);
+	if (status == EFI_SUCCESS)
+		return si;
+
+	efi_bs_call(free_pool, si);
+	return NULL;
+}
+
+void free_screen_info(struct screen_info *si)
+{
+	if (!si)
+		return;
+
+	efi_bs_call(install_configuration_table, &screen_info_guid, NULL);
+	efi_bs_call(free_pool, si);
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 256e70e42114..ca3278077670 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -404,7 +404,7 @@ void efi_native_runtime_setup(void);
  * structure that was populated by the stub based on the GOP protocol instance
  * associated with ConOut
  */
-#define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID	EFI_GUID(0xe03fc20a, 0x85dc, 0x406e,  0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95)
+#define LINUX_EFI_SCREEN_INFO_TABLE_GUID	EFI_GUID(0xe03fc20a, 0x85dc, 0x406e,  0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95)
 #define LINUX_EFI_ARM_CPU_STATE_TABLE_GUID	EFI_GUID(0xef79e4aa, 0x3c3d, 0x4989,  0xb9, 0x02, 0x07, 0xa9, 0x43, 0xe5, 0x50, 0xd2)
 #define LINUX_EFI_LOADER_ENTRY_GUID		EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf,  0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
 #define LINUX_EFI_RANDOM_SEED_TABLE_GUID	EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2,  0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 13/21] efi: libstub: Provide local implementations of strrchr() and memchr()
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (11 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 12/21] efi: libstub: Move screen_info handling to common code Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 14/21] efi: libstub: Factor out EFI stub entrypoint into separate file Ard Biesheuvel
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Clone the implementations of strrchr() and memchr() in lib/string.c so
we can use them in the standalone zboot decompressor app. These routines
are used by the FDT handling code.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/image-vars.h        |  3 -
 arch/riscv/kernel/image-vars.h        |  2 -
 drivers/firmware/efi/libstub/Makefile |  2 +
 drivers/firmware/efi/libstub/string.c | 62 ++++++++++++++++++++
 4 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index ace584e0b065..f31130ba0233 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -21,9 +21,6 @@ PROVIDE(__efistub_primary_entry_offset	= primary_entry - _text);
  * linked at. The routines below are all implemented in assembler in a
  * position independent manner
  */
-PROVIDE(__efistub_memchr		= __pi_memchr);
-PROVIDE(__efistub_strcmp		= __pi_strcmp);
-PROVIDE(__efistub_strrchr		= __pi_strrchr);
 PROVIDE(__efistub_dcache_clean_poc	= __pi_dcache_clean_poc);
 
 PROVIDE(__efistub__text			= _text);
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
index 4913abd6dd10..7e2962ef73f9 100644
--- a/arch/riscv/kernel/image-vars.h
+++ b/arch/riscv/kernel/image-vars.h
@@ -23,9 +23,7 @@
  * linked at. The routines below are all implemented in assembler in a
  * position independent manner
  */
-__efistub_memchr		= memchr;
 __efistub_strcmp		= strcmp;
-__efistub_strrchr		= strrchr;
 
 __efistub__start		= _start;
 __efistub__start_kernel		= _start_kernel;
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 53304e9c6778..6824ee5a4ae6 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -21,6 +21,8 @@ cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ \
 cflags-$(CONFIG_ARM64)		:= -fpie $(DISABLE_STACKLEAK_PLUGIN) \
 				   $(call cc-option,-mbranch-protection=none)
 cflags-$(CONFIG_ARM)		:= -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \
+				   -DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \
+				   -DEFI_HAVE_STRCMP \
 				   -fno-builtin -fpic \
 				   $(call cc-option,-mno-single-pic-base)
 cflags-$(CONFIG_RISCV)		:= -fpic
diff --git a/drivers/firmware/efi/libstub/string.c b/drivers/firmware/efi/libstub/string.c
index 5a1519d435bf..168fe8e79abc 100644
--- a/drivers/firmware/efi/libstub/string.c
+++ b/drivers/firmware/efi/libstub/string.c
@@ -64,6 +64,28 @@ char *strstr(const char *s1, const char *s2)
 	return NULL;
 }
 
+#ifndef EFI_HAVE_STRCMP
+/**
+ * strcmp - Compare two strings
+ * @cs: One string
+ * @ct: Another string
+ */
+int strcmp(const char *cs, const char *ct)
+{
+	unsigned char c1, c2;
+
+	while (1) {
+		c1 = *cs++;
+		c2 = *ct++;
+		if (c1 != c2)
+			return c1 < c2 ? -1 : 1;
+		if (!c1)
+			break;
+	}
+	return 0;
+}
+#endif
+
 /**
  * strncmp - Compare two length-limited strings
  * @cs: One string
@@ -140,3 +162,43 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)
 
 	return simple_strtoull(cp, endp, base);
 }
+
+#ifdef CONFIG_EFI_PARAMS_FROM_FDT
+#ifndef EFI_HAVE_STRRCHR
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char *strrchr(const char *s, int c)
+{
+	const char *last = NULL;
+	do {
+		if (*s == (char)c)
+			last = s;
+	} while (*s++);
+	return (char *)last;
+}
+#endif
+#ifndef EFI_HAVE_MEMCHR
+/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+	const unsigned char *p = s;
+	while (n-- != 0) {
+		if ((unsigned char)c == *p++) {
+			return (void *)(p - 1);
+		}
+	}
+	return NULL;
+}
+#endif
+#endif
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 14/21] efi: libstub: Factor out EFI stub entrypoint into separate file
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (12 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 13/21] efi: libstub: Provide local implementations of strrchr() and memchr() Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 15/21] efi: libstub: Add image code and data size to the zimage metadata Ard Biesheuvel
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

In preparation for allowing the EFI zboot decompressor to reuse most of
the EFI stub machinery, factor out the actual EFI PE/COFF entrypoint
into a separate file.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/Makefile         |  3 +-
 drivers/firmware/efi/libstub/efi-stub-entry.c | 65 ++++++++++++++
 drivers/firmware/efi/libstub/efi-stub.c       | 89 ++++++--------------
 drivers/firmware/efi/libstub/efistub.h        |  8 ++
 4 files changed, 101 insertions(+), 64 deletions(-)

diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 6824ee5a4ae6..d5d6c6239f9c 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -67,7 +67,8 @@ KCOV_INSTRUMENT			:= n
 lib-y				:= efi-stub-helper.o gop.o secureboot.o tpm.o \
 				   file.o mem.o random.o randomalloc.o pci.o \
 				   skip_spaces.o lib-cmdline.o lib-ctype.o \
-				   alignedmem.o relocate.o printk.o vsprintf.o
+				   alignedmem.o relocate.o printk.o vsprintf.o \
+				   efi-stub-entry.o
 
 # include the stub's libfdt dependencies from lib/ when needed
 libfdt-deps			:= fdt_rw.c fdt_ro.c fdt_wip.c fdt.c \
diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c
new file mode 100644
index 000000000000..5245c4f031c0
--- /dev/null
+++ b/drivers/firmware/efi/libstub/efi-stub-entry.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "efistub.h"
+
+/*
+ * EFI entry point for the generic EFI stub used by ARM, arm64, RISC-V and
+ * LoongArch. This is the entrypoint that is described in the PE/COFF header
+ * of the core kernel.
+ */
+efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
+				   efi_system_table_t *systab)
+{
+	efi_loaded_image_t *image;
+	efi_status_t status;
+	unsigned long image_addr;
+	unsigned long image_size = 0;
+	/* addr/point and size pairs for memory management*/
+	char *cmdline_ptr = NULL;
+	efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
+	unsigned long reserve_addr = 0;
+	unsigned long reserve_size = 0;
+
+	WRITE_ONCE(efi_system_table, systab);
+
+	/* Check if we were booted by the EFI firmware */
+	if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
+		return EFI_INVALID_PARAMETER;
+
+	/*
+	 * Get a handle to the loaded image protocol.  This is used to get
+	 * information about the running image, such as size and the command
+	 * line.
+	 */
+	status = efi_bs_call(handle_protocol, handle, &loaded_image_proto,
+			     (void *)&image);
+	if (status != EFI_SUCCESS) {
+		efi_err("Failed to get loaded image protocol\n");
+		return status;
+	}
+
+	status = efi_handle_cmdline(image, &cmdline_ptr);
+	if (status != EFI_SUCCESS)
+		return status;
+
+	efi_info("Booting Linux Kernel...\n");
+
+	status = handle_kernel_image(&image_addr, &image_size,
+				     &reserve_addr,
+				     &reserve_size,
+				     image, handle);
+	if (status != EFI_SUCCESS) {
+		efi_err("Failed to relocate kernel\n");
+		return status;
+	}
+
+	status = efi_stub_common(handle, image, image_addr, cmdline_ptr);
+
+	efi_free(image_size, image_addr);
+	efi_free(reserve_size, reserve_addr);
+
+	return status;
+}
diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 8521dc09c6ae..2955c1ac6a36 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -115,61 +115,21 @@ static u32 get_supported_rt_services(void)
 	return supported;
 }
 
-/*
- * EFI entry point for the arm/arm64 EFI stubs.  This is the entrypoint
- * that is described in the PE/COFF header.  Most of the code is the same
- * for both archictectures, with the arch-specific code provided in the
- * handle_kernel_image() function.
- */
-efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
-				   efi_system_table_t *sys_table_arg)
+efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr)
 {
-	efi_loaded_image_t *image;
-	efi_status_t status;
-	unsigned long image_addr;
-	unsigned long image_size = 0;
-	/* addr/point and size pairs for memory management*/
-	char *cmdline_ptr = NULL;
 	int cmdline_size = 0;
-	efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
-	unsigned long reserve_addr = 0;
-	unsigned long reserve_size = 0;
-	struct screen_info *si;
-
-	efi_system_table = sys_table_arg;
-
-	/* Check if we were booted by the EFI firmware */
-	if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
-		status = EFI_INVALID_PARAMETER;
-		goto fail;
-	}
-
-	status = check_platform_features();
-	if (status != EFI_SUCCESS)
-		goto fail;
-
-	/*
-	 * Get a handle to the loaded image protocol.  This is used to get
-	 * information about the running image, such as size and the command
-	 * line.
-	 */
-	status = efi_bs_call(handle_protocol, handle, &loaded_image_proto,
-			     (void *)&image);
-	if (status != EFI_SUCCESS) {
-		efi_err("Failed to get loaded image protocol\n");
-		goto fail;
-	}
+	efi_status_t status;
+	char *cmdline;
 
 	/*
 	 * Get the command line from EFI, using the LOADED_IMAGE
 	 * protocol. We are going to copy the command line into the
 	 * device tree, so this can be allocated anywhere.
 	 */
-	cmdline_ptr = efi_convert_cmdline(image, &cmdline_size);
-	if (!cmdline_ptr) {
+	cmdline = efi_convert_cmdline(image, &cmdline_size);
+	if (!cmdline) {
 		efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
-		status = EFI_OUT_OF_RESOURCES;
-		goto fail;
+		return EFI_OUT_OF_RESOURCES;
 	}
 
 	if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
@@ -183,25 +143,34 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 	}
 
 	if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0) {
-		status = efi_parse_options(cmdline_ptr);
+		status = efi_parse_options(cmdline);
 		if (status != EFI_SUCCESS) {
 			efi_err("Failed to parse options\n");
 			goto fail_free_cmdline;
 		}
 	}
 
-	efi_info("Booting Linux Kernel...\n");
+	*cmdline_ptr = cmdline;
+	return EFI_SUCCESS;
 
-	si = setup_graphics();
+fail_free_cmdline:
+	efi_bs_call(free_pool, cmdline_ptr);
+	return status;
+}
 
-	status = handle_kernel_image(&image_addr, &image_size,
-				     &reserve_addr,
-				     &reserve_size,
-				     image, handle);
-	if (status != EFI_SUCCESS) {
-		efi_err("Failed to relocate kernel\n");
-		goto fail_free_screeninfo;
-	}
+efi_status_t efi_stub_common(efi_handle_t handle,
+			     efi_loaded_image_t *image,
+			     unsigned long image_addr,
+			     char *cmdline_ptr)
+{
+	struct screen_info *si;
+	efi_status_t status;
+
+	status = check_platform_features();
+	if (status != EFI_SUCCESS)
+		return status;
+
+	si = setup_graphics();
 
 	efi_retrieve_tpm2_eventlog();
 
@@ -221,13 +190,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 
 	status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr);
 
-	efi_free(image_size, image_addr);
-	efi_free(reserve_size, reserve_addr);
-fail_free_screeninfo:
 	free_screen_info(si);
-fail_free_cmdline:
-	efi_bs_call(free_pool, cmdline_ptr);
-fail:
 	return status;
 }
 
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 215186a29ab9..a2fc0727880a 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1010,6 +1010,14 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 				 efi_loaded_image_t *image,
 				 efi_handle_t image_handle);
 
+/* shared entrypoint between the normal stub and the zboot stub */
+efi_status_t efi_stub_common(efi_handle_t handle,
+			     efi_loaded_image_t *image,
+			     unsigned long image_addr,
+			     char *cmdline_ptr);
+
+efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr);
+
 asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint,
 					    unsigned long fdt_addr,
 					    unsigned long fdt_size);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 15/21] efi: libstub: Add image code and data size to the zimage metadata
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (13 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 14/21] efi: libstub: Factor out EFI stub entrypoint into separate file Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 16/21] efi: libstub: Factor out min alignment and preferred kernel load address Ard Biesheuvel
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

In order to be able to switch from LoadImage() [which treats the
supplied PE/COFF image as file input only, and reconstructs the memory
image based on the section descriptors] to a mode where we allocate the
memory directly, and invoke the image in place, we need to now how much
memory to allocate beyond the end of the image. So copy this information
from the payload's PE/COFF header to the end of the compressed version
of the payload, so that the decompressor app can access it before
performing the decompression itself.

We'll also need to size of the code region once we switch arm64 to
jumping to the kernel proper with MMU and caches enabled, so let's
capture that information as well. Note that SizeOfCode does not account
for the header, so we need SizeOfHeaders as well.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/Makefile.zboot | 26 +++++++++-----------
 drivers/firmware/efi/libstub/zboot-header.S |  2 +-
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/firmware/efi/libstub/Makefile.zboot b/drivers/firmware/efi/libstub/Makefile.zboot
index 3340b385a05b..c5d11473ef80 100644
--- a/drivers/firmware/efi/libstub/Makefile.zboot
+++ b/drivers/firmware/efi/libstub/Makefile.zboot
@@ -10,18 +10,17 @@ comp-type-$(CONFIG_KERNEL_LZO)		:= lzo
 comp-type-$(CONFIG_KERNEL_XZ)		:= xzkern
 comp-type-$(CONFIG_KERNEL_ZSTD)		:= zstd22
 
-# in GZIP, the appended le32 carrying the uncompressed size is part of the
-# format, but in other cases, we just append it at the end for convenience,
-# causing the original tools to complain when checking image integrity.
-# So disregard it when calculating the payload size in the zimage header.
-zboot-method-y				:= $(comp-type-y)_with_size
-zboot-size-len-y			:= 4
-
-zboot-method-$(CONFIG_KERNEL_GZIP)	:= gzip
-zboot-size-len-$(CONFIG_KERNEL_GZIP)	:= 0
-
-$(obj)/vmlinuz: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE
-	$(call if_changed,$(zboot-method-y))
+# Copy the SizeOfHeaders, SizeOfCode and SizeOfImage fields from the payload to
+# the end of the compressed image. Note that this presupposes a PE header
+# offset of 64 bytes, which is what arm64, RISC-V and LoongArch use.
+quiet_cmd_pesize = PESIZE  $@
+      cmd_pesize = ( dd status=none if=$< bs=1 count=4 skip=148 ; \
+		     dd status=none if=$< bs=1 count=4 skip=92 ; \
+		     dd status=none if=$< bs=1 count=4 skip=144 ) >> $@
+
+$(obj)/vmlinuz: $(obj)/$(EFI_ZBOOT_PAYLOAD)
+	$(call cmd,$(comp-type-y))
+	$(call cmd,pesize)
 
 OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \
 			  --rename-section .data=.gzdata,load,alloc,readonly,contents
@@ -30,7 +29,6 @@ $(obj)/vmlinuz.o: $(obj)/vmlinuz FORCE
 
 AFLAGS_zboot-header.o += -DMACHINE_TYPE=IMAGE_FILE_MACHINE_$(EFI_ZBOOT_MACH_TYPE) \
 			 -DZBOOT_EFI_PATH="\"$(realpath $(obj)/vmlinuz.efi.elf)\"" \
-			 -DZBOOT_SIZE_LEN=$(zboot-size-len-y) \
 			 -DCOMP_TYPE="\"$(comp-type-y)\""
 
 $(obj)/zboot-header.o: $(srctree)/drivers/firmware/efi/libstub/zboot-header.S FORCE
@@ -46,4 +44,4 @@ OBJCOPYFLAGS_vmlinuz.efi := -O binary
 $(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.elf FORCE
 	$(call if_changed,objcopy)
 
-targets += zboot-header.o vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi
+targets += zboot-header.o vmlinuz.o vmlinuz.efi.elf vmlinuz.efi
diff --git a/drivers/firmware/efi/libstub/zboot-header.S b/drivers/firmware/efi/libstub/zboot-header.S
index 9e6fe061ab07..bc2d7750d7f1 100644
--- a/drivers/firmware/efi/libstub/zboot-header.S
+++ b/drivers/firmware/efi/libstub/zboot-header.S
@@ -17,7 +17,7 @@ __efistub_efi_zboot_header:
 	.long		MZ_MAGIC
 	.ascii		"zimg"					// image type
 	.long		__efistub__gzdata_start - .Ldoshdr	// payload offset
-	.long		__efistub__gzdata_size - ZBOOT_SIZE_LEN	// payload size
+	.long		__efistub__gzdata_size - 12		// payload size
 	.long		0, 0					// reserved
 	.asciz		COMP_TYPE				// compression type
 	.org		.Ldoshdr + 0x3c
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 16/21] efi: libstub: Factor out min alignment and preferred kernel load address
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (14 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 15/21] efi: libstub: Add image code and data size to the zimage metadata Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 17/21] efi/riscv: libstub: Split off kernel image relocation for builtin stub Ard Biesheuvel
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Factor out the expressions that describe the preferred placement of the
loaded image as well as the minimum alignment so we can reuse them in
the decompressor.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/include/asm/efi.h                  | 15 +++++++++++++++
 arch/loongarch/include/asm/efi.h              |  7 +++++++
 arch/riscv/include/asm/efi.h                  | 11 +++++++++++
 drivers/firmware/efi/libstub/arm64-stub.c     | 11 +----------
 drivers/firmware/efi/libstub/loongarch-stub.c |  3 ++-
 drivers/firmware/efi/libstub/riscv-stub.c     | 15 +++------------
 6 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index af35ad671754..108b115dbf5b 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -76,6 +76,21 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 	return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
 }
 
+static inline unsigned long efi_get_kimg_min_align(void)
+{
+	extern bool efi_nokaslr;
+
+	/*
+	 * Although relocatable kernels can fix up the misalignment with
+	 * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are
+	 * subtly out of sync with those recorded in the vmlinux when kaslr is
+	 * disabled but the image required relocation anyway. Therefore retain
+	 * 2M alignment if KASLR was explicitly disabled, even if it was not
+	 * going to be activated to begin with.
+	 */
+	return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN;
+}
+
 #define EFI_ALLOC_ALIGN		SZ_64K
 
 /*
diff --git a/arch/loongarch/include/asm/efi.h b/arch/loongarch/include/asm/efi.h
index 60d6a170c18d..5a470c8d2bbc 100644
--- a/arch/loongarch/include/asm/efi.h
+++ b/arch/loongarch/include/asm/efi.h
@@ -24,4 +24,11 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 	return ULONG_MAX;
 }
 
+static inline unsigned long efi_get_kimg_min_align(void)
+{
+	return SZ_2M;
+}
+
+#define EFI_KIMG_PREFERRED_ADDRESS	PHYSADDR(VMLINUX_LOAD_ADDRESS)
+
 #endif /* _ASM_LOONGARCH_EFI_H */
diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h
index d0570936cb8c..a742868eb23c 100644
--- a/arch/riscv/include/asm/efi.h
+++ b/arch/riscv/include/asm/efi.h
@@ -31,6 +31,17 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
 	return ULONG_MAX;
 }
 
+static inline unsigned long efi_get_kimg_min_align(void)
+{
+	/*
+	 * RISC-V requires the kernel image to placed 2 MB aligned base for 64
+	 * bit and 4MB for 32 bit.
+	 */
+	return IS_ENABLED(CONFIG_64BIT) ? SZ_2M : SZ_4M;
+}
+
+#define EFI_KIMG_PREFERRED_ADDRESS	efi_get_kimg_min_align()
+
 void efi_virtmap_load(void);
 void efi_virtmap_unload(void);
 
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index e767a5ac8c3d..dd21b7b7309a 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -88,16 +88,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 	efi_status_t status;
 	unsigned long kernel_size, kernel_memsize = 0;
 	u32 phys_seed = 0;
-
-	/*
-	 * Although relocatable kernels can fix up the misalignment with
-	 * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are
-	 * subtly out of sync with those recorded in the vmlinux when kaslr is
-	 * disabled but the image required relocation anyway. Therefore retain
-	 * 2M alignment if KASLR was explicitly disabled, even if it was not
-	 * going to be activated to begin with.
-	 */
-	u64 min_kimg_align = efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN;
+	u64 min_kimg_align = efi_get_kimg_min_align();
 
 	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
 		efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID;
diff --git a/drivers/firmware/efi/libstub/loongarch-stub.c b/drivers/firmware/efi/libstub/loongarch-stub.c
index 32329f2a92f9..a2e55e5c4003 100644
--- a/drivers/firmware/efi/libstub/loongarch-stub.c
+++ b/drivers/firmware/efi/libstub/loongarch-stub.c
@@ -35,7 +35,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 	kernel_addr = (unsigned long)&kernel_offset - kernel_offset;
 
 	status = efi_relocate_kernel(&kernel_addr, kernel_fsize, kernel_asize,
-				     PHYSADDR(VMLINUX_LOAD_ADDRESS), SZ_2M, 0x0);
+				     EFI_KIMG_PREFERRED_ADDRESS,
+				     efi_get_kimg_min_align(), 0x0);
 
 	*image_addr = kernel_addr;
 	*image_size = kernel_asize;
diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c
index b450ebf95977..c5a551f69a7f 100644
--- a/drivers/firmware/efi/libstub/riscv-stub.c
+++ b/drivers/firmware/efi/libstub/riscv-stub.c
@@ -12,16 +12,6 @@
 
 #include "efistub.h"
 
-/*
- * RISC-V requires the kernel image to placed 2 MB aligned base for 64 bit and
- * 4MB for 32 bit.
- */
-#ifdef CONFIG_64BIT
-#define MIN_KIMG_ALIGN		SZ_2M
-#else
-#define MIN_KIMG_ALIGN		SZ_4M
-#endif
-
 typedef void __noreturn (*jump_kernel_func)(unsigned long, unsigned long);
 
 static unsigned long hartid;
@@ -125,9 +115,10 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 	 * lowest possible memory region as long as the address and size meets
 	 * the alignment constraints.
 	 */
-	preferred_addr = MIN_KIMG_ALIGN;
+	preferred_addr = EFI_KIMG_PREFERRED_ADDRESS;
 	status = efi_relocate_kernel(image_addr, kernel_size, *image_size,
-				     preferred_addr, MIN_KIMG_ALIGN, 0x0);
+				     preferred_addr, efi_get_kimg_min_align(),
+				     0x0);
 
 	if (status != EFI_SUCCESS) {
 		efi_err("Failed to relocate kernel\n");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 17/21] efi/riscv: libstub: Split off kernel image relocation for builtin stub
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (15 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 16/21] efi: libstub: Factor out min alignment and preferred kernel load address Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 18/21] efi/arm64: " Ard Biesheuvel
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

The RISC-V build of the EFI stub is part of the core kernel image, and
therefore accesses section markers directly when it needs to figure out
the size of the various section.

The zboot decompressor does not have access to those symbols, but
doesn't really need that either. So let's move handle_kernel_image()
into a separate file (or rather, move everything else into a separate
file) so that the zboot build does not pull in unused code that links to
symbols that it does not define.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/riscv/include/asm/efi.h              |  2 +
 drivers/firmware/efi/libstub/Makefile     |  2 +-
 drivers/firmware/efi/libstub/riscv-stub.c | 81 ++--------------
 drivers/firmware/efi/libstub/riscv.c      | 98 ++++++++++++++++++++
 4 files changed, 108 insertions(+), 75 deletions(-)

diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h
index a742868eb23c..6cbc7437d886 100644
--- a/arch/riscv/include/asm/efi.h
+++ b/arch/riscv/include/asm/efi.h
@@ -45,4 +45,6 @@ static inline unsigned long efi_get_kimg_min_align(void)
 void efi_virtmap_load(void);
 void efi_virtmap_unload(void);
 
+unsigned long stext_offset(void);
+
 #endif /* _ASM_EFI_H */
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index d5d6c6239f9c..28c8300c6a61 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -86,7 +86,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o string.o intrinsics.o systable.o \
 lib-$(CONFIG_ARM)		+= arm32-stub.o
 lib-$(CONFIG_ARM64)		+= arm64-stub.o arm64-entry.o
 lib-$(CONFIG_X86)		+= x86-stub.o
-lib-$(CONFIG_RISCV)		+= riscv-stub.o
+lib-$(CONFIG_RISCV)		+= riscv.o riscv-stub.o
 lib-$(CONFIG_LOONGARCH)		+= loongarch-stub.o
 
 CFLAGS_arm32-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c
index c5a551f69a7f..145c9f0ba217 100644
--- a/drivers/firmware/efi/libstub/riscv-stub.c
+++ b/drivers/firmware/efi/libstub/riscv-stub.c
@@ -4,7 +4,6 @@
  */
 
 #include <linux/efi.h>
-#include <linux/libfdt.h>
 
 #include <asm/efi.h>
 #include <asm/sections.h>
@@ -12,82 +11,16 @@
 
 #include "efistub.h"
 
-typedef void __noreturn (*jump_kernel_func)(unsigned long, unsigned long);
-
-static unsigned long hartid;
-
-static int get_boot_hartid_from_fdt(void)
-{
-	const void *fdt;
-	int chosen_node, len;
-	const void *prop;
-
-	fdt = get_efi_config_table(DEVICE_TREE_GUID);
-	if (!fdt)
-		return -EINVAL;
-
-	chosen_node = fdt_path_offset(fdt, "/chosen");
-	if (chosen_node < 0)
-		return -EINVAL;
-
-	prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len);
-	if (!prop)
-		return -EINVAL;
-
-	if (len == sizeof(u32))
-		hartid = (unsigned long) fdt32_to_cpu(*(fdt32_t *)prop);
-	else if (len == sizeof(u64))
-		hartid = (unsigned long) fdt64_to_cpu(__get_unaligned_t(fdt64_t, prop));
-	else
-		return -EINVAL;
-
-	return 0;
-}
-
-static efi_status_t get_boot_hartid_from_efi(void)
+unsigned long stext_offset(void)
 {
-	efi_guid_t boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID;
-	struct riscv_efi_boot_protocol *boot_protocol;
-	efi_status_t status;
-
-	status = efi_bs_call(locate_protocol, &boot_protocol_guid, NULL,
-			     (void **)&boot_protocol);
-	if (status != EFI_SUCCESS)
-		return status;
-	return efi_call_proto(boot_protocol, get_boot_hartid, &hartid);
-}
-
-efi_status_t check_platform_features(void)
-{
-	efi_status_t status;
-	int ret;
-
-	status = get_boot_hartid_from_efi();
-	if (status != EFI_SUCCESS) {
-		ret = get_boot_hartid_from_fdt();
-		if (ret) {
-			efi_err("Failed to get boot hartid!\n");
-			return EFI_UNSUPPORTED;
-		}
-	}
-	return EFI_SUCCESS;
-}
-
-void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt,
-				 unsigned long fdt_size)
-{
-	unsigned long stext_offset = _start_kernel - _start;
-	unsigned long kernel_entry = entrypoint + stext_offset;
-	jump_kernel_func jump_kernel = (jump_kernel_func)kernel_entry;
-
 	/*
-	 * Jump to real kernel here with following constraints.
-	 * 1. MMU should be disabled.
-	 * 2. a0 should contain hartid
-	 * 3. a1 should DT address
+	 * When built as part of the kernel, the EFI stub cannot branch to the
+	 * kernel proper via the image header, as the PE/COFF header is
+	 * strictly not part of the in-memory presentation of the image, only
+	 * of the file representation. So instead, we need to jump to the
+	 * actual entrypoint in the .text region of the image.
 	 */
-	csr_write(CSR_SATP, 0);
-	jump_kernel(hartid, fdt);
+	return _start_kernel - _start;
 }
 
 efi_status_t handle_kernel_image(unsigned long *image_addr,
diff --git a/drivers/firmware/efi/libstub/riscv.c b/drivers/firmware/efi/libstub/riscv.c
new file mode 100644
index 000000000000..8022b104c3e6
--- /dev/null
+++ b/drivers/firmware/efi/libstub/riscv.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#include <linux/efi.h>
+#include <linux/libfdt.h>
+
+#include <asm/efi.h>
+#include <asm/unaligned.h>
+
+#include "efistub.h"
+
+typedef void __noreturn (*jump_kernel_func)(unsigned long, unsigned long);
+
+static unsigned long hartid;
+
+static int get_boot_hartid_from_fdt(void)
+{
+	const void *fdt;
+	int chosen_node, len;
+	const void *prop;
+
+	fdt = get_efi_config_table(DEVICE_TREE_GUID);
+	if (!fdt)
+		return -EINVAL;
+
+	chosen_node = fdt_path_offset(fdt, "/chosen");
+	if (chosen_node < 0)
+		return -EINVAL;
+
+	prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len);
+	if (!prop)
+		return -EINVAL;
+
+	if (len == sizeof(u32))
+		hartid = (unsigned long) fdt32_to_cpu(*(fdt32_t *)prop);
+	else if (len == sizeof(u64))
+		hartid = (unsigned long) fdt64_to_cpu(__get_unaligned_t(fdt64_t, prop));
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static efi_status_t get_boot_hartid_from_efi(void)
+{
+	efi_guid_t boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID;
+	struct riscv_efi_boot_protocol *boot_protocol;
+	efi_status_t status;
+
+	status = efi_bs_call(locate_protocol, &boot_protocol_guid, NULL,
+			     (void **)&boot_protocol);
+	if (status != EFI_SUCCESS)
+		return status;
+	return efi_call_proto(boot_protocol, get_boot_hartid, &hartid);
+}
+
+efi_status_t check_platform_features(void)
+{
+	efi_status_t status;
+	int ret;
+
+	status = get_boot_hartid_from_efi();
+	if (status != EFI_SUCCESS) {
+		ret = get_boot_hartid_from_fdt();
+		if (ret) {
+			efi_err("Failed to get boot hartid!\n");
+			return EFI_UNSUPPORTED;
+		}
+	}
+	return EFI_SUCCESS;
+}
+
+unsigned long __weak stext_offset(void)
+{
+	/*
+	 * This fallback definition is used by the EFI zboot stub, which loads
+	 * the entire image so it can branch via the image header at offset #0.
+	 */
+	return 0;
+}
+
+void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt,
+				 unsigned long fdt_size)
+{
+	unsigned long kernel_entry = entrypoint + stext_offset();
+	jump_kernel_func jump_kernel = (jump_kernel_func)kernel_entry;
+
+	/*
+	 * Jump to real kernel here with following constraints.
+	 * 1. MMU should be disabled.
+	 * 2. a0 should contain hartid
+	 * 3. a1 should DT address
+	 */
+	csr_write(CSR_SATP, 0);
+	jump_kernel(hartid, fdt);
+}
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 18/21] efi/arm64: libstub: Split off kernel image relocation for builtin stub
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (16 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 17/21] efi/riscv: libstub: Split off kernel image relocation for builtin stub Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 19/21] efi/loongarch: Don't jump to kernel entry via the old image Ard Biesheuvel
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

The arm64 build of the EFI stub is part of the core kernel image, and
therefore accesses section markers directly when it needs to figure out
the size of the various section.

The zboot decompressor does not have access to those symbols, but
doesn't really need that either. So let's move handle_kernel_image()
into a separate file (or rather, move everything else into a separate
file) so that the zboot build does not pull in unused code that links to
symbols that it does not define.

While at it, introduce a helper routine that the generic zboot loader
will need to invoke after decompressing the image but before invoking
it, to ensure that the I-side view of memory is consistent.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/Makefile      |  2 +-
 drivers/firmware/efi/libstub/arm64-entry.S | 12 ++++
 drivers/firmware/efi/libstub/arm64-stub.c  | 28 ---------
 drivers/firmware/efi/libstub/arm64.c       | 61 ++++++++++++++++++++
 drivers/firmware/efi/libstub/efistub.h     |  4 ++
 5 files changed, 78 insertions(+), 29 deletions(-)

diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 28c8300c6a61..ee24b222489c 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -84,7 +84,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o string.o intrinsics.o systable.o \
 				   screen_info.o
 
 lib-$(CONFIG_ARM)		+= arm32-stub.o
-lib-$(CONFIG_ARM64)		+= arm64-stub.o arm64-entry.o
+lib-$(CONFIG_ARM64)		+= arm64.o arm64-stub.o arm64-entry.o
 lib-$(CONFIG_X86)		+= x86-stub.o
 lib-$(CONFIG_RISCV)		+= riscv.o riscv-stub.o
 lib-$(CONFIG_LOONGARCH)		+= loongarch-stub.o
diff --git a/drivers/firmware/efi/libstub/arm64-entry.S b/drivers/firmware/efi/libstub/arm64-entry.S
index 87082b222a87..ec5492a738fe 100644
--- a/drivers/firmware/efi/libstub/arm64-entry.S
+++ b/drivers/firmware/efi/libstub/arm64-entry.S
@@ -8,6 +8,18 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
+	/*
+	 * The entrypoint of a arm64 bare metal image is at offset #0 of the
+	 * image, so this is a reasonable default for primary_entry_offset.
+	 * Only when the EFI stub is integrated into the core kernel, it is not
+	 * guaranteed that the PE/COFF header has been copied to memory too, so
+	 * in this case, primary_entry_offset should be overridden by the
+	 * linker and point to primary_entry() directly.
+	 */
+	.globl	primary_entry_offset
+	.weak	primary_entry_offset
+	.set	primary_entry_offset, 0
+
 SYM_CODE_START(efi_enter_kernel)
 	/*
 	 * efi_pe_entry() will have copied the kernel image if necessary and we
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index dd21b7b7309a..7f0aab3a8ab3 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -11,37 +11,9 @@
 #include <asm/efi.h>
 #include <asm/memory.h>
 #include <asm/sections.h>
-#include <asm/sysreg.h>
 
 #include "efistub.h"
 
-efi_status_t check_platform_features(void)
-{
-	u64 tg;
-
-	/*
-	 * If we have 48 bits of VA space for TTBR0 mappings, we can map the
-	 * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is
-	 * unnecessary.
-	 */
-	if (VA_BITS_MIN >= 48)
-		efi_novamap = true;
-
-	/* UEFI mandates support for 4 KB granularity, no need to check */
-	if (IS_ENABLED(CONFIG_ARM64_4K_PAGES))
-		return EFI_SUCCESS;
-
-	tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_EL1_TGRAN_SHIFT) & 0xf;
-	if (tg < ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX) {
-		if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
-			efi_err("This 64 KB granular kernel is not supported by your CPU\n");
-		else
-			efi_err("This 16 KB granular kernel is not supported by your CPU\n");
-		return EFI_UNSUPPORTED;
-	}
-	return EFI_SUCCESS;
-}
-
 /*
  * Distro versions of GRUB may ignore the BSS allocation entirely (i.e., fail
  * to provide space, and fail to zero it). Check for this condition by double
diff --git a/drivers/firmware/efi/libstub/arm64.c b/drivers/firmware/efi/libstub/arm64.c
new file mode 100644
index 000000000000..d2e94972c5fa
--- /dev/null
+++ b/drivers/firmware/efi/libstub/arm64.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2013, 2014 Linaro Ltd;  <roy.franz@linaro.org>
+ *
+ * This file implements the EFI boot stub for the arm64 kernel.
+ * Adapted from ARM version by Mark Salter <msalter@redhat.com>
+ */
+
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include <asm/memory.h>
+#include <asm/sysreg.h>
+
+#include "efistub.h"
+
+efi_status_t check_platform_features(void)
+{
+	u64 tg;
+
+	/*
+	 * If we have 48 bits of VA space for TTBR0 mappings, we can map the
+	 * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is
+	 * unnecessary.
+	 */
+	if (VA_BITS_MIN >= 48)
+		efi_novamap = true;
+
+	/* UEFI mandates support for 4 KB granularity, no need to check */
+	if (IS_ENABLED(CONFIG_ARM64_4K_PAGES))
+		return EFI_SUCCESS;
+
+	tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_EL1_TGRAN_SHIFT) & 0xf;
+	if (tg < ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX) {
+		if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
+			efi_err("This 64 KB granular kernel is not supported by your CPU\n");
+		else
+			efi_err("This 16 KB granular kernel is not supported by your CPU\n");
+		return EFI_UNSUPPORTED;
+	}
+	return EFI_SUCCESS;
+}
+
+void efi_cache_sync_image(unsigned long image_base,
+			  unsigned long alloc_size,
+			  unsigned long code_size)
+{
+	u32 ctr = read_cpuid_effective_cachetype();
+	u64 lsize = 4 << cpuid_feature_extract_unsigned_field(ctr,
+						CTR_EL0_DminLine_SHIFT);
+
+	do {
+		asm("dc civac, %0" :: "r"(image_base));
+		image_base += lsize;
+		alloc_size -= lsize;
+	} while (alloc_size >= lsize);
+
+	asm("ic ialluis");
+	dsb(ish);
+	isb();
+}
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index a2fc0727880a..576e5cfec980 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1038,4 +1038,8 @@ void efi_retrieve_tpm2_eventlog(void);
 struct screen_info *alloc_screen_info(void);
 void free_screen_info(struct screen_info *si);
 
+void efi_cache_sync_image(unsigned long image_base,
+			  unsigned long alloc_size,
+			  unsigned long code_size);
+
 #endif
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 19/21] efi/loongarch: Don't jump to kernel entry via the old image
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (17 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 18/21] efi/arm64: " Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:16 ` [PATCH 20/21] efi/loongarch: libstub: Split off kernel image relocation for builtin stub Ard Biesheuvel
  2022-10-17 17:17 ` [PATCH 21/21] efi: libstub: Merge zboot decompressor with the ordinary stub Ard Biesheuvel
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Currently, the EFI entry code for LoongArch is set up to copy the
executable image to the preferred offset, but instead of branching
directly into that image, it branches to the local copy of kernel_entry,
and relies on the logic in that function to switch to the link time
address instead.

This is a bit sloppy, and not something we can support once we merge the
EFI decompressor with the EFI stub. So let's clean this up a bit, by
adding a helper that computes the offset of kernel_entry from the start
of the image, and simply adding the result to VMLINUX_LOAD_ADDRESS.

And considering that we cannot execute from anywhere else anyway, let's
avoid efi_relocate_kernel() and just allocate the pages instead.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/loongarch/include/asm/efi.h              |  2 ++
 drivers/firmware/efi/libstub/loongarch-stub.c | 33 ++++++++++++++------
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/arch/loongarch/include/asm/efi.h b/arch/loongarch/include/asm/efi.h
index 5a470c8d2bbc..97f16e60c6ff 100644
--- a/arch/loongarch/include/asm/efi.h
+++ b/arch/loongarch/include/asm/efi.h
@@ -31,4 +31,6 @@ static inline unsigned long efi_get_kimg_min_align(void)
 
 #define EFI_KIMG_PREFERRED_ADDRESS	PHYSADDR(VMLINUX_LOAD_ADDRESS)
 
+unsigned long kernel_entry_address(void);
+
 #endif /* _ASM_LOONGARCH_EFI_H */
diff --git a/drivers/firmware/efi/libstub/loongarch-stub.c b/drivers/firmware/efi/libstub/loongarch-stub.c
index a2e55e5c4003..6b30fc281458 100644
--- a/drivers/firmware/efi/libstub/loongarch-stub.c
+++ b/drivers/firmware/efi/libstub/loongarch-stub.c
@@ -29,18 +29,27 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 				 efi_loaded_image_t *image,
 				 efi_handle_t image_handle)
 {
+	int nr_pages = round_up(kernel_asize, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
+	efi_physical_addr_t kernel_addr = EFI_KIMG_PREFERRED_ADDRESS;
 	efi_status_t status;
-	unsigned long kernel_addr = 0;
 
-	kernel_addr = (unsigned long)&kernel_offset - kernel_offset;
-
-	status = efi_relocate_kernel(&kernel_addr, kernel_fsize, kernel_asize,
-				     EFI_KIMG_PREFERRED_ADDRESS,
-				     efi_get_kimg_min_align(), 0x0);
+	/*
+	 * Allocate space for the kernel image at the preferred offset. This is
+	 * the only location in memory from where we can execute the image, so
+	 * no point in falling back to another allocation.
+	 */
+	status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
+			     EFI_LOADER_DATA, nr_pages, &kernel_addr);
+	if (status != EFI_SUCCESS)
+		return status;
 
-	*image_addr = kernel_addr;
+	*image_addr = EFI_KIMG_PREFERRED_ADDRESS;
 	*image_size = kernel_asize;
 
+	memcpy((void *)EFI_KIMG_PREFERRED_ADDRESS,
+	       (void *)&kernel_offset - kernel_offset,
+	       kernel_fsize);
+
 	return status;
 }
 
@@ -64,6 +73,13 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
 	return EFI_SUCCESS;
 }
 
+unsigned long kernel_entry_address(void)
+{
+	unsigned long base = (unsigned long)&kernel_offset - kernel_offset;
+
+	return (unsigned long)&kernel_entry - base + VMLINUX_LOAD_ADDRESS;
+}
+
 efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
 			     unsigned long kernel_addr, char *cmdline_ptr)
 {
@@ -95,8 +111,7 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
 	csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
 	csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
 
-	real_kernel_entry = (kernel_entry_t)
-		((unsigned long)&kernel_entry - kernel_addr + VMLINUX_LOAD_ADDRESS);
+	real_kernel_entry = (void *)kernel_entry_address();
 
 	real_kernel_entry(true, (unsigned long)cmdline_ptr,
 			  (unsigned long)efi_system_table);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 20/21] efi/loongarch: libstub: Split off kernel image relocation for builtin stub
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (18 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 19/21] efi/loongarch: Don't jump to kernel entry via the old image Ard Biesheuvel
@ 2022-10-17 17:16 ` Ard Biesheuvel
  2022-10-17 17:17 ` [PATCH 21/21] efi: libstub: Merge zboot decompressor with the ordinary stub Ard Biesheuvel
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:16 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

The LoongArch build of the EFI stub is part of the core kernel image, and
therefore accesses section markers directly when it needs to figure out
the size of the various section.

The zboot decompressor does not have access to those symbols, but
doesn't really need that either. So let's move handle_kernel_image()
into a separate file (or rather, move everything else into a separate
file) so that the zboot build does not pull in unused code that links to
symbols that it does not define.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/Makefile         |  2 +-
 drivers/firmware/efi/libstub/loongarch-stub.c | 67 +---------------
 drivers/firmware/efi/libstub/loongarch.c      | 80 ++++++++++++++++++++
 3 files changed, 82 insertions(+), 67 deletions(-)

diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index ee24b222489c..37e23e4ab68d 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -87,7 +87,7 @@ lib-$(CONFIG_ARM)		+= arm32-stub.o
 lib-$(CONFIG_ARM64)		+= arm64.o arm64-stub.o arm64-entry.o
 lib-$(CONFIG_X86)		+= x86-stub.o
 lib-$(CONFIG_RISCV)		+= riscv.o riscv-stub.o
-lib-$(CONFIG_LOONGARCH)		+= loongarch-stub.o
+lib-$(CONFIG_LOONGARCH)		+= loongarch.o loongarch-stub.o
 
 CFLAGS_arm32-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 
diff --git a/drivers/firmware/efi/libstub/loongarch-stub.c b/drivers/firmware/efi/libstub/loongarch-stub.c
index 6b30fc281458..eee7ed43cdfb 100644
--- a/drivers/firmware/efi/libstub/loongarch-stub.c
+++ b/drivers/firmware/efi/libstub/loongarch-stub.c
@@ -9,18 +9,10 @@
 #include <asm/addrspace.h>
 #include "efistub.h"
 
-typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long cmdline,
-					  unsigned long systab);
-
 extern int kernel_asize;
 extern int kernel_fsize;
 extern int kernel_offset;
-extern kernel_entry_t kernel_entry;
-
-efi_status_t check_platform_features(void)
-{
-	return EFI_SUCCESS;
-}
+extern int kernel_entry;
 
 efi_status_t handle_kernel_image(unsigned long *image_addr,
 				 unsigned long *image_size,
@@ -53,66 +45,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 	return status;
 }
 
-struct exit_boot_struct {
-	efi_memory_desc_t	*runtime_map;
-	int			runtime_entry_count;
-};
-
-static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
-{
-	struct exit_boot_struct *p = priv;
-
-	/*
-	 * Update the memory map with virtual addresses. The function will also
-	 * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
-	 * entries so that we can pass it straight to SetVirtualAddressMap()
-	 */
-	efi_get_virtmap(map->map, map->map_size, map->desc_size,
-			p->runtime_map, &p->runtime_entry_count);
-
-	return EFI_SUCCESS;
-}
-
 unsigned long kernel_entry_address(void)
 {
 	unsigned long base = (unsigned long)&kernel_offset - kernel_offset;
 
 	return (unsigned long)&kernel_entry - base + VMLINUX_LOAD_ADDRESS;
 }
-
-efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
-			     unsigned long kernel_addr, char *cmdline_ptr)
-{
-	kernel_entry_t real_kernel_entry;
-	struct exit_boot_struct priv;
-	unsigned long desc_size;
-	efi_status_t status;
-	u32 desc_ver;
-
-	status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver);
-	if (status != EFI_SUCCESS) {
-		efi_err("Unable to retrieve UEFI memory map.\n");
-		return status;
-	}
-
-	efi_info("Exiting boot services\n");
-
-	efi_novamap = false;
-	status = efi_exit_boot_services(handle, &priv, exit_boot_func);
-	if (status != EFI_SUCCESS)
-		return status;
-
-	/* Install the new virtual address map */
-	efi_rt_call(set_virtual_address_map,
-		    priv.runtime_entry_count * desc_size, desc_size,
-		    desc_ver, priv.runtime_map);
-
-	/* Config Direct Mapping */
-	csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
-	csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
-
-	real_kernel_entry = (void *)kernel_entry_address();
-
-	real_kernel_entry(true, (unsigned long)cmdline_ptr,
-			  (unsigned long)efi_system_table);
-}
diff --git a/drivers/firmware/efi/libstub/loongarch.c b/drivers/firmware/efi/libstub/loongarch.c
new file mode 100644
index 000000000000..807cba2693fc
--- /dev/null
+++ b/drivers/firmware/efi/libstub/loongarch.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author: Yun Liu <liuyun@loongson.cn>
+ *         Huacai Chen <chenhuacai@loongson.cn>
+ * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
+ */
+
+#include <asm/efi.h>
+#include <asm/addrspace.h>
+#include "efistub.h"
+
+typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long cmdline,
+					  unsigned long systab);
+
+efi_status_t check_platform_features(void)
+{
+	return EFI_SUCCESS;
+}
+
+struct exit_boot_struct {
+	efi_memory_desc_t	*runtime_map;
+	int			runtime_entry_count;
+};
+
+static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
+{
+	struct exit_boot_struct *p = priv;
+
+	/*
+	 * Update the memory map with virtual addresses. The function will also
+	 * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
+	 * entries so that we can pass it straight to SetVirtualAddressMap()
+	 */
+	efi_get_virtmap(map->map, map->map_size, map->desc_size,
+			p->runtime_map, &p->runtime_entry_count);
+
+	return EFI_SUCCESS;
+}
+
+unsigned long __weak kernel_entry_address(void)
+{
+	return *(unsigned long *)(PHYSADDR(VMLINUX_LOAD_ADDRESS) + 8);
+}
+
+efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
+			     unsigned long kernel_addr, char *cmdline_ptr)
+{
+	kernel_entry_t real_kernel_entry;
+	struct exit_boot_struct priv;
+	unsigned long desc_size;
+	efi_status_t status;
+	u32 desc_ver;
+
+	status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver);
+	if (status != EFI_SUCCESS) {
+		efi_err("Unable to retrieve UEFI memory map.\n");
+		return status;
+	}
+
+	efi_info("Exiting boot services\n");
+
+	efi_novamap = false;
+	status = efi_exit_boot_services(handle, &priv, exit_boot_func);
+	if (status != EFI_SUCCESS)
+		return status;
+
+	/* Install the new virtual address map */
+	efi_rt_call(set_virtual_address_map,
+		    priv.runtime_entry_count * desc_size, desc_size,
+		    desc_ver, priv.runtime_map);
+
+	/* Config Direct Mapping */
+	csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
+	csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
+
+	real_kernel_entry = (void *)kernel_entry_address();
+
+	real_kernel_entry(true, (unsigned long)cmdline_ptr,
+			  (unsigned long)efi_system_table);
+}
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 21/21] efi: libstub: Merge zboot decompressor with the ordinary stub
  2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
                   ` (19 preceding siblings ...)
  2022-10-17 17:16 ` [PATCH 20/21] efi/loongarch: libstub: Split off kernel image relocation for builtin stub Ard Biesheuvel
@ 2022-10-17 17:17 ` Ard Biesheuvel
  20 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-17 17:17 UTC (permalink / raw)
  To: linux-efi
  Cc: keescook, Ard Biesheuvel, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon, Catalin Marinas

Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
  a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
  image in memory in case of KASLR, mirrored memory or if the image must
  execute from a certain a priori defined address.

There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
  which anything goes.

Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.

This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.

In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/file.c  |  18 --
 drivers/firmware/efi/libstub/zboot.c | 284 +++++---------------
 2 files changed, 74 insertions(+), 228 deletions(-)

diff --git a/drivers/firmware/efi/libstub/file.c b/drivers/firmware/efi/libstub/file.c
index 995d9d823519..d6a025df07dc 100644
--- a/drivers/firmware/efi/libstub/file.c
+++ b/drivers/firmware/efi/libstub/file.c
@@ -74,28 +74,10 @@ static efi_status_t efi_open_file(efi_file_protocol_t *volume,
 static efi_status_t efi_open_volume(efi_loaded_image_t *image,
 				    efi_file_protocol_t **fh)
 {
-	struct efi_vendor_dev_path *dp = efi_table_attr(image, file_path);
-	efi_guid_t li_proto = LOADED_IMAGE_PROTOCOL_GUID;
 	efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
 	efi_simple_file_system_protocol_t *io;
 	efi_status_t status;
 
-	// If we are using EFI zboot, we should look for the file system
-	// protocol on the parent image's handle instead
-	if (IS_ENABLED(CONFIG_EFI_ZBOOT) &&
-	    image->parent_handle != NULL &&
-	    dp != NULL &&
-	    dp->header.type == EFI_DEV_MEDIA &&
-	    dp->header.sub_type == EFI_DEV_MEDIA_VENDOR &&
-	    !efi_guidcmp(dp->vendorguid, LINUX_EFI_ZBOOT_MEDIA_GUID)) {
-		status = efi_bs_call(handle_protocol, image->parent_handle,
-				     &li_proto, (void *)&image);
-		if (status != EFI_SUCCESS) {
-			efi_err("Failed to locate parent image handle\n");
-			return status;
-		}
-	}
-
 	status = efi_bs_call(handle_protocol, efi_table_attr(image, device_handle),
 			     &fs_proto, (void **)&io);
 	if (status != EFI_SUCCESS) {
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 5f41a5b17d6e..66be5fdc6b58 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -37,247 +37,111 @@ static void error(char *x)
 	efi_err("EFI decompressor: %s\n", x);
 }
 
-static efi_status_t __efiapi
-load_file(efi_load_file_protocol_t *this, efi_device_path_protocol_t *rem,
-	  bool boot_policy, unsigned long *bufsize, void *buffer)
+static unsigned long alloc_preferred_address(unsigned long alloc_size)
 {
-	unsigned long compressed_size = _gzdata_end - _gzdata_start;
-	struct efi_vendor_dev_path *vendor_dp;
-	bool decompress = false;
-	unsigned long size;
-	int ret;
-
-	if (rem == NULL || bufsize == NULL)
-		return EFI_INVALID_PARAMETER;
-
-	if (boot_policy)
-		return EFI_UNSUPPORTED;
-
-	// Look for our vendor media device node in the remaining file path
-	if (rem->type == EFI_DEV_MEDIA &&
-	    rem->sub_type == EFI_DEV_MEDIA_VENDOR) {
-		vendor_dp = container_of(rem, struct efi_vendor_dev_path, header);
-		if (efi_guidcmp(vendor_dp->vendorguid, LINUX_EFI_ZBOOT_MEDIA_GUID))
-			return EFI_NOT_FOUND;
-
-		decompress = true;
-		rem = (void *)(vendor_dp + 1);
-	}
-
-	if (rem->type != EFI_DEV_END_PATH ||
-	    rem->sub_type != EFI_DEV_END_ENTIRE)
-		return EFI_NOT_FOUND;
-
-	// The uncompressed size of the payload is appended to the raw bit
-	// stream, and may therefore appear misaligned in memory
-	size = decompress ? get_unaligned_le32(_gzdata_end - 4)
-			  : compressed_size;
-	if (buffer == NULL || *bufsize < size) {
-		*bufsize = size;
-		return EFI_BUFFER_TOO_SMALL;
-	}
-
-	if (decompress) {
-		ret = __decompress(_gzdata_start, compressed_size, NULL, NULL,
-				   buffer, size, NULL, error);
-		if (ret	< 0) {
-			error("Decompression failed");
-			return EFI_DEVICE_ERROR;
-		}
-	} else {
-		memcpy(buffer, _gzdata_start, compressed_size);
-	}
-
-	return EFI_SUCCESS;
-}
-
-// Return the length in bytes of the device path up to the first end node.
-static int device_path_length(const efi_device_path_protocol_t *dp)
-{
-	int len = 0;
-
-	while (dp->type != EFI_DEV_END_PATH) {
-		len += dp->length;
-		dp = (void *)((u8 *)dp + dp->length);
-	}
-	return len;
-}
-
-static void append_rel_offset_node(efi_device_path_protocol_t **dp,
-				   unsigned long start, unsigned long end)
-{
-	struct efi_rel_offset_dev_path *rodp = (void *)*dp;
-
-	rodp->header.type	= EFI_DEV_MEDIA;
-	rodp->header.sub_type	= EFI_DEV_MEDIA_REL_OFFSET;
-	rodp->header.length	= sizeof(struct efi_rel_offset_dev_path);
-	rodp->reserved		= 0;
-	rodp->starting_offset	= start;
-	rodp->ending_offset	= end;
-
-	*dp = (void *)(rodp + 1);
-}
-
-static void append_ven_media_node(efi_device_path_protocol_t **dp,
-				  efi_guid_t *guid)
-{
-	struct efi_vendor_dev_path *vmdp = (void *)*dp;
-
-	vmdp->header.type	= EFI_DEV_MEDIA;
-	vmdp->header.sub_type	= EFI_DEV_MEDIA_VENDOR;
-	vmdp->header.length	= sizeof(struct efi_vendor_dev_path);
-	vmdp->vendorguid	= *guid;
+#ifdef EFI_KIMG_PREFERRED_ADDRESS
+	efi_physical_addr_t efi_addr = EFI_KIMG_PREFERRED_ADDRESS;
 
-	*dp = (void *)(vmdp + 1);
+	if (efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
+			alloc_size / EFI_PAGE_SIZE, &efi_addr) == EFI_SUCCESS)
+		return efi_addr;
+#endif
+	return ULONG_MAX;
 }
 
-static void append_end_node(efi_device_path_protocol_t **dp)
+void __weak efi_cache_sync_image(unsigned long image_base,
+				 unsigned long alloc_size,
+				 unsigned long code_size)
 {
-	(*dp)->type		= EFI_DEV_END_PATH;
-	(*dp)->sub_type		= EFI_DEV_END_ENTIRE;
-	(*dp)->length		= sizeof(struct efi_generic_dev_path);
-
-	++*dp;
+	// Provided by the arch to perform the cache maintenance necessary for
+	// executable code loaded into memory to be safe for execution.
 }
 
 asmlinkage efi_status_t __efiapi
 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 {
-	struct efi_mem_mapped_dev_path mmdp = {
-		.header.type		= EFI_DEV_HW,
-		.header.sub_type	= EFI_DEV_MEM_MAPPED,
-		.header.length		= sizeof(struct efi_mem_mapped_dev_path)
-	};
-	efi_device_path_protocol_t *parent_dp, *dpp, *lf2_dp, *li_dp;
-	efi_load_file2_protocol_t zboot_load_file2;
-	efi_loaded_image_t *parent, *child;
-	unsigned long exit_data_size;
-	efi_handle_t child_handle;
-	efi_handle_t zboot_handle;
-	efi_char16_t *exit_data;
+	unsigned long compressed_size = _gzdata_end - _gzdata_start;
+	unsigned long image_base, alloc_size, code_size;
+	efi_loaded_image_t *image;
 	efi_status_t status;
-	void *dp_alloc;
-	int dp_len;
+	char *cmdline_ptr;
+	int ret;
 
 	WRITE_ONCE(efi_system_table, systab);
 
 	free_mem_ptr = (unsigned long)&zboot_heap;
 	free_mem_end_ptr = free_mem_ptr + sizeof(zboot_heap);
 
-	exit_data = NULL;
-	exit_data_size = 0;
-
 	status = efi_bs_call(handle_protocol, handle,
-			     &LOADED_IMAGE_PROTOCOL_GUID, (void **)&parent);
+			     &LOADED_IMAGE_PROTOCOL_GUID, (void **)&image);
 	if (status != EFI_SUCCESS) {
 		error("Failed to locate parent's loaded image protocol");
 		return status;
 	}
 
-	status = efi_bs_call(handle_protocol, handle,
-			     &LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID,
-			     (void **)&parent_dp);
-	if (status != EFI_SUCCESS || parent_dp == NULL) {
-		// Create a MemoryMapped() device path node to describe
-		// the parent image if no device path was provided.
-		mmdp.memory_type	= parent->image_code_type;
-		mmdp.starting_addr	= (unsigned long)parent->image_base;
-		mmdp.ending_addr	= (unsigned long)parent->image_base +
-					  parent->image_size - 1;
-		parent_dp = &mmdp.header;
-		dp_len = sizeof(mmdp);
-	} else {
-		dp_len = device_path_length(parent_dp);
-	}
-
-	// Allocate some pool memory for device path protocol data
-	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
-			     2 * (dp_len + sizeof(struct efi_rel_offset_dev_path) +
-			          sizeof(struct efi_generic_dev_path)) +
-			     sizeof(struct efi_vendor_dev_path),
-			     (void **)&dp_alloc);
-	if (status != EFI_SUCCESS) {
-		error("Failed to allocate device path pool memory");
+	status = efi_handle_cmdline(image, &cmdline_ptr);
+	if (status != EFI_SUCCESS)
 		return status;
-	}
-
-	// Create a device path describing the compressed payload in this image
-	// <...parent_dp...>/Offset(<start>, <end>)
-	lf2_dp = memcpy(dp_alloc, parent_dp, dp_len);
-	dpp = (void *)((u8 *)lf2_dp + dp_len);
-	append_rel_offset_node(&dpp,
-			       (unsigned long)(_gzdata_start - efi_zboot_header),
-			       (unsigned long)(_gzdata_end - efi_zboot_header - 1));
-	append_end_node(&dpp);
 
-	// Create a device path describing the decompressed payload in this image
-	// <...parent_dp...>/Offset(<start>, <end>)/VenMedia(ZBOOT_MEDIA_GUID)
-	dp_len += sizeof(struct efi_rel_offset_dev_path);
-	li_dp = memcpy(dpp, lf2_dp, dp_len);
-	dpp = (void *)((u8 *)li_dp + dp_len);
-	append_ven_media_node(&dpp, &LINUX_EFI_ZBOOT_MEDIA_GUID);
-	append_end_node(&dpp);
-
-	zboot_handle = NULL;
-	zboot_load_file2.load_file = load_file;
-	status = efi_bs_call(install_multiple_protocol_interfaces,
-			     &zboot_handle,
-			     &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp,
-			     &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2,
-			     NULL);
-	if (status != EFI_SUCCESS) {
-		error("Failed to install LoadFile2 protocol and device path");
-		goto free_dpalloc;
-	}
-
-	status = efi_bs_call(load_image, false, handle, li_dp, NULL, 0,
-			     &child_handle);
-	if (status != EFI_SUCCESS) {
-		error("Failed to load image");
-		goto uninstall_lf2;
-	}
+	efi_info("Decompressing Linux Kernel...\n");
+
+	// SizeOfImage from the compressee's PE/COFF header
+	alloc_size = round_up(get_unaligned_le32(_gzdata_end - 4),
+			      EFI_ALLOC_ALIGN);
+
+	// SizeOfHeaders and SizeOfCode from the compressee's PE/COFF header
+	code_size = get_unaligned_le32(_gzdata_end - 8) +
+		    get_unaligned_le32(_gzdata_end - 12);
+
+	 // If the architecture has a preferred address for the image,
+	 // try that first.
+	image_base = alloc_preferred_address(alloc_size);
+	if (image_base == ULONG_MAX) {
+		unsigned long min_kimg_align = efi_get_kimg_min_align();
+		u32 seed = U32_MAX;
+
+		if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
+			// Setting the random seed to 0x0 is the same as
+			// allocating as low as possible
+			seed = 0;
+		} else if (efi_nokaslr) {
+			efi_info("KASLR disabled on kernel command line\n");
+		} else {
+			status = efi_get_random_bytes(sizeof(seed), (u8 *)&seed);
+			if (status == EFI_NOT_FOUND) {
+				efi_info("EFI_RNG_PROTOCOL unavailable\n");
+				efi_nokaslr = true;
+			} else if (status != EFI_SUCCESS) {
+				efi_err("efi_get_random_bytes() failed (0x%lx)\n",
+					status);
+				efi_nokaslr = true;
+			}
+		}
 
-	status = efi_bs_call(handle_protocol, child_handle,
-			     &LOADED_IMAGE_PROTOCOL_GUID, (void **)&child);
-	if (status != EFI_SUCCESS) {
-		error("Failed to locate child's loaded image protocol");
-		goto unload_image;
+		status = efi_random_alloc(alloc_size, min_kimg_align, &image_base,
+					  seed, EFI_LOADER_CODE);
+		if (status != EFI_SUCCESS) {
+			efi_err("Failed to allocate memory\n");
+			goto free_cmdline;
+		}
 	}
 
-	// Copy the kernel command line
-	child->load_options = parent->load_options;
-	child->load_options_size = parent->load_options_size;
-
-	status = efi_bs_call(start_image, child_handle, &exit_data_size,
-			     &exit_data);
-	if (status != EFI_SUCCESS) {
-		error("StartImage() returned with error:");
-		if (exit_data_size > 0)
-			efi_err("%ls\n", exit_data);
-
-		// If StartImage() returns EFI_SECURITY_VIOLATION, the image is
-		// not unloaded so we need to do it by hand.
-		if (status == EFI_SECURITY_VIOLATION)
-unload_image:
-			efi_bs_call(unload_image, child_handle);
+	// Decompress the payload into the newly allocated buffer.
+	ret = __decompress(_gzdata_start, compressed_size, NULL, NULL,
+			   (void *)image_base, alloc_size, NULL, error);
+	if (ret	< 0) {
+		error("Decompression failed");
+		status = EFI_DEVICE_ERROR;
+		goto free_image;
 	}
 
-uninstall_lf2:
-	efi_bs_call(uninstall_multiple_protocol_interfaces,
-		    zboot_handle,
-		    &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp,
-		    &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2,
-		    NULL);
-
-free_dpalloc:
-	efi_bs_call(free_pool, dp_alloc);
+	efi_cache_sync_image(image_base, alloc_size, code_size);
 
-	efi_bs_call(exit, handle, status, exit_data_size, exit_data);
+	status = efi_stub_common(handle, image, image_base, cmdline_ptr);
 
-	// Free ExitData in case Exit() returned with a failure code,
-	// but return the original status code.
-	error("Exit() returned with failure code");
-	if (exit_data != NULL)
-		efi_bs_call(free_pool, exit_data);
+free_image:
+	efi_free(alloc_size, image_base);
+free_cmdline:
+	efi_bs_call(free_pool, cmdline_ptr);
 	return status;
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel()
  2022-10-17 17:16 ` [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel() Ard Biesheuvel
@ 2022-10-18 11:27   ` Catalin Marinas
  2022-10-18 11:38     ` Ard Biesheuvel
  0 siblings, 1 reply; 28+ messages in thread
From: Catalin Marinas @ 2022-10-18 11:27 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, keescook, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon

On Mon, Oct 17, 2022 at 07:16:40PM +0200, Ard Biesheuvel wrote:
> diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
> index 61a87fa1c305..1c1be004a271 100644
> --- a/arch/arm64/kernel/efi-entry.S
> +++ b/arch/arm64/kernel/efi-entry.S
> @@ -23,15 +23,6 @@ SYM_CODE_START(efi_enter_kernel)
>  	add	x19, x0, x2		// relocated Image entrypoint
>  	mov	x20, x1			// DTB address
>  
> -	/*
> -	 * Clean the copied Image to the PoC, and ensure it is not shadowed by
> -	 * stale icache entries from before relocation.
> -	 */
> -	ldr	w1, =kernel_size
> -	add	x1, x0, x1
> -	bl	dcache_clean_poc
> -	ic	ialluis
> -
>  	/*
>  	 * Clean the remainder of this routine to the PoC
>  	 * so that we can safely disable the MMU and caches.
[...]
> diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
> index 598c76c4bbaa..e767a5ac8c3d 100644
> --- a/drivers/firmware/efi/libstub/arm64-stub.c
> +++ b/drivers/firmware/efi/libstub/arm64-stub.c
[...]
> @@ -174,5 +174,13 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
>  	*image_addr = *reserve_addr;
>  	memcpy((void *)*image_addr, _text, kernel_size);
>  
> +clean_image_to_poc:
> +	/*
> +	 * Clean the copied Image to the PoC, and ensure it is not shadowed by
> +	 * stale icache entries from before relocation.
> +	 */
> +	dcache_clean_poc(*image_addr, *image_addr + kernel_size);
> +	asm("ic ialluis");

Does this need some barriers, at least a DSB? The original code had DSB
and ISB, though not immediately after the IC instruction.

-- 
Catalin

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel()
  2022-10-18 11:27   ` Catalin Marinas
@ 2022-10-18 11:38     ` Ard Biesheuvel
  2022-10-18 11:54       ` Catalin Marinas
  0 siblings, 1 reply; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-18 11:38 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-efi, keescook, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon

On Tue, 18 Oct 2022 at 13:28, Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Mon, Oct 17, 2022 at 07:16:40PM +0200, Ard Biesheuvel wrote:
> > diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
> > index 61a87fa1c305..1c1be004a271 100644
> > --- a/arch/arm64/kernel/efi-entry.S
> > +++ b/arch/arm64/kernel/efi-entry.S
> > @@ -23,15 +23,6 @@ SYM_CODE_START(efi_enter_kernel)
> >       add     x19, x0, x2             // relocated Image entrypoint
> >       mov     x20, x1                 // DTB address
> >
> > -     /*
> > -      * Clean the copied Image to the PoC, and ensure it is not shadowed by
> > -      * stale icache entries from before relocation.
> > -      */
> > -     ldr     w1, =kernel_size
> > -     add     x1, x0, x1
> > -     bl      dcache_clean_poc
> > -     ic      ialluis
> > -
> >       /*
> >        * Clean the remainder of this routine to the PoC
> >        * so that we can safely disable the MMU and caches.
> [...]
> > diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
> > index 598c76c4bbaa..e767a5ac8c3d 100644
> > --- a/drivers/firmware/efi/libstub/arm64-stub.c
> > +++ b/drivers/firmware/efi/libstub/arm64-stub.c
> [...]
> > @@ -174,5 +174,13 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
> >       *image_addr = *reserve_addr;
> >       memcpy((void *)*image_addr, _text, kernel_size);
> >
> > +clean_image_to_poc:
> > +     /*
> > +      * Clean the copied Image to the PoC, and ensure it is not shadowed by
> > +      * stale icache entries from before relocation.
> > +      */
> > +     dcache_clean_poc(*image_addr, *image_addr + kernel_size);
> > +     asm("ic ialluis");
>
> Does this need some barriers, at least a DSB? The original code had DSB
> and ISB, though not immediately after the IC instruction.
>

We are still relying on the implicit DSB done by the subsequent call
to dcache_clean_to_poc() call in efi_enter_kernel(), which executes
much later than this code.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel()
  2022-10-18 11:38     ` Ard Biesheuvel
@ 2022-10-18 11:54       ` Catalin Marinas
  0 siblings, 0 replies; 28+ messages in thread
From: Catalin Marinas @ 2022-10-18 11:54 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, keescook, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon

On Tue, Oct 18, 2022 at 01:38:57PM +0200, Ard Biesheuvel wrote:
> On Tue, 18 Oct 2022 at 13:28, Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Mon, Oct 17, 2022 at 07:16:40PM +0200, Ard Biesheuvel wrote:
> > > diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
> > > index 61a87fa1c305..1c1be004a271 100644
> > > --- a/arch/arm64/kernel/efi-entry.S
> > > +++ b/arch/arm64/kernel/efi-entry.S
> > > @@ -23,15 +23,6 @@ SYM_CODE_START(efi_enter_kernel)
> > >       add     x19, x0, x2             // relocated Image entrypoint
> > >       mov     x20, x1                 // DTB address
> > >
> > > -     /*
> > > -      * Clean the copied Image to the PoC, and ensure it is not shadowed by
> > > -      * stale icache entries from before relocation.
> > > -      */
> > > -     ldr     w1, =kernel_size
> > > -     add     x1, x0, x1
> > > -     bl      dcache_clean_poc
> > > -     ic      ialluis
> > > -
> > >       /*
> > >        * Clean the remainder of this routine to the PoC
> > >        * so that we can safely disable the MMU and caches.
> > [...]
> > > diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
> > > index 598c76c4bbaa..e767a5ac8c3d 100644
> > > --- a/drivers/firmware/efi/libstub/arm64-stub.c
> > > +++ b/drivers/firmware/efi/libstub/arm64-stub.c
> > [...]
> > > @@ -174,5 +174,13 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
> > >       *image_addr = *reserve_addr;
> > >       memcpy((void *)*image_addr, _text, kernel_size);
> > >
> > > +clean_image_to_poc:
> > > +     /*
> > > +      * Clean the copied Image to the PoC, and ensure it is not shadowed by
> > > +      * stale icache entries from before relocation.
> > > +      */
> > > +     dcache_clean_poc(*image_addr, *image_addr + kernel_size);
> > > +     asm("ic ialluis");
> >
> > Does this need some barriers, at least a DSB? The original code had DSB
> > and ISB, though not immediately after the IC instruction.
> 
> We are still relying on the implicit DSB done by the subsequent call
> to dcache_clean_to_poc() call in efi_enter_kernel(), which executes
> much later than this code.

Ah, ok.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 02/21] arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel()
  2022-10-17 17:16 ` [PATCH 02/21] arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel() Ard Biesheuvel
@ 2022-10-18 11:57   ` Catalin Marinas
  2022-10-18 11:59     ` Ard Biesheuvel
  0 siblings, 1 reply; 28+ messages in thread
From: Catalin Marinas @ 2022-10-18 11:57 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, keescook, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon

On Mon, Oct 17, 2022 at 07:16:41PM +0200, Ard Biesheuvel wrote:
> To allow efi_enter_kernel() to be shared with the EFI zboot decompressor
> build, drop another reference to dcache_clean_poc() and replace it with
> a single DC CVAC instruction. To ensure that it covers the remainder of
> efi_enter_kernel() as intended, reorganize the code a bit so it fits in
> a 32-byte cacheline, and align it to 32 bytes. (Even though the
> architecture defines 16 as the minimum D-cache line size, even the
> chosen value of 32 is highly unlikely to ever be encountered on real
> hardware, and this works with any line size >= 32)

This should do.

> -0:
> +	adr	x4, 1f
> +	dc	civac, x4

s/civac/cvac/ ?

Otherwise,

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 03/21] arm64: efi: Move efi-entry.S into the libstub source directory
  2022-10-17 17:16 ` [PATCH 03/21] arm64: efi: Move efi-entry.S into the libstub source directory Ard Biesheuvel
@ 2022-10-18 11:57   ` Catalin Marinas
  0 siblings, 0 replies; 28+ messages in thread
From: Catalin Marinas @ 2022-10-18 11:57 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, keescook, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon

On Mon, Oct 17, 2022 at 07:16:42PM +0200, Ard Biesheuvel wrote:
> We will be sharing efi-entry.S with the zboot decompressor build, which
> does not link against vmlinux directly. So move it into the libstub
> source directory so we can include in the libstub static library.
> 
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 02/21] arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel()
  2022-10-18 11:57   ` Catalin Marinas
@ 2022-10-18 11:59     ` Ard Biesheuvel
  0 siblings, 0 replies; 28+ messages in thread
From: Ard Biesheuvel @ 2022-10-18 11:59 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-efi, keescook, Matthew Garrett, Peter Jones,
	Ilias Apalodimas, Palmer Dabbelt, Atish Patra, Arnd Bergmann,
	Huacai Chen, Xi Ruoyao, Lennart Poettering, Jeremy Linton,
	Will Deacon

On Tue, 18 Oct 2022 at 13:57, Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Mon, Oct 17, 2022 at 07:16:41PM +0200, Ard Biesheuvel wrote:
> > To allow efi_enter_kernel() to be shared with the EFI zboot decompressor
> > build, drop another reference to dcache_clean_poc() and replace it with
> > a single DC CVAC instruction. To ensure that it covers the remainder of
> > efi_enter_kernel() as intended, reorganize the code a bit so it fits in
> > a 32-byte cacheline, and align it to 32 bytes. (Even though the
> > architecture defines 16 as the minimum D-cache line size, even the
> > chosen value of 32 is highly unlikely to ever be encountered on real
> > hardware, and this works with any line size >= 32)
>
> This should do.
>
> > -0:
> > +     adr     x4, 1f
> > +     dc      civac, x4
>
> s/civac/cvac/ ?
>

Ah yes, I changed that last minute because of
ARM64_WORKAROUND_CLEAN_CACHE - I'll add a note.

> Otherwise,
>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>

Thanks

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2022-10-18 12:01 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-17 17:16 [PATCH 00/21] efi: Combine stub functionality with zboot decompressor Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 01/21] arm64: efi: Move dcache cleaning of loaded image out of efi_enter_kernel() Ard Biesheuvel
2022-10-18 11:27   ` Catalin Marinas
2022-10-18 11:38     ` Ard Biesheuvel
2022-10-18 11:54       ` Catalin Marinas
2022-10-17 17:16 ` [PATCH 02/21] arm64: efi: Avoid dcache_clean_poc() altogether in efi_enter_kernel() Ard Biesheuvel
2022-10-18 11:57   ` Catalin Marinas
2022-10-18 11:59     ` Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 03/21] arm64: efi: Move efi-entry.S into the libstub source directory Ard Biesheuvel
2022-10-18 11:57   ` Catalin Marinas
2022-10-17 17:16 ` [PATCH 04/21] efi: libstub: Remove zboot signing from build options Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 05/21] efi: libstub: Drop randomization of runtime memory map Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 06/21] efi: libstub: Drop handling of EFI properties table Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 07/21] efi: libstub: Deduplicate ftrace command line argument filtering Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 08/21] efi: libstub: Use local strncmp() implementation unconditionally Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 09/21] efi: libstub: Clone memcmp() into the stub Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 10/21] efi: libstub: Enable efi_printk() in zboot decompressor Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 11/21] efi: loongarch: Drop exports of unused string routines Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 12/21] efi: libstub: Move screen_info handling to common code Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 13/21] efi: libstub: Provide local implementations of strrchr() and memchr() Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 14/21] efi: libstub: Factor out EFI stub entrypoint into separate file Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 15/21] efi: libstub: Add image code and data size to the zimage metadata Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 16/21] efi: libstub: Factor out min alignment and preferred kernel load address Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 17/21] efi/riscv: libstub: Split off kernel image relocation for builtin stub Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 18/21] efi/arm64: " Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 19/21] efi/loongarch: Don't jump to kernel entry via the old image Ard Biesheuvel
2022-10-17 17:16 ` [PATCH 20/21] efi/loongarch: libstub: Split off kernel image relocation for builtin stub Ard Biesheuvel
2022-10-17 17:17 ` [PATCH 21/21] efi: libstub: Merge zboot decompressor with the ordinary stub Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).