efi: Retain the address of the LINUX_EFI_MEMRESERVE table

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>
This commit is contained in:
Ard Biesheuvel 2026-10-12 11:59:10 +02:00
parent aaf3ed0f46
commit a278b88b76
2 changed files with 7 additions and 6 deletions

View File

@ -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))

View File

@ -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;