Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3541574imu; Fri, 30 Nov 2018 01:58:46 -0800 (PST) X-Google-Smtp-Source: AFSGD/UyiaQaF+qjJIoIvaRceOGnjPpR9Z1bIza56MEjOIsOfkWptBmFu2ZDFrh5b/wYMWR0kaem X-Received: by 2002:a17:902:1102:: with SMTP id d2mr813304pla.138.1543571926423; Fri, 30 Nov 2018 01:58:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543571926; cv=none; d=google.com; s=arc-20160816; b=r3Fc+dJSv/U92whB94mu/+NY2bPafnPzd4ehfxo6TrolC7sQPBrCe+L9669lEJKSZz gNpdPaI3XuPZHZXi4tf6RfBqhYurRdng47HtoqW7P6ebFpmmwdFXmS22pRHqWWKQkNG/ AWYOmhELKgxUZCMI4pTPP24PEGU7Ugu35zn4fACTt9eBeNeubFz+CQAVbgLhPo5mMIFq dci0aPcKxu2xt4mNNje8v59ETt9JtAhG7OHF8NXHyZND1ncpWKhLe44Pe6517xiGJdyY I+RQCo9Jb8a1GJkb5iOazwSLVRslJs+58W8JHlzGtXzYBt6nwuVLbgUDrUBGJPCv7r37 11qw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date; bh=9MUhw0RASv8CGts0ZPuqSb2914iKeZ7K3iJP7LUnk3k=; b=SRb6q7OgS71mhj9hbOxfWARl8GZzfbB+1twn1RcxRIZtmlQ9ViKnj9E1ZFkjeZpySb IIL87L0RZuFGlf/II/Asy6vN+nybv/0NAdcVKL1emY/LvAWO5IY1ppo0tVmqsg5zE1mR L/+lmal3W9ULeWAt9I2BoCY20Znx2q2ZDoj8VIw93Mk+Pnc5mzckF3M6W4LGGDL1FLF+ 0Tes01mfODWfa8D28VKQifMSsQiyEBqfz6jdYLvERMh+9AiA5sIURhURxHFlZM7dmEo0 nedZY1Tx5WZcu93vTNfpMxXa61HbT8/4SXxB7t2mH+DiqPh6vhc4x//Ck7NcOm0vArnc iO8g== ARC-Authentication-Results: i=1; mx.google.com; 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 w16-v6si5000453plk.317.2018.11.30.01.58.32; Fri, 30 Nov 2018 01:58:46 -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; 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 S1726883AbeK3VFD (ORCPT + 99 others); Fri, 30 Nov 2018 16:05:03 -0500 Received: from terminus.zytor.com ([198.137.202.136]:57093 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726597AbeK3VFD (ORCPT ); Fri, 30 Nov 2018 16:05:03 -0500 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id wAU9t3do3260871 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 30 Nov 2018 01:55:03 -0800 Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id wAU9t2093260858; Fri, 30 Nov 2018 01:55:02 -0800 Date: Fri, 30 Nov 2018 01:55:02 -0800 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Eric Snowberg Message-ID: Cc: natechancellor@gmail.com, linux-kernel@vger.kernel.org, torvalds@linux-foundation.org, julien.thierry@arm.com, tglx@linutronix.de, ard.biesheuvel@linaro.org, jonathanh@nvidia.com, arend.vanspriel@broadcom.com, dave.hansen@intel.com, sedat.dilek@gmail.com, hpa@zytor.com, mingo@kernel.org, peterz@infradead.org, zhuyifei1999@gmail.com, matt@codeblueprint.co.uk, eric.snowberg@oracle.com, sai.praneeth.prakhya@intel.com, luto@kernel.org, bhsharma@redhat.com, marc.zyngier@arm.com, hdegoede@redhat.com, joe@perches.com, bp@alien8.de, stable@vger.kernel.org Reply-To: sai.praneeth.prakhya@intel.com, luto@kernel.org, bhsharma@redhat.com, joe@perches.com, bp@alien8.de, hdegoede@redhat.com, marc.zyngier@arm.com, stable@vger.kernel.org, natechancellor@gmail.com, linux-kernel@vger.kernel.org, julien.thierry@arm.com, tglx@linutronix.de, torvalds@linux-foundation.org, ard.biesheuvel@linaro.org, jonathanh@nvidia.com, arend.vanspriel@broadcom.com, dave.hansen@intel.com, sedat.dilek@gmail.com, hpa@zytor.com, mingo@kernel.org, zhuyifei1999@gmail.com, peterz@infradead.org, matt@codeblueprint.co.uk, eric.snowberg@oracle.com In-Reply-To: <20181129171230.18699-2-ard.biesheuvel@linaro.org> References: <20181129171230.18699-2-ard.biesheuvel@linaro.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:efi/core] x86/efi: Allocate e820 buffer before calling efi_exit_boot_service Git-Commit-ID: b84a64fad40637b1c9fa4f4dbf847a23e29e672b X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=1.6 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_48_96,FREEMAIL_FORGED_REPLYTO, FREEMAIL_REPLYTO_END_DIGIT autolearn=no autolearn_force=no version=3.4.2 X-Spam-Level: * X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: b84a64fad40637b1c9fa4f4dbf847a23e29e672b Gitweb: https://git.kernel.org/tip/b84a64fad40637b1c9fa4f4dbf847a23e29e672b Author: Eric Snowberg AuthorDate: Thu, 29 Nov 2018 18:12:20 +0100 Committer: Ingo Molnar CommitDate: Fri, 30 Nov 2018 08:30:07 +0100 x86/efi: Allocate e820 buffer before calling efi_exit_boot_service 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 --- 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..544ac4fafd11 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;