Linux EFI development
 help / color / mirror / Atom feed
* [PATCH 0/5] efi: Expose loaded image properties via info struct
@ 2026-11-06 14:19 Ard Biesheuvel
  2026-11-06 14:19 ` [PATCH 1/5] efi/libstub: Make efi_remap_image() return efi_status_t Ard Biesheuvel
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Ard Biesheuvel @ 2026-11-06 14:19 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, mark.rutland, will, catalin.marinas,
	Ard Biesheuvel, Jason Gunthorpe

From: Ard Biesheuvel <ardb@kernel.org>

Clean up the arm64 build script and linker hacks that zboot uses to
obtain properties of the loaded image (which it cannot access directly
via a relative reference like the ordinary EFI stub).

Instead, define a struct efi_image_info (whose contents are arch
specific), and expose its offset in the loaded image via the arm64 image
header, so that zboot can access it after decompressing the image.

Cc: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/all/0-v2-989a18390eb1+486-arm64_drtm_jgg@nvidia.com/

Ard Biesheuvel (5):
  efi/libstub: Make efi_remap_image() return efi_status_t
  efi/libstub: Pass a struct efi_image_info to efi_stub_common()
  efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image()
  efi/arm64: Expose struct efi_image_info via the image header
  efi/arm64: Drop build and linker script hacks to obtain image code
    size

 Documentation/arch/arm64/booting.rst           |  3 +-
 arch/arm64/boot/Makefile                       |  3 --
 arch/arm64/include/asm/efi.h                   | 11 ++++++
 arch/arm64/include/asm/image.h                 |  4 ++-
 arch/arm64/kernel/efi-header.S                 |  6 ++++
 arch/arm64/kernel/head.S                       |  3 +-
 arch/arm64/kernel/image-vars.h                 |  4 ---
 drivers/firmware/efi/libstub/arm64-stub.c      | 16 +++++++++
 drivers/firmware/efi/libstub/arm64.c           | 13 ++++---
 drivers/firmware/efi/libstub/efi-stub-entry.c  |  8 ++++-
 drivers/firmware/efi/libstub/efi-stub-helper.c | 13 ++++---
 drivers/firmware/efi/libstub/efi-stub.c        |  3 +-
 drivers/firmware/efi/libstub/efistub.h         | 16 +++++++--
 drivers/firmware/efi/libstub/zboot.c           | 36 ++++++++++++++++++--
 drivers/firmware/efi/libstub/zboot.lds         |  7 ----
 15 files changed, 112 insertions(+), 34 deletions(-)


base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
-- 
2.56.0.455.g6c5a503b38-goog


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

* [PATCH 1/5] efi/libstub: Make efi_remap_image() return efi_status_t
  2026-11-06 14:19 [PATCH 0/5] efi: Expose loaded image properties via info struct Ard Biesheuvel
@ 2026-11-06 14:19 ` Ard Biesheuvel
  2026-11-06 14:36   ` sashiko-bot
  2026-11-06 14:19 ` [PATCH 2/5] efi/libstub: Pass a struct efi_image_info to efi_stub_common() Ard Biesheuvel
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Ard Biesheuvel @ 2026-11-06 14:19 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, mark.rutland, will, catalin.marinas,
	Ard Biesheuvel, Jason Gunthorpe

From: Ard Biesheuvel <ardb@kernel.org>

efi_remap_image() uses the EFI Memory Attributes Protocol to remap code
and data regions with the appropriate permissions. This could fail for a
variety of regions, all of which are currently ignored.

So relay the failure status code if any occur when invoking the
protocol. Locating the protocol itself is allowed to fail, as remapping
the image is likely unnecessary in the first place if the protocol does
not exist.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/efi-stub-helper.c | 13 ++++++++-----
 drivers/firmware/efi/libstub/efistub.h         |  4 ++--
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 8e43eb3f418b..b2ad081cf324 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -698,8 +698,8 @@ efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
  * read-write/non-executable. The code region is assumed to start at the base
  * of the image, and will therefore cover the PE/COFF header as well.
  */
-void efi_remap_image(unsigned long image_base, unsigned alloc_size,
-		     unsigned long code_size)
+efi_status_t efi_remap_image(unsigned long image_base, unsigned alloc_size,
+			     unsigned long code_size)
 {
 	static efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
 	efi_memory_attribute_protocol_t *memattr;
@@ -710,10 +710,12 @@ void efi_remap_image(unsigned long image_base, unsigned alloc_size,
 	 * If the firmware implements the EFI_MEMORY_ATTRIBUTE_PROTOCOL, let's
 	 * invoke it to remap the text/rodata region of the decompressed image
 	 * as read-only and the data/bss region as non-executable.
+	 * Don't bother if the protocol does not exist: it means all memory is
+	 * read-write-exec anyway.
 	 */
 	status = efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr);
 	if (status != EFI_SUCCESS)
-		return;
+		return EFI_SUCCESS;
 
 	// Get the current attributes for the entire region
 	status = memattr->get_memory_attributes(memattr, image_base,
@@ -721,7 +723,7 @@ void efi_remap_image(unsigned long image_base, unsigned alloc_size,
 	if (status != EFI_SUCCESS) {
 		efi_warn("Failed to retrieve memory attributes for image region: 0x%lx\n",
 			 status);
-		return;
+		return status;
 	}
 
 	// Mark the code region as read-only
@@ -729,7 +731,7 @@ void efi_remap_image(unsigned long image_base, unsigned alloc_size,
 						EFI_MEMORY_RO);
 	if (status != EFI_SUCCESS) {
 		efi_warn("Failed to remap code region read-only\n");
-		return;
+		return status;
 	}
 
 	// If the entire region was already mapped as non-exec, clear the
@@ -749,4 +751,5 @@ void efi_remap_image(unsigned long image_base, unsigned alloc_size,
 		if (status != EFI_SUCCESS)
 			efi_warn("Failed to remap data region non-executable\n");
 	}
+	return status;
 }
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index f5eec8c12894..b09d6c535ab5 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1241,8 +1241,8 @@ struct efi_smbios_type4_record {
 const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
 				  const u8 *offset);
 
-void efi_remap_image(unsigned long image_base, unsigned alloc_size,
-		     unsigned long code_size);
+efi_status_t efi_remap_image(unsigned long image_base, unsigned alloc_size,
+			     unsigned long code_size);
 efi_status_t efi_kaslr_relocate_kernel(unsigned long *image_addr,
 				       unsigned long *reserve_addr,
 				       unsigned long *reserve_size,
-- 
2.56.0.455.g6c5a503b38-goog


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

* [PATCH 2/5] efi/libstub: Pass a struct efi_image_info to efi_stub_common()
  2026-11-06 14:19 [PATCH 0/5] efi: Expose loaded image properties via info struct Ard Biesheuvel
  2026-11-06 14:19 ` [PATCH 1/5] efi/libstub: Make efi_remap_image() return efi_status_t Ard Biesheuvel
@ 2026-11-06 14:19 ` Ard Biesheuvel
  2026-11-06 14:27   ` sashiko-bot
  2026-11-06 14:19 ` [PATCH 3/5] efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image() Ard Biesheuvel
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Ard Biesheuvel @ 2026-11-06 14:19 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, mark.rutland, will, catalin.marinas,
	Ard Biesheuvel, Jason Gunthorpe

From: Ard Biesheuvel <ardb@kernel.org>

Pass a struct efi_image_info pointer to efi_stub_common() so that
architectures can expose properties of the image being loaded in a
consistent manner for both the uncompressed kernel and the EFI zboot
image.

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

diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c
index efa3ab8ad1c6..ff559708dfe7 100644
--- a/drivers/firmware/efi/libstub/efi-stub-entry.c
+++ b/drivers/firmware/efi/libstub/efi-stub-entry.c
@@ -27,6 +27,11 @@ struct sysfb_display_info *alloc_primary_display(void)
 	return NULL;
 }
 
+const struct efi_image_info * __weak efistub_get_image_info(void)
+{
+	return NULL;
+}
+
 /*
  * 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
@@ -80,7 +85,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 
 	kernel_image_offset = image_addr - (unsigned long)image->image_base;
 
-	status = efi_stub_common(handle, image, image_addr, cmdline_ptr);
+	status = efi_stub_common(handle, image, image_addr, cmdline_ptr,
+				 efistub_get_image_info());
 
 	efi_free(image_size, image_addr);
 	efi_free(reserve_size, reserve_addr);
diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 6db10590f89b..ee5931eed59c 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -161,7 +161,8 @@ efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr)
 efi_status_t efi_stub_common(efi_handle_t handle,
 			     efi_loaded_image_t *image,
 			     unsigned long image_addr,
-			     char *cmdline_ptr)
+			     char *cmdline_ptr,
+			     const struct efi_image_info *image_info)
 {
 	struct sysfb_display_info *dpy;
 	efi_status_t status;
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index b09d6c535ab5..1955cdb5139a 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1148,11 +1148,17 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 				 efi_loaded_image_t *image,
 				 efi_handle_t image_handle);
 
+struct efi_image_info;
+
+const struct efi_image_info *zboot_get_image_info(unsigned long image_base);
+const struct efi_image_info *efistub_get_image_info(void);
+
 /* 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);
+			     char *cmdline_ptr,
+			     const struct efi_image_info *image_info);
 
 efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr);
 
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 4a5ffe164873..97ae706c034a 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -31,6 +31,11 @@ struct sysfb_display_info *alloc_primary_display(void)
 	return __alloc_primary_display();
 }
 
+const struct efi_image_info * __weak zboot_get_image_info(unsigned long image_base)
+{
+	return NULL;
+}
+
 asmlinkage efi_status_t __efiapi
 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 {
@@ -93,9 +98,15 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 	}
 
 	// Decompress the payload into the newly allocated buffer
-	status = efi_zboot_decompress((void *)image_base, alloc_size) ?:
-	         efi_stub_common(handle, image, image_base, cmdline_ptr);
+	status = efi_zboot_decompress((void *)image_base, alloc_size);
+	if (status != EFI_SUCCESS)
+		goto error;
+
+	auto image_info = zboot_get_image_info(image_base);
+	status = efi_stub_common(handle, image, image_base, cmdline_ptr,
+				 image_info);
 
+error:
 	efi_free(alloc_size, image_base);
 	return status;
 }
-- 
2.56.0.455.g6c5a503b38-goog


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

* [PATCH 3/5] efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image()
  2026-11-06 14:19 [PATCH 0/5] efi: Expose loaded image properties via info struct Ard Biesheuvel
  2026-11-06 14:19 ` [PATCH 1/5] efi/libstub: Make efi_remap_image() return efi_status_t Ard Biesheuvel
  2026-11-06 14:19 ` [PATCH 2/5] efi/libstub: Pass a struct efi_image_info to efi_stub_common() Ard Biesheuvel
@ 2026-11-06 14:19 ` Ard Biesheuvel
  2026-11-06 14:34   ` sashiko-bot
  2026-11-06 14:19 ` [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header Ard Biesheuvel
  2026-11-06 14:19 ` [PATCH 5/5] efi/arm64: Drop build and linker script hacks to obtain image code size Ard Biesheuvel
  4 siblings, 1 reply; 13+ messages in thread
From: Ard Biesheuvel @ 2026-11-06 14:19 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, mark.rutland, will, catalin.marinas,
	Ard Biesheuvel, Jason Gunthorpe

From: Ard Biesheuvel <ardb@kernel.org>

Refactor efi_cache_sync_image() so that it is not in charge of calling
efi_remap_image(), which is really the wrong way around.

Instead, call efi_remap_image() from the primary zboot procedure, where
it is more straight-forward to obtain the code size from the loaded
image.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/include/asm/efi.h           |  3 +++
 drivers/firmware/efi/libstub/arm64.c   |  2 --
 drivers/firmware/efi/libstub/efistub.h |  4 ++++
 drivers/firmware/efi/libstub/zboot.c   | 23 +++++++++++++++++++-
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index e8a9783235cb..da6afd4a7a27 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -151,4 +151,7 @@ efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f);
 
 void efi_icache_sync(unsigned long start, unsigned long end);
 
+// temporary resolution for efistub_get_code_size()
+#define efistub_get_code_size(image_info) ({ extern u32 code_size; code_size; })
+
 #endif /* _ASM_EFI_H */
diff --git a/drivers/firmware/efi/libstub/arm64.c b/drivers/firmware/efi/libstub/arm64.c
index e57cd3de0a00..7ab634e37cf1 100644
--- a/drivers/firmware/efi/libstub/arm64.c
+++ b/drivers/firmware/efi/libstub/arm64.c
@@ -112,8 +112,6 @@ void efi_cache_sync_image(unsigned long image_base,
 	asm("ic ialluis");
 	dsb(ish);
 	isb();
-
-	efi_remap_image(image_base, alloc_size, code_size);
 }
 
 unsigned long __weak primary_entry_offset(void)
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 1955cdb5139a..89cd2ae57a3c 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1270,4 +1270,8 @@ void arch_accept_memory(phys_addr_t start, phys_addr_t end);
 efi_status_t efi_zboot_decompress_init(unsigned long *alloc_size);
 efi_status_t efi_zboot_decompress(u8 *out, unsigned long outlen);
 
+#ifndef efistub_get_code_size
+#define efistub_get_code_size(image_info)	0
+#endif
+
 #endif
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 97ae706c034a..27f6661253c0 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -36,6 +36,26 @@ const struct efi_image_info * __weak zboot_get_image_info(unsigned long image_ba
 	return NULL;
 }
 
+static efi_status_t efi_zboot_remap_image(const struct efi_image_info *image_info,
+					  unsigned long image_base,
+					  unsigned long image_size)
+{
+	unsigned long code_size = efistub_get_code_size(image_info);
+	efi_status_t status;
+
+	if (code_size) {
+		efi_cache_sync_image(image_base, code_size);
+
+		status = efi_remap_image(image_base, image_size, code_size);
+		if (status != EFI_SUCCESS)
+			return status;
+	} else {
+		efi_cache_sync_image(image_base, image_size);
+	}
+
+	return EFI_SUCCESS;
+}
+
 asmlinkage efi_status_t __efiapi
 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 {
@@ -103,7 +123,8 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 		goto error;
 
 	auto image_info = zboot_get_image_info(image_base);
-	status = efi_stub_common(handle, image, image_base, cmdline_ptr,
+	status = efi_zboot_remap_image(image_info, image_base, alloc_size) ?:
+	         efi_stub_common(handle, image, image_base, cmdline_ptr,
 				 image_info);
 
 error:
-- 
2.56.0.455.g6c5a503b38-goog


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

* [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header
  2026-11-06 14:19 [PATCH 0/5] efi: Expose loaded image properties via info struct Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2026-11-06 14:19 ` [PATCH 3/5] efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image() Ard Biesheuvel
@ 2026-11-06 14:19 ` Ard Biesheuvel
  2026-11-06 14:34   ` Jason Gunthorpe
  2026-11-06 14:19 ` [PATCH 5/5] efi/arm64: Drop build and linker script hacks to obtain image code size Ard Biesheuvel
  4 siblings, 1 reply; 13+ messages in thread
From: Ard Biesheuvel @ 2026-11-06 14:19 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, mark.rutland, will, catalin.marinas,
	Ard Biesheuvel, Jason Gunthorpe

From: Ard Biesheuvel <ardb@kernel.org>

The zboot compressed kernel and the uncompressed Image both contain a
copy of the EFI stub, and both are tightly coupled to the kernel image.

However, the zboot stub is not linked into vmlinux like the ordinary EFI
stub is, and so it does not have direct access to its symbols. This is
needed today for things like image size and code size, but there are
more cases coming (DRTM) where both stubs need to have a consistent view
of these things.

So add a struct efi_image_info that is built into vmlinux and exposed
via the image header, so that zboot can access it easily.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 Documentation/arch/arm64/booting.rst      |  3 ++-
 arch/arm64/include/asm/efi.h              |  3 +++
 arch/arm64/include/asm/image.h            |  4 +++-
 arch/arm64/kernel/efi-header.S            |  6 ++++++
 arch/arm64/kernel/head.S                  |  3 ++-
 drivers/firmware/efi/libstub/arm64-stub.c | 14 ++++++++++++++
 drivers/firmware/efi/libstub/arm64.c      |  7 +++++++
 7 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
index dae5ff9fae26..2389558bd389 100644
--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -84,7 +84,8 @@ The decompressed kernel image contains a 64-byte header as follows::
   u64 flags;			/* kernel flags, little endian */
   u64 res2	= 0;		/* reserved */
   u64 res3	= 0;		/* reserved */
-  u64 res4	= 0;		/* reserved */
+  u32 res4	= 0;		/* reserved */
+  u32 efi_image_info_offset;	/* Offset to struct efi_image_info */
   u32 magic	= 0x644d5241;	/* Magic number, little endian, "ARM\x64" */
   u32 res5;			/* reserved (used for PE COFF offset) */
 
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index da6afd4a7a27..b0c9120b9741 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -154,4 +154,7 @@ void efi_icache_sync(unsigned long start, unsigned long end);
 // temporary resolution for efistub_get_code_size()
 #define efistub_get_code_size(image_info) ({ extern u32 code_size; code_size; })
 
+struct efi_image_info {
+};
+
 #endif /* _ASM_EFI_H */
diff --git a/arch/arm64/include/asm/image.h b/arch/arm64/include/asm/image.h
index 9ba85173f857..10b35521cf28 100644
--- a/arch/arm64/include/asm/image.h
+++ b/arch/arm64/include/asm/image.h
@@ -36,6 +36,7 @@
  * @image_size:		Effective Image size
  * @flags:		kernel flags
  * @reserved:		reserved
+ * @efi_image_offset:	Offset to struct efi_image_info
  * @magic:		Magic number
  * @reserved5:		reserved, or
  *   @pe_header:	  alternatively used for PE COFF offset
@@ -49,7 +50,8 @@ struct arm64_image_header {
 	__le64 flags;
 	__le64 res2;
 	__le64 res3;
-	__le64 res4;
+	__le32 res4;
+	__le32 efi_image_info_offset;
 	__le32 magic;
 	__le32 res5;
 };
diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index 329e8df9215f..62061cb0bf21 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -7,6 +7,12 @@
 #include <linux/pe.h>
 #include <linux/sizes.h>
 
+#ifdef CONFIG_EFI
+#define EFI_IMAGE_INFO_OFFSET  __efistub_efi_image_info - .L_head
+#else
+#define EFI_IMAGE_INFO_OFFSET	0
+#endif
+
 	.macro	efi_signature_nop
 #ifdef CONFIG_EFI
 .L_head:
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index d6ba3c0af811..f1827e32b0e5 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -65,7 +65,8 @@
 	le64sym	_kernel_flags_le		// Informative flags, little-endian
 	.quad	0				// reserved
 	.quad	0				// reserved
-	.quad	0				// reserved
+       .long   0                               // reserved
+       .long   EFI_IMAGE_INFO_OFFSET           // Offset to struct efi_image_info
 	.ascii	ARM64_IMAGE_MAGIC		// Magic number
 	.long	.Lpe_header_offset		// Offset to the PE header.
 
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index 2c3869356147..8daed681f97d 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -61,3 +61,17 @@ void efi_icache_sync(unsigned long start, unsigned long end)
 {
 	caches_clean_inval_pou(start, end);
 }
+
+extern const struct efi_image_info efi_image_info;
+
+asm("	.section \".rodata\", \"a\", %progbits;			" \
+    "	.align	3;						" \
+    "	.globl	efi_image_info;					" \
+    "efi_image_info:						" \
+    "	.previous						");
+
+
+const struct efi_image_info *efistub_get_image_info(void)
+{
+	return &efi_image_info;
+}
diff --git a/drivers/firmware/efi/libstub/arm64.c b/drivers/firmware/efi/libstub/arm64.c
index 7ab634e37cf1..190cf180bb23 100644
--- a/drivers/firmware/efi/libstub/arm64.c
+++ b/drivers/firmware/efi/libstub/arm64.c
@@ -135,3 +135,10 @@ void __noreturn efi_enter_kernel(unsigned long entrypoint,
 	enter_kernel = (void *)entrypoint + primary_entry_offset();
 	enter_kernel(fdt_addr, 0, 0, 0);
 }
+
+const struct efi_image_info *zboot_get_image_info(unsigned long image_base)
+{
+	auto header = (const struct arm64_image_header *)image_base;
+
+	return (void *)image_base + header->efi_image_info_offset;
+}
-- 
2.56.0.455.g6c5a503b38-goog


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

* [PATCH 5/5] efi/arm64: Drop build and linker script hacks to obtain image code size
  2026-11-06 14:19 [PATCH 0/5] efi: Expose loaded image properties via info struct Ard Biesheuvel
                   ` (3 preceding siblings ...)
  2026-11-06 14:19 ` [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header Ard Biesheuvel
@ 2026-11-06 14:19 ` Ard Biesheuvel
  2026-11-06 14:33   ` sashiko-bot
  4 siblings, 1 reply; 13+ messages in thread
From: Ard Biesheuvel @ 2026-11-06 14:19 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, mark.rutland, will, catalin.marinas,
	Ard Biesheuvel, Jason Gunthorpe

From: Ard Biesheuvel <ardb@kernel.org>

Instead of taking vmlinux symbol values at build time and poking them
into the zboot linker script, wire up struct efi_image_info so this
information can be obtained from the code.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/boot/Makefile                  |  3 ---
 arch/arm64/include/asm/efi.h              | 11 ++++++++---
 arch/arm64/kernel/image-vars.h            |  4 ----
 drivers/firmware/efi/libstub/arm64-stub.c |  2 ++
 drivers/firmware/efi/libstub/arm64.c      |  4 +---
 drivers/firmware/efi/libstub/zboot.lds    |  7 -------
 6 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
index d42d07667822..509b59518818 100644
--- a/arch/arm64/boot/Makefile
+++ b/arch/arm64/boot/Makefile
@@ -51,7 +51,4 @@ EFI_ZBOOT_BFD_TARGET	:= elf64-littleaarch64
 EFI_ZBOOT_MACH_TYPE	:= ARM64
 EFI_ZBOOT_FORWARD_CFI	:= $(CONFIG_ARM64_BTI_KERNEL)
 
-EFI_ZBOOT_OBJCOPY_FLAGS	= --add-symbol zboot_code_size=0x$$( \
-				$(NM) vmlinux|grep _kernel_codesize|cut -d' ' -f1)
-
 include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index b0c9120b9741..3194e133a4d5 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -151,10 +151,15 @@ efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f);
 
 void efi_icache_sync(unsigned long start, unsigned long end);
 
-// temporary resolution for efistub_get_code_size()
-#define efistub_get_code_size(image_info) ({ extern u32 code_size; code_size; })
-
 struct efi_image_info {
+	s32 _text_offset;
+	s32 __inittext_end_offset;
 };
 
+static inline u32 efistub_get_code_size(const struct efi_image_info *info)
+{
+	return info->__inittext_end_offset - info->_text_offset;
+}
+#define efistub_get_code_size efistub_get_code_size
+
 #endif /* _ASM_EFI_H */
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 19d602e45523..b02234f080b0 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -150,10 +150,6 @@ KVM_NVHE_ALIAS(kvm_protected_mode_initialized);
 
 #endif /* CONFIG_KVM */
 
-#ifdef CONFIG_EFI_ZBOOT
-_kernel_codesize = ABSOLUTE(__inittext_end - _text);
-#endif
-
 /*
  * LLD will occasionally error out with a '__init_end does not converge' error
  * if INIT_IDMAP_DIR_SIZE is defined in terms of _end, as this results in a
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index 8daed681f97d..754cb2843967 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -68,6 +68,8 @@ asm("	.section \".rodata\", \"a\", %progbits;			" \
     "	.align	3;						" \
     "	.globl	efi_image_info;					" \
     "efi_image_info:						" \
+    "	.long	_text - efi_image_info;				" \
+    "	.long	__inittext_end - efi_image_info;		" \
     "	.previous						");
 
 
diff --git a/drivers/firmware/efi/libstub/arm64.c b/drivers/firmware/efi/libstub/arm64.c
index 190cf180bb23..da6fa2f6c821 100644
--- a/drivers/firmware/efi/libstub/arm64.c
+++ b/drivers/firmware/efi/libstub/arm64.c
@@ -88,8 +88,6 @@ efi_status_t check_platform_features(void)
 #define DCTYPE	"cvau"
 #endif
 
-u32 __weak code_size;
-
 void efi_cache_sync_image(unsigned long image_base,
 			  unsigned long alloc_size)
 {
@@ -100,7 +98,7 @@ void efi_cache_sync_image(unsigned long image_base,
 	/* only perform the cache maintenance if needed for I/D coherency */
 	if (!(ctr & BIT(CTR_EL0_IDC_SHIFT))) {
 		unsigned long base = image_base;
-		unsigned long size = code_size;
+		unsigned long size = alloc_size;
 
 		do {
 			asm("dc " DCTYPE ", %0" :: "r"(base));
diff --git a/drivers/firmware/efi/libstub/zboot.lds b/drivers/firmware/efi/libstub/zboot.lds
index 367907eb7d86..61714a151766 100644
--- a/drivers/firmware/efi/libstub/zboot.lds
+++ b/drivers/firmware/efi/libstub/zboot.lds
@@ -2,8 +2,6 @@
 
 ENTRY(__efistub_efi_zboot_header);
 
-PROVIDE(zboot_code_size = ABSOLUTE(0));
-
 SECTIONS
 {
 	.head : ALIGN(4096) {
@@ -20,11 +18,6 @@ SECTIONS
 		__efistub_payload_size = . - 4;
 		__efistub__gzdata_end = .;
 		*(.rodata* .init.rodata* .srodata*)
-
-		. = ALIGN(4);
-		__efistub_code_size = .;
-		LONG(zboot_code_size);
-
 		_etext = ALIGN(4096);
 		. = _etext;
 	}
-- 
2.56.0.455.g6c5a503b38-goog


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

* Re: [PATCH 2/5] efi/libstub: Pass a struct efi_image_info to efi_stub_common()
  2026-11-06 14:19 ` [PATCH 2/5] efi/libstub: Pass a struct efi_image_info to efi_stub_common() Ard Biesheuvel
@ 2026-11-06 14:27   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-11-06 14:27 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-efi
  Cc: mark.rutland, will, catalin.marinas, Ard Biesheuvel,
	Jason Gunthorpe

Thank you for your contribution! Sashiko AI review found no new issues
in this patch, but noticed 1 related pre-existing issue it does not
introduce:
- [High] efi/libstub: freed memory retains RO/XP attributes in
  efi_zboot_entry() [1]
--

commit ddd62e73ed528e3f2c2ae65f0467b40b21e1c353
Author: Ard Biesheuvel <ardb@kernel.org>

efi/libstub: Pass a struct efi_image_info to efi_stub_common()

This commit passes a struct efi_image_info pointer from both efi_pe_entry()
and efi_zboot_entry() into efi_stub_common().

> diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
> index 4a5ffe164873e..97ae706c034ad 100644
> --- a/drivers/firmware/efi/libstub/zboot.c
> +++ b/drivers/firmware/efi/libstub/zboot.c
[ ... ]
> @@ -93,9 +98,15 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
>  	}
>  
>  	// Decompress the payload into the newly allocated buffer
> -	status = efi_zboot_decompress((void *)image_base, alloc_size) ?:
> -	         efi_stub_common(handle, image, image_base, cmdline_ptr);
> +	status = efi_zboot_decompress((void *)image_base, alloc_size);
> +	if (status != EFI_SUCCESS)
> +		goto error;
> +
> +	auto image_info = zboot_get_image_info(image_base);
> +	status = efi_stub_common(handle, image, image_base, cmdline_ptr,
> +				 image_info);
>  
> +error:
>  	efi_free(alloc_size, image_base);
>  	return status;
>  }

[Severity: High]
This problem wasn't introduced by this patch, but can efi_free() return
pages at image_base to the firmware pool while they still carry EFI_MEMORY_RO
and EFI_MEMORY_XP attributes [1]?

When efi_zboot_decompress() succeeds, it remaps the decompressed image's code
as read-only and its data as non-executable via efi_remap_image().  If
efi_stub_common() then fails, efi_free() frees image_base without clearing
those attributes, and UEFI does not require FreePages() to clear memory
attributes automatically.  Later firmware allocations that reuse those pages
(such as during boot fallback) can fault and crash when writing data or
executing code.

[1] https://sashiko.dev/#/bug/linux-e232037c-ef9b-47bd-b6d0-1bea4732c0e2

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261106141936.2744481-7-ardb+git@google.com?part=2

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

* Re: [PATCH 5/5] efi/arm64: Drop build and linker script hacks to obtain image code size
  2026-11-06 14:19 ` [PATCH 5/5] efi/arm64: Drop build and linker script hacks to obtain image code size Ard Biesheuvel
@ 2026-11-06 14:33   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-11-06 14:33 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-efi
  Cc: mark.rutland, will, catalin.marinas, Ard Biesheuvel,
	Jason Gunthorpe

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Low] efi/zboot: redundant full-image cache sync in
  efi_zboot_decompress()
It also noticed 1 related pre-existing issue this patch does not
introduce:
- [High] efi/libstub: arm64: missing DSB ISH in efi_cache_sync_image()
  [1]
--

commit 579820756d50227a71aeb397996f2064f5e5696a
Author: Ard Biesheuvel <ardb@kernel.org>

efi/arm64: Drop build and linker script hacks to obtain image code size

This commit replaces the build-time symbol injection and linker script
logic for obtaining the kernel code size in EFI zboot with offsets stored
in struct efi_image_info, and updates efi_cache_sync_image() to use its
alloc_size argument.

> diff --git a/drivers/firmware/efi/libstub/arm64.c b/drivers/firmware/efi/libstub/arm64.c
> index 190cf180bb234..da6fa2f6c8219 100644
> --- a/drivers/firmware/efi/libstub/arm64.c
> +++ b/drivers/firmware/efi/libstub/arm64.c
> @@ -88,8 +88,6 @@ efi_status_t check_platform_features(void)
>  #define DCTYPE	"cvau"
>  #endif
>  
> -u32 __weak code_size;
> -
>  void efi_cache_sync_image(unsigned long image_base,
>  			  unsigned long alloc_size)
>  {
> @@ -100,7 +98,7 @@ void efi_cache_sync_image(unsigned long image_base,
>  	/* only perform the cache maintenance if needed for I/D coherency */
>  	if (!(ctr & BIT(CTR_EL0_IDC_SHIFT))) {
>  		unsigned long base = image_base;
> -		unsigned long size = code_size;
> +		unsigned long size = alloc_size;
>  
>  		do {
>  			asm("dc " DCTYPE ", %0" :: "r"(base));

[Severity: Low]
Does changing size from code_size to alloc_size cause efi_zboot_decompress()
to clean the data cache across the entire decompressed image allocation
before efi_zboot_remap_image() syncs the code region a second time?

Both gzip and zstd implementations of efi_zboot_decompress() still call
efi_cache_sync_image((unsigned long)out, outlen) with the full allocation
size (including rodata, data, and BSS), and efi_zboot_entry() then calls
efi_zboot_remap_image() -> efi_cache_sync_image(image_base, code_size)
immediately afterward.

[Severity: High]
This problem wasn't introduced by this patch, but is a dsb(ish) barrier
needed [1] between the data cache clean loop and ic ialluis in
efi_cache_sync_image()?

drivers/firmware/efi/libstub/arm64.c:efi_cache_sync_image() {
	...
	if (!(ctr & BIT(CTR_EL0_IDC_SHIFT))) {
		unsigned long base = image_base;
		unsigned long size = alloc_size;

		do {
			asm("dc " DCTYPE ", %0" :: "r"(base));
			base += lsize;
			size -= lsize;
		} while (size >= lsize);
	}

	asm("ic ialluis");
	dsb(ish);
	isb();
}

Without a barrier after the dc maintenance instructions, ic ialluis can
execute before the data cache cleans complete, allowing the instruction
cache to refetch stale instructions during early boot.

[1] https://sashiko.dev/#/bug/linux-3f5f98cd-053a-49ef-9e97-834ca6744a2c

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261106141936.2744481-7-ardb+git@google.com?part=5

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

* Re: [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header
  2026-11-06 14:19 ` [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header Ard Biesheuvel
@ 2026-11-06 14:34   ` Jason Gunthorpe
  2026-11-06 15:51     ` Ard Biesheuvel
  0 siblings, 1 reply; 13+ messages in thread
From: Jason Gunthorpe @ 2026-11-06 14:34 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, linux-arm-kernel, mark.rutland, will, catalin.marinas,
	Ard Biesheuvel

On Fri, Nov 06, 2026 at 03:19:41PM +0100, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
> 
> The zboot compressed kernel and the uncompressed Image both contain a
> copy of the EFI stub, and both are tightly coupled to the kernel image.
> 
> However, the zboot stub is not linked into vmlinux like the ordinary EFI
> stub is, and so it does not have direct access to its symbols. This is
> needed today for things like image size and code size, but there are
> more cases coming (DRTM) where both stubs need to have a consistent view
> of these things.
> 
> So add a struct efi_image_info that is built into vmlinux and exposed
> via the image header, so that zboot can access it easily.

I tried hard to avoid doing this because I didn't want to make the
struct layout ABI. I really see only negatives to that.

Putting it here and documenting it in the rst is going to encourage
other bootloaders to look inside it and try to read the contents. :(

The linker trick to inject the offset into zboot seemed better because
it completely prevents it from being ABI as nothing but the EFI stubs
can ever locate it.

Also, I wanted it to eventually be cross arch and I don't know if
other arches have any spare space like this.

Jason

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

* Re: [PATCH 3/5] efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image()
  2026-11-06 14:19 ` [PATCH 3/5] efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image() Ard Biesheuvel
@ 2026-11-06 14:34   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-11-06 14:34 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-efi
  Cc: mark.rutland, will, catalin.marinas, Ard Biesheuvel,
	Jason Gunthorpe

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Low] efi/zboot: duplicate efi_cache_sync_image() calls after
  decompression
--

commit c04555ab5ec2e8a3cceff169f625d907a16b1267
Author: Ard Biesheuvel <ardb@kernel.org>

efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image()

This commit moves the efi_remap_image() call out of arm64's
efi_cache_sync_image() into a new efi_zboot_remap_image() helper called from
efi_zboot_entry().

> diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
> index 97ae706c034ad..27f6661253c08 100644
> --- a/drivers/firmware/efi/libstub/zboot.c
> +++ b/drivers/firmware/efi/libstub/zboot.c
> @@ -36,6 +36,26 @@ const struct efi_image_info * __weak zboot_get_image_info(unsigned long image_ba
>  	return NULL;
>  }
>  
> +static efi_status_t efi_zboot_remap_image(const struct efi_image_info *image_info,
> +					  unsigned long image_base,
> +					  unsigned long image_size)
> +{
> +	unsigned long code_size = efistub_get_code_size(image_info);
> +	efi_status_t status;
> +
> +	if (code_size) {
> +		efi_cache_sync_image(image_base, code_size);
> +
> +		status = efi_remap_image(image_base, image_size, code_size);
> +		if (status != EFI_SUCCESS)
> +			return status;
> +	} else {
> +		efi_cache_sync_image(image_base, image_size);
> +	}
> +
> +	return EFI_SUCCESS;
> +}

[Severity: Low]
Does calling efi_cache_sync_image() in efi_zboot_remap_image() duplicate the
cache sync already performed at the end of efi_zboot_decompress()?

0dc1754e16b4 ("efi/libstub: Avoid legacy decompressor zlib/zstd wrappers")
moved efi_cache_sync_image((unsigned long)out, outlen) into
efi_zboot_decompress() in both zboot-decompress-gzip.c and
zboot-decompress-zstd.c.  Because efi_zboot_entry() calls
efi_zboot_remap_image() right after efi_zboot_decompress(),
efi_cache_sync_image() now runs twice back-to-back on every zboot boot, first
over the full allocation and then over code_size.  Should the
efi_cache_sync_image() calls in efi_zboot_decompress() be dropped?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261106141936.2744481-7-ardb+git@google.com?part=3

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

* Re: [PATCH 1/5] efi/libstub: Make efi_remap_image() return efi_status_t
  2026-11-06 14:19 ` [PATCH 1/5] efi/libstub: Make efi_remap_image() return efi_status_t Ard Biesheuvel
@ 2026-11-06 14:36   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-11-06 14:36 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-efi
  Cc: mark.rutland, will, catalin.marinas, Ard Biesheuvel,
	Jason Gunthorpe

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Low] efi/libstub: missing Return: section in efi_remap_image()
  kernel-doc
--

commit 87d3e561f50dd1226f0d061af43fd4aa4ab0ee9c
Author: Ard Biesheuvel <ardb@kernel.org>

efi/libstub: Make efi_remap_image() return efi_status_t

This commit changes efi_remap_image() to return an efi_status_t so callers
are notified if remapping code or data regions via the EFI Memory
Attributes Protocol fails.

> diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
> index 8e43eb3f418b1..b2ad081cf324c 100644
> --- a/drivers/firmware/efi/libstub/efi-stub-helper.c
> +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
> @@ -698,8 +698,8 @@ efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
>   * read-write/non-executable. The code region is assumed to start at the base
>   * of the image, and will therefore cover the PE/COFF header as well.
>   */
> -void efi_remap_image(unsigned long image_base, unsigned alloc_size,
> -		     unsigned long code_size)
> +efi_status_t efi_remap_image(unsigned long image_base, unsigned alloc_size,
> +			     unsigned long code_size)

[Severity: Low]
This isn't a bug, but now that efi_remap_image() returns efi_status_t
instead of void, the preceding kernel-doc comment needs a Return: section
to avoid a kernel-doc -Wreturn warning (make W=2).

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261106141936.2744481-7-ardb+git@google.com?part=1

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

* Re: [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header
  2026-11-06 14:34   ` Jason Gunthorpe
@ 2026-11-06 15:51     ` Ard Biesheuvel
  2026-11-06 17:09       ` Jason Gunthorpe
  0 siblings, 1 reply; 13+ messages in thread
From: Ard Biesheuvel @ 2026-11-06 15:51 UTC (permalink / raw)
  To: Jason Gunthorpe, Ard Biesheuvel
  Cc: linux-efi, linux-arm-kernel, Mark Rutland, Will Deacon,
	Catalin Marinas



On Fri, 6 Nov 2026, at 15:34, Jason Gunthorpe wrote:
> On Fri, Nov 06, 2026 at 03:19:41PM +0100, Ard Biesheuvel wrote:
>> From: Ard Biesheuvel <ardb@kernel.org>
>> 
>> The zboot compressed kernel and the uncompressed Image both contain a
>> copy of the EFI stub, and both are tightly coupled to the kernel image.
>> 
>> However, the zboot stub is not linked into vmlinux like the ordinary EFI
>> stub is, and so it does not have direct access to its symbols. This is
>> needed today for things like image size and code size, but there are
>> more cases coming (DRTM) where both stubs need to have a consistent view
>> of these things.
>> 
>> So add a struct efi_image_info that is built into vmlinux and exposed
>> via the image header, so that zboot can access it easily.
>
> I tried hard to avoid doing this because I didn't want to make the
> struct layout ABI. I really see only negatives to that.
>
> Putting it here and documenting it in the rst is going to encourage
> other bootloaders to look inside it and try to read the contents. :(
>

Fair point.

> The linker trick to inject the offset into zboot seemed better because
> it completely prevents it from being ABI as nothing but the EFI stubs
> can ever locate it.
>
> Also, I wanted it to eventually be cross arch and I don't know if
> other arches have any spare space like this.
>

Yeah so let's bring back the code injection hack but only for the
offset of image info. 

What I would still like to avoid (compared to your proposal) are:
- having the efi_image_info pointer be a global that can be grabbed
from anywhere, even though in zboot, it only becomes valid after
the decompression has been performed;
- putting every shared variable in the linker script.

Please confirm whether those aspects look ok to you, and I'll respin
this quickly.


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

* Re: [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header
  2026-11-06 15:51     ` Ard Biesheuvel
@ 2026-11-06 17:09       ` Jason Gunthorpe
  0 siblings, 0 replies; 13+ messages in thread
From: Jason Gunthorpe @ 2026-11-06 17:09 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Ard Biesheuvel, linux-efi, linux-arm-kernel, Mark Rutland,
	Will Deacon, Catalin Marinas

On Fri, Nov 06, 2026 at 04:51:09PM +0100, Ard Biesheuvel wrote:

> > Also, I wanted it to eventually be cross arch and I don't know if
> > other arches have any spare space like this.
> 
> Yeah so let's bring back the code injection hack but only for the
> offset of image info. 

OK, that great

> What I would still like to avoid (compared to your proposal) are:
> - having the efi_image_info pointer be a global that can be grabbed
> from anywhere, even though in zboot, it only becomes valid after
> the decompression has been performed;

Yeah, I liked what you did here by passing it through the call
chain. That's nice, I wasn't bold enough to try that.

> - putting every shared variable in the linker script.

It took me a bit to understand what this does:

@@ -68,6 +68,8 @@ asm("	.section \".rodata\", \"a\", %progbits;			" \
     "	.align	3;						" \
     "	.globl	efi_image_info;					" \
     "efi_image_info:						" \
+    "	.long	_text - efi_image_info;				" \
+    "	.long	__inittext_end - efi_image_info;		" \
     "	.previous						");
 
Generating a PC relative R_AARCH64_PREL32 relocation is a very clever
trick! I see no issue with it.

The .long should be expanded to 64 bits, I already got a kbuild 0-day
failure from some crazy kconfig that overflowed the 32 bits I had
originally. The linker script version did have assertions to detect
that.

It also still needs every shared variable to be put in the linker
script, these patches don't show it but these are still required:

PROVIDE(__efistub__text			= _text);
PROVIDE(__efistub___inittext_end       	= __inittext_end);

IMHO it would be a bit nicer to put the asm block in a file that
doesn't get the __efistub__ symbol renaming so even these provides are
not required? It is why I put it in the main build and not in the
stub, also I thought it would let it work better for x86 which doesn't
use the built in stub?

Jason

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

end of thread, other threads:[~2026-11-06 17:09 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-06 14:19 [PATCH 0/5] efi: Expose loaded image properties via info struct Ard Biesheuvel
2026-11-06 14:19 ` [PATCH 1/5] efi/libstub: Make efi_remap_image() return efi_status_t Ard Biesheuvel
2026-11-06 14:36   ` sashiko-bot
2026-11-06 14:19 ` [PATCH 2/5] efi/libstub: Pass a struct efi_image_info to efi_stub_common() Ard Biesheuvel
2026-11-06 14:27   ` sashiko-bot
2026-11-06 14:19 ` [PATCH 3/5] efi/zboot: Disentangle efi_remap_image() from efi_cache_sync_image() Ard Biesheuvel
2026-11-06 14:34   ` sashiko-bot
2026-11-06 14:19 ` [PATCH 4/5] efi/arm64: Expose struct efi_image_info via the image header Ard Biesheuvel
2026-11-06 14:34   ` Jason Gunthorpe
2026-11-06 15:51     ` Ard Biesheuvel
2026-11-06 17:09       ` Jason Gunthorpe
2026-11-06 14:19 ` [PATCH 5/5] efi/arm64: Drop build and linker script hacks to obtain image code size Ard Biesheuvel
2026-11-06 14:33   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox