From: Ard Biesheuvel <ard.biesheuvel@linaro.org> To: linux-efi@vger.kernel.org, Ingo Molnar <mingo@kernel.org>, Thomas Gleixner <tglx@linutronix.de> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>, linux-kernel@vger.kernel.org, Andy Lutomirski <luto@kernel.org>, Arend van Spriel <arend.vanspriel@broadcom.com>, Bhupesh Sharma <bhsharma@redhat.com>, Borislav Petkov <bp@alien8.de>, Dave Hansen <dave.hansen@intel.com>, Eric Snowberg <eric.snowberg@oracle.com>, Hans de Goede <hdegoede@redhat.com>, Joe Perches <joe@perches.com>, Jon Hunter <jonathanh@nvidia.com>, Julien Thierry <julien.thierry@arm.com>, Marc Zyngier <marc.zyngier@arm.com>, Nathan Chancellor <natechancellor@gmail.com>, Peter Zijlstra <peterz@infradead.org>, Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, Sedat Dilek <sedat.dilek@gmail.com>, YiFei Zhu <zhuyifei1999@gmail.com> Subject: [PATCH 01/11] x86/efi: Allocate e820 buffer before calling efi_exit_boot_service Date: Thu, 29 Nov 2018 18:12:20 +0100 Message-ID: <20181129171230.18699-2-ard.biesheuvel@linaro.org> (raw) In-Reply-To: <20181129171230.18699-1-ard.biesheuvel@linaro.org> From: Eric Snowberg <eric.snowberg@oracle.com> Commit d64934019f6c ("x86/efi: Use efi_exit_boot_services()") introduced a regression on systems with large memory maps causing them to hang on boot. The first "goto get_map" that was removed from exit_boot insured there was enough room for the memory map when efi_call_early(exit_boot_services) was called. This happens when (nr_desc > ARRAY_SIZE(params->e820_table). Chain of events: exit_boot() efi_exit_boot_services() efi_get_memory_map <- at this point the mm can't grow over 8 desc priv_func() exit_boot_func() allocate_e820ext() <- new mm grows over 8 desc from e820 alloc efi_call_early(exit_boot_services) <- mm key doesn't match so retry efi_call_early(get_memory_map) <- not enough room for new mm system hangs This patch allocates the e820 buffer before calling efi_exit_boot_services and fixes the regression. Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- arch/x86/boot/compressed/eboot.c | 65 ++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 8b4c5e001157..f7bad07bb251 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -1,3 +1,4 @@ + /* ----------------------------------------------------------------------- * * Copyright 2011 Intel Corporation; author Matt Fleming @@ -634,37 +635,54 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, return status; } +static efi_status_t allocate_e820(struct boot_params *params, + struct setup_data **e820ext, + u32 *e820ext_size) +{ + unsigned long map_size, desc_size, buff_size; + struct efi_boot_memmap boot_map; + efi_memory_desc_t *map; + efi_status_t status; + __u32 nr_desc; + + boot_map.map = ↦ + boot_map.map_size = &map_size; + boot_map.desc_size = &desc_size; + boot_map.desc_ver = NULL; + boot_map.key_ptr = NULL; + boot_map.buff_size = &buff_size; + + status = efi_get_memory_map(sys_table, &boot_map); + if (status != EFI_SUCCESS) + return status; + + nr_desc = buff_size / desc_size; + + if (nr_desc > ARRAY_SIZE(params->e820_table)) { + u32 nr_e820ext = nr_desc - ARRAY_SIZE(params->e820_table); + + status = alloc_e820ext(nr_e820ext, e820ext, e820ext_size); + if (status != EFI_SUCCESS) + return status; + } + + return EFI_SUCCESS; +} + struct exit_boot_struct { struct boot_params *boot_params; struct efi_info *efi; - struct setup_data *e820ext; - __u32 e820ext_size; }; static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg, struct efi_boot_memmap *map, void *priv) { - static bool first = true; const char *signature; __u32 nr_desc; efi_status_t status; struct exit_boot_struct *p = priv; - if (first) { - nr_desc = *map->buff_size / *map->desc_size; - if (nr_desc > ARRAY_SIZE(p->boot_params->e820_table)) { - u32 nr_e820ext = nr_desc - - ARRAY_SIZE(p->boot_params->e820_table); - - status = alloc_e820ext(nr_e820ext, &p->e820ext, - &p->e820ext_size); - if (status != EFI_SUCCESS) - return status; - } - first = false; - } - signature = efi_is_64bit() ? EFI64_LOADER_SIGNATURE : EFI32_LOADER_SIGNATURE; memcpy(&p->efi->efi_loader_signature, signature, sizeof(__u32)); @@ -687,8 +705,8 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) { unsigned long map_sz, key, desc_size, buff_size; efi_memory_desc_t *mem_map; - struct setup_data *e820ext; - __u32 e820ext_size; + struct setup_data *e820ext = NULL; + __u32 e820ext_size = 0; efi_status_t status; __u32 desc_version; struct efi_boot_memmap map; @@ -702,8 +720,10 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) map.buff_size = &buff_size; priv.boot_params = boot_params; priv.efi = &boot_params->efi_info; - priv.e820ext = NULL; - priv.e820ext_size = 0; + + status = allocate_e820(boot_params, &e820ext, &e820ext_size); + if (status != EFI_SUCCESS) + return status; /* Might as well exit boot services now */ status = efi_exit_boot_services(sys_table, handle, &map, &priv, @@ -711,9 +731,6 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) if (status != EFI_SUCCESS) return status; - e820ext = priv.e820ext; - e820ext_size = priv.e820ext_size; - /* Historic? */ boot_params->alt_mem_k = 32 * 1024; -- 2.19.1
next prev parent reply index Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-11-29 17:12 [GIT PULL 00/11] EFI updates Ard Biesheuvel 2018-11-29 17:12 ` Ard Biesheuvel [this message] 2018-11-30 7:29 ` [PATCH 01/11] x86/efi: Allocate e820 buffer before calling efi_exit_boot_service Ingo Molnar 2018-11-30 8:26 ` Ard Biesheuvel 2018-11-30 8:36 ` Ingo Molnar 2018-11-29 17:12 ` [PATCH 02/11] efi/fdt: Indentation fix Ard Biesheuvel 2018-11-30 7:56 ` [PATCH] efi/fdt: More cleanups Ingo Molnar 2018-11-30 8:31 ` Ard Biesheuvel 2018-11-30 9:48 ` Ingo Molnar 2018-11-29 17:12 ` [PATCH 03/11] efi/fdt: Simplify get_fdt flow Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 04/11] x86/mm/pageattr: Introduce helper function to unmap EFI boot services Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 05/11] x86/efi: Unmap EFI boot services code/data regions from efi_pgd Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 06/11] x86/efi: Move efi_<reserve/free>_boot_services() to arch/x86 Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 07/11] efi/libstub: Disable some warnings for x86{,_64} Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 08/11] firmware: efi: add NULL pointer checks in efivars api functions Ard Biesheuvel 2018-11-30 8:11 ` Ingo Molnar 2018-11-30 8:37 ` Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 09/11] efi: permit multiple entries in persistent memreserve data structure Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 10/11] efi: reduce the amount of memblock reservations for persistent allocations Ard Biesheuvel 2018-11-30 8:38 ` Ingo Molnar 2018-11-30 8:39 ` Ard Biesheuvel 2018-11-29 17:12 ` [PATCH 11/11] efi/x86: earlyprintk - Fix infinite loop on some screen widths Ard Biesheuvel 2018-11-30 8:05 ` Ingo Molnar 2018-11-30 8:32 ` Ard Biesheuvel 2018-11-29 18:27 ` [GIT PULL 00/11] EFI updates Prakhya, Sai Praneeth 2018-11-30 12:01 ` Ard Biesheuvel 2018-11-30 18:01 ` Prakhya, Sai Praneeth
Reply instructions: You may reply publically to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20181129171230.18699-2-ard.biesheuvel@linaro.org \ --to=ard.biesheuvel@linaro.org \ --cc=arend.vanspriel@broadcom.com \ --cc=bhsharma@redhat.com \ --cc=bp@alien8.de \ --cc=dave.hansen@intel.com \ --cc=eric.snowberg@oracle.com \ --cc=hdegoede@redhat.com \ --cc=joe@perches.com \ --cc=jonathanh@nvidia.com \ --cc=julien.thierry@arm.com \ --cc=linux-efi@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=luto@kernel.org \ --cc=marc.zyngier@arm.com \ --cc=mingo@kernel.org \ --cc=natechancellor@gmail.com \ --cc=peterz@infradead.org \ --cc=sai.praneeth.prakhya@intel.com \ --cc=sedat.dilek@gmail.com \ --cc=tglx@linutronix.de \ --cc=zhuyifei1999@gmail.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Linux-EFI Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-efi/0 linux-efi/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-efi linux-efi/ https://lore.kernel.org/linux-efi \ linux-efi@vger.kernel.org public-inbox-index linux-efi Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-efi AGPL code for this site: git clone https://public-inbox.org/public-inbox.git