From 4e78921ba4dd0aca1cc89168f45039add4183f8e Mon Sep 17 00:00:00 2001 From: Gen Zhang Date: Sat, 25 May 2019 13:25:58 +0200 Subject: efi/x86/Add missing error handling to old_memmap 1:1 mapping code The old_memmap flow in efi_call_phys_prolog() performs numerous memory allocations, and either does not check for failure at all, or it does but fails to propagate it back to the caller, which may end up calling into the firmware with an incomplete 1:1 mapping. So let's fix this by returning NULL from efi_call_phys_prolog() on memory allocation failures only, and by handling this condition in the caller. Also, clean up any half baked sets of page tables that we may have created before returning with a NULL return value. Note that any failure at this level will trigger a panic() two levels up, so none of this makes a huge difference, but it is a nice cleanup nonetheless. [ardb: update commit log, add efi_call_phys_epilog() call on error path] Signed-off-by: Gen Zhang Signed-off-by: Ard Biesheuvel Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Rob Bradford Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20190525112559.7917-2-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/efi.c | 2 ++ arch/x86/platform/efi/efi_64.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index e1cb01a22fa8..a7189a3b4d70 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -85,6 +85,8 @@ static efi_status_t __init phys_efi_set_virtual_address_map( pgd_t *save_pgd; save_pgd = efi_call_phys_prolog(); + if (!save_pgd) + return EFI_ABORTED; /* Disable interrupts around EFI calls: */ local_irq_save(flags); diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index cf0347f61b21..08ce8177c3af 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -84,13 +84,15 @@ pgd_t * __init efi_call_phys_prolog(void) if (!efi_enabled(EFI_OLD_MEMMAP)) { efi_switch_mm(&efi_mm); - return NULL; + return efi_mm.pgd; } early_code_mapping_set_exec(1); n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); save_pgd = kmalloc_array(n_pgds, sizeof(*save_pgd), GFP_KERNEL); + if (!save_pgd) + return NULL; /* * Build 1:1 identity mapping for efi=old_map usage. Note that @@ -138,10 +140,11 @@ pgd_t * __init efi_call_phys_prolog(void) pgd_offset_k(pgd * PGDIR_SIZE)->pgd &= ~_PAGE_NX; } -out: __flush_tlb_all(); - return save_pgd; +out: + efi_call_phys_epilog(save_pgd); + return NULL; } void __init efi_call_phys_epilog(pgd_t *save_pgd) -- cgit v1.2.3-58-ga151 From 88447c5b93d98be847f428c39ba589779a59eb83 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Sat, 25 May 2019 13:25:59 +0200 Subject: efi: Allow the number of EFI configuration tables entries to be zero Only try and access the EFI configuration tables if there there are any reported. This allows EFI to be continued to used on systems where there are no configuration table entries. Signed-off-by: Rob Bradford Signed-off-by: Ard Biesheuvel Cc: Gen Zhang Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20190525112559.7917-3-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/quirks.c | 3 +++ drivers/firmware/efi/efi.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index feb77777c8b8..632b83885867 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -513,6 +513,9 @@ int __init efi_reuse_config(u64 tables, int nr_tables) void *p, *tablep; struct efi_setup_data *data; + if (nr_tables == 0) + return 0; + if (!efi_setup) return 0; diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 55b77c576c42..521a541d02ad 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -636,6 +636,9 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) void *config_tables; int sz, ret; + if (efi.systab->nr_tables == 0) + return 0; + if (efi_enabled(EFI_64BIT)) sz = sizeof(efi_config_table_64_t); else -- cgit v1.2.3-58-ga151