Linux EFI development
 help / color / mirror / Atom feed
* [PATCH 0/3] efi: Unconditionally preserve kernel's own config tables
@ 2026-10-15  6:51 Ard Biesheuvel
  2026-10-15  6:51 ` [PATCH 1/3] efi/libstub: Don't replace an existing LINUX_EFI_MEMRESERVE table Ard Biesheuvel
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2026-10-15  6:51 UTC (permalink / raw)
  To: linux-efi; +Cc: Ard Biesheuvel

From: Ard Biesheuvel <ardb@kernel.org>

Some prepwork for kexec via the EFI stub, which may never land, but
these are arguably cleanups in their own right, or neutral at the least.

Ard Biesheuvel (3):
  efi/libstub: Don't replace an existing LINUX_EFI_MEMRESERVE table
  efi: Retain the address of the LINUX_EFI_MEMRESERVE table
  efi: Initialize all configuration table addresses to
    EFI_INVALID_TABLE_ADDR

 drivers/firmware/efi/efi.c              | 18 ++++++------------
 drivers/firmware/efi/libstub/efi-stub.c |  8 ++++++++
 include/linux/efi.h                     |  1 +
 3 files changed, 15 insertions(+), 12 deletions(-)

-- 
2.56.0.385.gd3acb90ef8-goog


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

* [PATCH 1/3] efi/libstub: Don't replace an existing LINUX_EFI_MEMRESERVE table
  2026-10-15  6:51 [PATCH 0/3] efi: Unconditionally preserve kernel's own config tables Ard Biesheuvel
@ 2026-10-15  6:51 ` Ard Biesheuvel
  2026-10-15  6:51 ` [PATCH 2/3] efi: Retain the address of the " Ard Biesheuvel
  2026-10-15  6:51 ` [PATCH 3/3] efi: Initialize all configuration table addresses to EFI_INVALID_TABLE_ADDR Ard Biesheuvel
  2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2026-10-15  6:51 UTC (permalink / raw)
  To: linux-efi; +Cc: Ard Biesheuvel

From: Ard Biesheuvel <ardb@kernel.org>

The LINUX_EFI_MEMRESERVE table is the root of a linked list of memory
reservations that need to persist across kexec, such as the GICv3 LPI
pending and property tables, which cannot be moved once the
redistributors have been enabled. Each kernel adds its own reservations
to the list that it finds via the EFI configuration table, and honours
the ones made by its predecessors.

The EFI stub installs a new, empty table unconditionally, replacing any
existing one. This is fine on a cold boot, but not if the stub is being
executed by a loader that passes on the configuration tables of an
earlier kernel, e.g., a kexec loader that runs the incoming kernel's EFI
stub, as the reservations made by earlier kernels would be lost.

So leave an existing table in place, and only install a new one if none
exists yet.

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

diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 975148f986bf..6db10590f89b 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -83,6 +83,14 @@ static void install_memreserve_table(void)
 	struct linux_efi_memreserve *rsv;
 	efi_status_t status;
 
+	/*
+	 * If an earlier boot stage installed a memreserve table already, e.g.,
+	 * a kexec loader passing on the persistent reservations made by the
+	 * previous kernel, use it as is: installing a new one would replace it.
+	 */
+	if (get_efi_config_table(memreserve_table_guid))
+		return;
+
 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
 			     (void **)&rsv);
 	if (status != EFI_SUCCESS) {
-- 
2.56.0.385.gd3acb90ef8-goog


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

* [PATCH 2/3] efi: Retain the address of the LINUX_EFI_MEMRESERVE table
  2026-10-15  6:51 [PATCH 0/3] efi: Unconditionally preserve kernel's own config tables Ard Biesheuvel
  2026-10-15  6:51 ` [PATCH 1/3] efi/libstub: Don't replace an existing LINUX_EFI_MEMRESERVE table Ard Biesheuvel
@ 2026-10-15  6:51 ` Ard Biesheuvel
  2026-10-15  6:51 ` [PATCH 3/3] efi: Initialize all configuration table addresses to EFI_INVALID_TABLE_ADDR Ard Biesheuvel
  2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2026-10-15  6:51 UTC (permalink / raw)
  To: linux-efi; +Cc: Ard Biesheuvel

From: Ard Biesheuvel <ardb@kernel.org>

The physical address of the LINUX_EFI_MEMRESERVE configuration table is
only kept in __initdata, but a kexec loader that runs the incoming
kernel's EFI stub needs it in order to pass the table on, so that the
persistent memory reservations made by this kernel and its predecessors
(e.g., for the GICv3 LPI tables) are carried over.

So move it into struct efi, alongside the addresses of the other EFI
configuration tables that may be passed on in this way.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/efi.c | 12 ++++++------
 include/linux/efi.h        |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index b4504542cb2c..14b9c7ebb5df 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -46,6 +46,7 @@ struct efi __read_mostly efi = {
 	.tpm_log		= EFI_INVALID_TABLE_ADDR,
 	.tpm_final_log		= EFI_INVALID_TABLE_ADDR,
 	.ovmf_debug_log         = EFI_INVALID_TABLE_ADDR,
+	.mem_reserve		= EFI_INVALID_TABLE_ADDR,
 #ifdef CONFIG_LOAD_UEFI_KEYS
 	.mokvar_table		= EFI_INVALID_TABLE_ADDR,
 #endif
@@ -59,7 +60,6 @@ struct efi __read_mostly efi = {
 EXPORT_SYMBOL(efi);
 
 unsigned long __ro_after_init efi_rng_seed = EFI_INVALID_TABLE_ADDR;
-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;
 
@@ -663,7 +663,7 @@ static const efi_config_table_type_t common_tables[] __initconst = {
 	{LINUX_EFI_TPM_EVENT_LOG_GUID,		&efi.tpm_log,		"TPMEventLog"	},
 	{EFI_TCG2_FINAL_EVENTS_TABLE_GUID,	&efi.tpm_final_log,	"TPMFinalLog"	},
 	{EFI_CC_FINAL_EVENTS_TABLE_GUID,	&efi.tpm_final_log,	"CCFinalLog"	},
-	{LINUX_EFI_MEMRESERVE_TABLE_GUID,	&mem_reserve,		"MEMRESERVE"	},
+	{LINUX_EFI_MEMRESERVE_TABLE_GUID,	&efi.mem_reserve,	"MEMRESERVE"	},
 	{LINUX_EFI_INITRD_MEDIA_GUID,		&initrd,		"INITRD"	},
 	{EFI_RT_PROPERTIES_TABLE_GUID,		&rt_prop,		"RTPROP"	},
 #ifdef CONFIG_OVMF_DEBUG_LOG
@@ -806,8 +806,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
 
 	efi_tpm_eventlog_init();
 
-	if (mem_reserve != EFI_INVALID_TABLE_ADDR) {
-		unsigned long prsv = mem_reserve;
+	if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
+		unsigned long prsv = efi.mem_reserve;
 
 		while (prsv) {
 			struct linux_efi_memreserve *rsv;
@@ -1094,10 +1094,10 @@ static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
 
 static int __init efi_memreserve_map_root(void)
 {
-	if (mem_reserve == EFI_INVALID_TABLE_ADDR)
+	if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
 		return -ENODEV;
 
-	efi_memreserve_root = memremap(mem_reserve,
+	efi_memreserve_root = memremap(efi.mem_reserve,
 				       sizeof(*efi_memreserve_root),
 				       MEMREMAP_WB);
 	if (WARN_ON_ONCE(!efi_memreserve_root))
diff --git a/include/linux/efi.h b/include/linux/efi.h
index fda81d7c4850..cd8728702e93 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -650,6 +650,7 @@ extern struct efi {
 	unsigned long			mokvar_table;		/* MOK variable config table */
 	unsigned long			coco_secret;		/* Confidential computing secret table */
 	unsigned long			unaccepted;		/* Unaccepted memory table */
+	unsigned long			mem_reserve;		/* Persistent memory reservations */
 
 	efi_get_time_t			*get_time;
 	efi_set_time_t			*set_time;
-- 
2.56.0.385.gd3acb90ef8-goog


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

* [PATCH 3/3] efi: Initialize all configuration table addresses to EFI_INVALID_TABLE_ADDR
  2026-10-15  6:51 [PATCH 0/3] efi: Unconditionally preserve kernel's own config tables Ard Biesheuvel
  2026-10-15  6:51 ` [PATCH 1/3] efi/libstub: Don't replace an existing LINUX_EFI_MEMRESERVE table Ard Biesheuvel
  2026-10-15  6:51 ` [PATCH 2/3] efi: Retain the address of the " Ard Biesheuvel
@ 2026-10-15  6:51 ` Ard Biesheuvel
  2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2026-10-15  6:51 UTC (permalink / raw)
  To: linux-efi; +Cc: Ard Biesheuvel

From: Ard Biesheuvel <ardb@kernel.org>

The addresses of the MOK variable table, the confidential computing
secret area and the unaccepted memory table in struct efi are only
initialized to EFI_INVALID_TABLE_ADDR if support for the respective
table is enabled, and are left at 0 otherwise. This is harmless for
the existing users, which are compiled out in that case, but code that
consumes the table addresses in struct efi generically, such as a kexec
loader that passes the configuration tables on to the incoming kernel,
would mistake 0 for a valid table address.

So initialize all of them unconditionally: efi_config_parse_tables()
only assigns them if support for the table is enabled, and so they
remain EFI_INVALID_TABLE_ADDR otherwise.

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

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 14b9c7ebb5df..9bc22de0d67e 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -47,15 +47,9 @@ struct efi __read_mostly efi = {
 	.tpm_final_log		= EFI_INVALID_TABLE_ADDR,
 	.ovmf_debug_log         = EFI_INVALID_TABLE_ADDR,
 	.mem_reserve		= EFI_INVALID_TABLE_ADDR,
-#ifdef CONFIG_LOAD_UEFI_KEYS
 	.mokvar_table		= EFI_INVALID_TABLE_ADDR,
-#endif
-#ifdef CONFIG_EFI_COCO_SECRET
 	.coco_secret		= EFI_INVALID_TABLE_ADDR,
-#endif
-#ifdef CONFIG_UNACCEPTED_MEMORY
 	.unaccepted		= EFI_INVALID_TABLE_ADDR,
-#endif
 };
 EXPORT_SYMBOL(efi);
 
-- 
2.56.0.385.gd3acb90ef8-goog


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

end of thread, other threads:[~2026-10-15  6:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-15  6:51 [PATCH 0/3] efi: Unconditionally preserve kernel's own config tables Ard Biesheuvel
2026-10-15  6:51 ` [PATCH 1/3] efi/libstub: Don't replace an existing LINUX_EFI_MEMRESERVE table Ard Biesheuvel
2026-10-15  6:51 ` [PATCH 2/3] efi: Retain the address of the " Ard Biesheuvel
2026-10-15  6:51 ` [PATCH 3/3] efi: Initialize all configuration table addresses to EFI_INVALID_TABLE_ADDR Ard Biesheuvel

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