Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp813293imu; Tue, 11 Dec 2018 08:00:10 -0800 (PST) X-Google-Smtp-Source: AFSGD/WV7Cz4BoMwNQeILnhdl1yP5gPvXXfiyb44v+wz4ftLbAgPRS9V3zTmfKYqezmFAdOnBY0e X-Received: by 2002:a17:902:9006:: with SMTP id a6mr16309941plp.334.1544544009951; Tue, 11 Dec 2018 08:00:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544544009; cv=none; d=google.com; s=arc-20160816; b=UOEKEciSc4cVIntsA/vmjLlkPNWOnS8MTe1iDJ57MIaSZqRBG6VxGxgCDsGLnv+aWd lSDHYMwlOCBgkD6znEsA63eD/lb5dML5SpSzvitC18+BDnDVBdFFlXuRxJuaf2QJ0DPG /sEsryS8CjBqsvlOXHp4iy4/isBnucQoPteOgBL5mrU+bX4aPP/DAaVYOOvP+XdehtlH /rsTJk1YU1GHB4+nDIeFRvKmgUwweX1iAnkubqupnW933WO0RdPI9m7aeCrKSIOm6Il2 xqFLkGpFtV0ufRWFS0hAopzKYJC/k3NkoZVYZFBJgDsDAdsGwksBPZrImw/nA7PJn/LS 6cpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=XIuGieaHrJEXp+hM6fxDhDYIpxczj+g1ln2YSndfYmE=; b=p+w/DnPzzHHMNBeQlgPCvYZAxmdYxh850Pb+CXEZibRq0Ol38vz2t/eKsHlybgWtmg EleYEmptoeH7MAfSVUMRQPK4kaavu/DmVrSRI7rBJ11cgTOKMTUgJOppqg79YGiKRVXP mkXgz4sYpH+GsdX6EDubx08HlVELpt6Ge/o9bDqOmf73XKEBWyJSJSvo/2ypli1zrbju aa+CEt/ZHKWmYt32ikqxLhOT3o4aAsAp6jNs6by9dQCvHKe+KJi8UIgNS9b7Il+JopDN WecNxYbrF/SoSAjqRoSPRxnb/GlT0I/0LlLzaohAapmvND7wh26U6cdPX2JxHF3UAfc7 lnFA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=NHbMYihm; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d92si13308947pld.45.2018.12.11.07.59.54; Tue, 11 Dec 2018 08:00:09 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=NHbMYihm; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730990AbeLKP6S (ORCPT + 99 others); Tue, 11 Dec 2018 10:58:18 -0500 Received: from mail.kernel.org ([198.145.29.99]:47518 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730986AbeLKP6P (ORCPT ); Tue, 11 Dec 2018 10:58:15 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 21EF220855; Tue, 11 Dec 2018 15:58:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1544543894; bh=Z4dEKU5XyzUe5XhxqjuWXU2SvcsVn6Ng+Qqi2xedwIo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NHbMYihmfgeoKPLDNUcbEK/WUr4M/1YvqeqKGZs9qVb2+RQT73ZZm2SkBwUGStq1o D3Z+W6JJ+6lzvzmZRFz02jhjqcK7ZGp6vOc0g6wpUXasJVWtP9s/N/O0kglbd/upsD olBqgEDmJtAqEJtdioV1YYt724H/E55KAuxXET/I= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Snowberg , Ard Biesheuvel , Andy Lutomirski , Arend van Spriel , Bhupesh Sharma , Borislav Petkov , Dave Hansen , Hans de Goede , Joe Perches , Jon Hunter , Julien Thierry , Linus Torvalds , Marc Zyngier , Matt Fleming , Nathan Chancellor , Peter Zijlstra , Sai Praneeth Prakhya , Sedat Dilek , Thomas Gleixner , YiFei Zhu , linux-efi@vger.kernel.org, Ingo Molnar Subject: [PATCH 4.19 104/118] x86/efi: Allocate e820 buffer before calling efi_exit_boot_service Date: Tue, 11 Dec 2018 16:42:03 +0100 Message-Id: <20181211151648.466213185@linuxfoundation.org> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181211151644.216668863@linuxfoundation.org> References: <20181211151644.216668863@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Eric Snowberg commit b84a64fad40637b1c9fa4f4dbf847a23e29e672b upstream. The following 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() ensured 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. [ mingo: minor cleanliness edits. ] Signed-off-by: Eric Snowberg Signed-off-by: Ard Biesheuvel Cc: Cc: Andy Lutomirski Cc: Arend van Spriel Cc: Bhupesh Sharma Cc: Borislav Petkov Cc: Dave Hansen Cc: Hans de Goede Cc: Joe Perches Cc: Jon Hunter Cc: Julien Thierry Cc: Linus Torvalds Cc: Marc Zyngier Cc: Matt Fleming Cc: Nathan Chancellor Cc: Peter Zijlstra Cc: Sai Praneeth Prakhya Cc: Sedat Dilek Cc: Thomas Gleixner Cc: YiFei Zhu Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20181129171230.18699-2-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/boot/compressed/eboot.c | 65 ++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 24 deletions(-) --- 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 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 boo { 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 boo 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 boo if (status != EFI_SUCCESS) return status; - e820ext = priv.e820ext; - e820ext_size = priv.e820ext_size; - /* Historic? */ boot_params->alt_mem_k = 32 * 1024;