From 674a9f1f6815849bfb5bf385e7da8fc198aaaba9 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Thu, 8 Jul 2021 11:46:54 +0200 Subject: [PATCH 1/4] efi/tpm: Differentiate missing and invalid final event log table. Missing TPM final event log table is not a firmware bug. Clearly if providing event log in the old format makes the final event log invalid it should not be provided at least in that case. Fixes: b4f1874c6216 ("tpm: check event log version before reading final events") Signed-off-by: Michal Suchanek Reviewed-by: Jarkko Sakkinen Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/tpm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c index c1955d320fec..8f665678e9e3 100644 --- a/drivers/firmware/efi/tpm.c +++ b/drivers/firmware/efi/tpm.c @@ -62,9 +62,11 @@ int __init efi_tpm_eventlog_init(void) tbl_size = sizeof(*log_tbl) + log_tbl->size; memblock_reserve(efi.tpm_log, tbl_size); - if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || - log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { - pr_warn(FW_BUG "TPM Final Events table missing or invalid\n"); + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) { + pr_info("TPM Final Events table not present\n"); + goto out; + } else if (log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { + pr_warn(FW_BUG "TPM Final Events table invalid\n"); goto out; } From 2bab693a608bdf614b9fcd44083c5100f34b9f77 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 13 Jul 2021 19:43:26 +0100 Subject: [PATCH 2/4] firmware/efi: Tell memblock about EFI iomem reservations kexec_load_file() relies on the memblock infrastructure to avoid stamping over regions of memory that are essential to the survival of the system. However, nobody seems to agree how to flag these regions as reserved, and (for example) EFI only publishes its reservations in /proc/iomem for the benefit of the traditional, userspace based kexec tool. On arm64 platforms with GICv3, this can result in the payload being placed at the location of the LPI tables. Shock, horror! Let's augment the EFI reservation code with a memblock_reserve() call, protecting our dear tables from the secondary kernel invasion. Reported-by: Moritz Fischer Tested-by: Moritz Fischer Signed-off-by: Marc Zyngier Cc: stable@vger.kernel.org Cc: Ard Biesheuvel Cc: James Morse Cc: Catalin Marinas Cc: Will Deacon Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/efi.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 4b7ee3fa9224..847f33ffc4ae 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -896,6 +896,7 @@ static int __init efi_memreserve_map_root(void) static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) { struct resource *res, *parent; + int ret; res = kzalloc(sizeof(struct resource), GFP_ATOMIC); if (!res) @@ -908,7 +909,17 @@ static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) /* we expect a conflict with a 'System RAM' region */ parent = request_resource_conflict(&iomem_resource, res); - return parent ? request_resource(parent, res) : 0; + ret = parent ? request_resource(parent, res) : 0; + + /* + * Given that efi_mem_reserve_iomem() can be called at any + * time, only call memblock_reserve() if the architecture + * keeps the infrastructure around. + */ + if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK) && !ret) + memblock_reserve(addr, size); + + return ret; } int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) From 947228cb9f1a2c69a5da5279c48f02bb4f49ce32 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 2 Jul 2021 12:10:44 -0700 Subject: [PATCH 3/4] efi/libstub: Fix the efi_load_initrd function description The soft_limit and hard_limit in the function efi_load_initrd describes the preferred and max address of initrd loading location respectively. However, the description wrongly describes it as the size of the allocated memory. Fix the function description. Signed-off-by: Atish Patra Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efi-stub-helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index aa8da0a49829..ae87dded989d 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -630,8 +630,8 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, * @image: EFI loaded image protocol * @load_addr: pointer to loaded initrd * @load_size: size of loaded initrd - * @soft_limit: preferred size of allocated memory for loading the initrd - * @hard_limit: minimum size of allocated memory + * @soft_limit: preferred address for loading the initrd + * @hard_limit: upper limit address for loading the initrd * * Return: status code */ From 47e1e233e9d822dfda068383fb9a616451bda703 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 20 Jul 2021 09:28:09 +0200 Subject: [PATCH 4/4] efi/mokvar: Reserve the table only if it is in boot services data One of the SUSE QA tests triggered: localhost kernel: efi: Failed to lookup EFI memory descriptor for 0x000000003dcf8000 which comes from x86's version of efi_arch_mem_reserve() trying to reserve a memory region. Usually, that function expects EFI_BOOT_SERVICES_DATA memory descriptors but the above case is for the MOKvar table which is allocated in the EFI shim as runtime services. That lead to a fix changing the allocation of that table to boot services. However, that fix broke booting SEV guests with that shim leading to this kernel fix 8d651ee9c71b ("x86/ioremap: Map EFI-reserved memory as encrypted for SEV") which extended the ioremap hint to map reserved EFI boot services as decrypted too. However, all that wasn't needed, IMO, because that error message in efi_arch_mem_reserve() was innocuous in this case - if the MOKvar table is not in boot services, then it doesn't need to be reserved in the first place because it is, well, in runtime services which *should* be reserved anyway. So do that reservation for the MOKvar table only if it is allocated in boot services data. I couldn't find any requirement about where that table should be allocated in, unlike the ESRT which allocation is mandated to be done in boot services data by the UEFI spec. Signed-off-by: Borislav Petkov Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/mokvar-table.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c index d8bc01340686..38722d2009e2 100644 --- a/drivers/firmware/efi/mokvar-table.c +++ b/drivers/firmware/efi/mokvar-table.c @@ -180,7 +180,10 @@ void __init efi_mokvar_table_init(void) pr_err("EFI MOKvar config table is not valid\n"); return; } - efi_mem_reserve(efi.mokvar_table, map_size_needed); + + if (md.type == EFI_BOOT_SERVICES_DATA) + efi_mem_reserve(efi.mokvar_table, map_size_needed); + efi_mokvar_table_size = map_size_needed; }