From patchwork Thu Nov 29 17:12:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 152413 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp2633969ljp; Thu, 29 Nov 2018 09:12:53 -0800 (PST) X-Google-Smtp-Source: AFSGD/WAzUV1rZp6Gv9mJ22/9JZoQew+LIOJCKD1Ki7r8zZA2jlWOEfhUIXqqCCC35QVmVSAlxuG X-Received: by 2002:a17:902:8e8a:: with SMTP id bg10mr2293242plb.192.1543511573581; Thu, 29 Nov 2018 09:12:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543511573; cv=none; d=google.com; s=arc-20160816; b=LV5JuHnKGA6rmb2WPvciVBsCJ51ivdlkaGfza9mF/2WcsbV2wLV1jW6gHAPEaK09te eIKkWIIQ0pJv3dw3zghQixcmMy42aTX94FNbuyCPW8MDpcWcFzvnbpQWSpdzi9VhULE/ Y98ywZEGX1a5rS/M6aUCTalFmrF3RPr3QccaKvHkZDfy0b76EfKAlqLTT6giRJqVP0cZ 2c1Pc57vBa0louih+X/d4Oc5pfJ3AlawNctGdnsNjSYOcoK3UOTddiHRFl8y7LfYRdtP +Ek36eocufmZH5EfPTidFAZrFk8vu8EkzBiVH1KH/52Q3mCu9xCV3lJYrIAU22AzBDFc goNA== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=XsSaaAOivGZ+SMEV1HNl9ikqQLGcv3idzYmN9Jqzt5c=; b=lQQCHXoyO4kexY7MKBfS9Gx9UsOeVMOW0oY15dA4KiU6noFcm0ydOIqIUBqmY3XCwO 4JHQhD44GEAopb2pDilxK1jqs05/8yuWvPN2ftuQNDMfnfNzT4E4A97H1GTPVls8yIH/ ogt/W8w7fo3/yO1RG07nC4ZXVL6DPD38BEw7tn+A+dvVYO3fzvCzi98f+7IDxIH9l4C6 XjhJ0CELN6Dxilh8/z0wlCf+iKRcft8tVRagnXegQT0YJFpO9Dop3kUhntqV+ZsXYY+K vV1QsLsx8fF02MAU83DZW6djo1DAuhGd/03s51frR1eqSSUUTdRnpijKePGXomgTthro VR/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dcC5p86o; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l124si2518448pfl.284.2018.11.29.09.12.52; Thu, 29 Nov 2018 09:12:53 -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=@linaro.org header.s=google header.b=dcC5p86o; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730474AbeK3ES4 (ORCPT + 32 others); Thu, 29 Nov 2018 23:18:56 -0500 Received: from mail-wr1-f66.google.com ([209.85.221.66]:34606 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728157AbeK3ESz (ORCPT ); Thu, 29 Nov 2018 23:18:55 -0500 Received: by mail-wr1-f66.google.com with SMTP id j2so2695273wrw.1 for ; Thu, 29 Nov 2018 09:12:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XsSaaAOivGZ+SMEV1HNl9ikqQLGcv3idzYmN9Jqzt5c=; b=dcC5p86oeYdf0PuJPXvTl+IxGk6KAwIaDC40VblPUnrv10ctKWv/QPjA56MPMCwhOv hU199FHB3jis9/WVya/WmQqBCO4nYRQ0d2+pgQaDLnMuyyFK65YmLI6S88u29mjMQv0v U/k1IirkxTFV43Pui5b9993IyZqHYQTQnwNGo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XsSaaAOivGZ+SMEV1HNl9ikqQLGcv3idzYmN9Jqzt5c=; b=pfEsFMj8AOPug4reYWcDmezZSJQz1leSA7xgFe/g/DAEj1QBfTmEgQ2jYE6MBixP4o bg5fZPOhqC6rZi9vfij49ow7Zrsi2qt9oERPlunWI9DXdB3dIQGD2/5EXw2q+7zqJZLa fjLejl4cEYYNMLD33FDy+whKNhXEzUJBH9+RbjSUvnic56Ms8E5gfjEsTzA3bc0xECvM V6qb/4keZXAe4KJsmNhyE6CYEgQOhO6Ws/soq/FYLtlr28DErfT8OCI7HCOjuWJpts/x sTF7073zIo9xrf7LfRoEF6oDai1+aNTjcQepPtubKr2chw/VwJVtboaxvKMCSp2QryxE Ev5w== X-Gm-Message-State: AA+aEWZY0KUhrIAGNovzSZaNv8PnI2xFpC6XUI4VbEu8UOgwkQult45q EGi43M5wX7jswav9ngierv1cAA== X-Received: by 2002:adf:d0c9:: with SMTP id z9mr2063343wrh.317.1543511568971; Thu, 29 Nov 2018 09:12:48 -0800 (PST) Received: from harold.home ([2a01:cb1d:112:6f00:f070:d240:312e:9f99]) by smtp.gmail.com with ESMTPSA id y185sm1593882wmg.34.2018.11.29.09.12.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 29 Nov 2018 09:12:48 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, Andy Lutomirski , Arend van Spriel , Bhupesh Sharma , Borislav Petkov , Dave Hansen , Eric Snowberg , Hans de Goede , Joe Perches , Jon Hunter , Julien Thierry , Marc Zyngier , Nathan Chancellor , Peter Zijlstra , Sai Praneeth Prakhya , Sedat Dilek , YiFei Zhu 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> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181129171230.18699-1-ard.biesheuvel@linaro.org> References: <20181129171230.18699-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Snowberg 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 Signed-off-by: Ard Biesheuvel --- arch/x86/boot/compressed/eboot.c | 65 ++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 24 deletions(-) -- 2.19.1 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;