From patchwork Tue Jan 2 17:21:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 123184 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp9206140qgn; Tue, 2 Jan 2018 09:21:26 -0800 (PST) X-Google-Smtp-Source: ACJfBotx6/b1rsBh+pPxffoLbmbtioGrzEvge2eL1XllR1U2fMdodurqpTZnOAFntUUyDlqzp2JX X-Received: by 10.98.46.7 with SMTP id u7mr46130871pfu.37.1514913686195; Tue, 02 Jan 2018 09:21:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1514913686; cv=none; d=google.com; s=arc-20160816; b=vcJ5nFmPkDAjHKmqJvreMeu1E9DkR/L96tfTNh574pzt/gfZ4DKV9HSSPsYGoWsGZF l0w5syX+/tCCd060+e+NLtF2ySNB6TD7Kw9JKTzf9TcSXTt6WdvJs0QJSzpDQGVuRyFG lm3nX6SZfWxnVa+Uhx/r2VrEK2qKx7lr7ekzABkM/+GkP7Hwzz5naRxE+BFLYZxuRMFg 3hqgd4goSdwRaxsf82VU4pc5190tejJEt4cmp89SOx4lSTkeZUx3SIoW80YEKxoC2oqb 2hB/+EpO8c3hYFXGxOoW0u4sOxpxdSyrCQzoroOVrHt953t9jekcoH5KJbGFA79sOK5f bWMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=FCyO40DKrucujFfu2+JC0FcC/6gxnbkSxPBAKsofSAg=; b=OXEqs46L48yaPXApxz4FznHMex0wVvDT05vWVp20vbMD9Rtm0qI8REdS6ryFUt0lsQ f2l+bAED5pGcmNi5TT71XfdND1MbVbLdJx+Hs6vD0xpkQOP5rDwZ5WZl89LgKx7iXxbi SkDUFuW8v10QhnJN8ttHTTc8aN4nmQneXEy7+kJWJ4uXA7iuS6CNbUJpZls4kdiUIdU/ 4blgYKRPmI1FEUD7pQZlP5tZ4yZKgDxuDUriAcir/xkIRoXRvGWHVyfHoSdDSpDLKb8m Ghn+zNORd7k6VS4v8BoAgZ28bBwu3fcAvBDWFbjJ0l5Tl1lPXKHK3CyD0ve2rXz1WeHl L2ig== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=YzS6a1HZ; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (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 v2si30860548pgf.457.2018.01.02.09.21.25; Tue, 02 Jan 2018 09:21:26 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=YzS6a1HZ; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751311AbeABRVY (ORCPT + 2 others); Tue, 2 Jan 2018 12:21:24 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:44264 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751299AbeABRVW (ORCPT ); Tue, 2 Jan 2018 12:21:22 -0500 Received: by mail-wm0-f65.google.com with SMTP id t8so62234628wmc.3 for ; Tue, 02 Jan 2018 09:21:21 -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; bh=IHch68vFMdIAcbibYL30NiwOmIwdzSx2+2M3u08xi7c=; b=YzS6a1HZiBaQj+7R6Tz8vXadsDdY3CE6mG78x4RfJSP/yr1UwTi3qBFOUPSZ8Q4c1W /5HFyfH0UEIb/WOgh4ICL+Cj8El1TFU2im1o+mDnmMvq6QElVFsLWWuuvMROLCbNCT1B U0SYYvo0BZE/kBv92FIrHMpOPoxWMnjnzyXas= 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; bh=IHch68vFMdIAcbibYL30NiwOmIwdzSx2+2M3u08xi7c=; b=nont1mNUrJXNMHGLeAPItfdUSaSAI+JhNgX+eqfVladaCeZLLyFsCZHm5I6JHGGJfa h3h9wqIqu1pAYbGPEefbhCRNHO2QCqTwzSBKy9Rfrzme0NrzS0WLmzfh4EkZjdAp5PGb OhqX5lO0vHyNlODyO6gtJPdXHQuxabK2Mf2nSsf6l7Obr7NWzDgPnGmwii9DG8PUoh2v kBfHFk3+NGT5cDruDvWZlYmQE/5WaAs5tIF6Hof+h9CXYv/28SGEZbORhFF4OETcbowy JE4f7bUxL7W6HKup4kHdH78NWntKIQ2hxca3NvuI6gvvlGBZacsbzcNTa/hACmKF55wB KIKQ== X-Gm-Message-State: AKGB3mLN6Z4BF+/2Ex8IbuDQ26FX9ZYqXfoR8CxnCLixjhoe4AI3+aMR sIzrRpeYCPDaX/oS8b2PQcO6xm54A+s= X-Received: by 10.28.62.5 with SMTP id l5mr37461292wma.47.1514913680834; Tue, 02 Jan 2018 09:21:20 -0800 (PST) Received: from localhost.localdomain ([160.89.138.198]) by smtp.gmail.com with ESMTPSA id p15sm8692446wre.64.2018.01.02.09.21.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Jan 2018 09:21:20 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, Bryan O'Donoghue , Dave Young , Ge Song , Matt Fleming Subject: [PATCH 1/2] x86/efi: Fix kernel param add_efi_memmap regression Date: Tue, 2 Jan 2018 17:21:09 +0000 Message-Id: <20180102172110.17018-2-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180102172110.17018-1-ard.biesheuvel@linaro.org> References: <20180102172110.17018-1-ard.biesheuvel@linaro.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Dave Young 'add_efi_memmap' is an early param, but do_add_efi_memmap() has no chance to run because the code path is before parse_early_param(). I believe it worked when the param was introduced but probably later some other changes caused the wrong order and nobody noticed it. Move efi_memblock_x86_reserve_range() after parse_early_param() to fix it. Signed-off-by: Dave Young Cc: Ingo Molnar Signed-off-by: Matt Fleming Signed-off-by: Ard Biesheuvel --- arch/x86/kernel/setup.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 8af2e8d0c0a1..145810b0edf6 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -906,9 +906,6 @@ void __init setup_arch(char **cmdline_p) set_bit(EFI_BOOT, &efi.flags); set_bit(EFI_64BIT, &efi.flags); } - - if (efi_enabled(EFI_BOOT)) - efi_memblock_x86_reserve_range(); #endif x86_init.oem.arch_setup(); @@ -962,6 +959,8 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); + if (efi_enabled(EFI_BOOT)) + efi_memblock_x86_reserve_range(); #ifdef CONFIG_MEMORY_HOTPLUG /* * Memory used by the kernel cannot be hot-removed because Linux From patchwork Tue Jan 2 17:21:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 123185 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp9206233qgn; Tue, 2 Jan 2018 09:21:31 -0800 (PST) X-Google-Smtp-Source: ACJfBos5AIMS/IEHdYcEnlbphHqJetq8CT0idlYbGebCUJQAWVg+f4VFIOS7gAZTNWtXCzGVeFgu X-Received: by 10.98.79.74 with SMTP id d71mr45264589pfb.238.1514913691085; Tue, 02 Jan 2018 09:21:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1514913691; cv=none; d=google.com; s=arc-20160816; b=qnV9DvM9jKl1CH4le3l+G72XUleJ48EAWHYlMm3yztMTyA0LP5Qbgzef31UKH7r4ai Ny58eaZAr8negJhZ525S5LeABH9wqpIJWKItJIB4xHw3N4zSBDE2IaMfd9vf1djSni4F bbJ8NI1uL4Q8ZP9r9J/+uLo3lhPRAIhnAP6iySwqo0CQopIhUCa530OXNOfbfl3TN65k ZZrjuhRPVBF1fk77at4fqtuBnC5TaiMSLwDUQOkCwMI5I3OnJ+fkfkrSQ18OPhbk14qz cpp9CS2gR2p3fX0wC+WHXd7dn9Qt9gmfJ1Y9DnZaqjF0dCktcXD9NayW8u1eXkdsftdz zOJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=QkCU7Z3PCe4jxnkijwF21yX1SMk7925KRDsvA9yl1TY=; b=dUf3khYmf7EmZrMOeB2j8moz3vdQ0wCSw7NaouUK75//iVTeIToOd4S0j7GpC8DXV1 BsPHsax7LA4JRoBMsOXeJyI7DM8QlPnWFd4PWLIUXCn2q50T/JO6WXya4djonoSdDPeL fXfJUWvXxl4YguIk2rSVKnt5FN/BSwHS7VIXi/A83S5gVX5CdvBWNwzDB/gNPLBSl7Gc xW++zUXp33ctZXmzmdMGyeXkG/kJu/cmeRz3FM8+XsLrVcwH+YoI6gc0JJ51aaojaHXK jFX8SvIWrErMfe/vwl6r1IUstuO4kZJdnqt2Jf3/+5fLh8AAJkyRzFyIUbd2Of23AJSj LTCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=LM/o36fj; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (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 x186si24204550pgb.437.2018.01.02.09.21.30; Tue, 02 Jan 2018 09:21:31 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=LM/o36fj; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751354AbeABRVa (ORCPT + 2 others); Tue, 2 Jan 2018 12:21:30 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:44271 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751305AbeABRVZ (ORCPT ); Tue, 2 Jan 2018 12:21:25 -0500 Received: by mail-wm0-f65.google.com with SMTP id t8so62234855wmc.3 for ; Tue, 02 Jan 2018 09:21:24 -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; bh=eBuw37Ey28ZF/DpUlxLC+bz+JGhlrKy0TJLRnI2xGSA=; b=LM/o36fjwEa/elxQ6fg++FFraFoBAg930mTo7g3ow9O25mldu2chc6yw5aS1yMuTt2 9M56h9/fX8DAKnGK+w/5hgxZBvHaUGAyVyAOFTGaSCukpWdsiHUuM51yv3AMfVbjMQj+ tZOeuhJ7FkNE7VWghVWRWofh2SeL2YO8Xn7pI= 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; bh=eBuw37Ey28ZF/DpUlxLC+bz+JGhlrKy0TJLRnI2xGSA=; b=np0blpHpZhQC7zxIiPUAWTEv+YQif5owZ7cQnD+R6WlMcOtL7vXVyIU/WBIWaq60pW uyrSY0oN9XlYYcmCIErdD75/hBesTXRKaylr2GAou70Ev+FTReHg3jdmYTUGJ3n4i1Ow acwRwUn2TiorNcVgnpl0sh9VY5ProS0nwQueHSAnNM3HdZ3Xr3a3ue3W3y2wADJV5IDL PQ9AI/+msW3ogalJ5ttYCAIoMjAE0/S8ctGBVY7YlZHuqN1AnQ7VuwxG81vb82/BKbJp NGVK6STXMM8l1efBuKkT59oSycOiwhxwnol1ADStRqyDw4UtUmj0iaNnAjAn4Li7fP5q cAOw== X-Gm-Message-State: AKGB3mI3vKsNK/QwqDYFNElUzgBRC2u6Vhe7Hsr06WLVOguSxCmLer5t NpLwpPkFMe1nODxvsFltFZrEk355buA= X-Received: by 10.28.59.133 with SMTP id i127mr34572722wma.30.1514913683330; Tue, 02 Jan 2018 09:21:23 -0800 (PST) Received: from localhost.localdomain ([160.89.138.198]) by smtp.gmail.com with ESMTPSA id p15sm8692446wre.64.2018.01.02.09.21.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Jan 2018 09:21:22 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, Bryan O'Donoghue , Dave Young , Ge Song , Matt Fleming Subject: [PATCH 2/2] efi: capsule-loader: reinstate virtual capsule mapping Date: Tue, 2 Jan 2018 17:21:10 +0000 Message-Id: <20180102172110.17018-3-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180102172110.17018-1-ard.biesheuvel@linaro.org> References: <20180102172110.17018-1-ard.biesheuvel@linaro.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Commit 82c3768b8d68 ("efi/capsule-loader: Use a cached copy of the capsule header") refactored the capsule loading code that maps the capsule header, to avoid having to map it several times. However, as it turns out, the vmap() call we ended up removing did not just map the header, but the entire capsule image, and dropping this virtual mapping breaks capsules that are processed by the firmware immediately (i.e., without a reboot). Unfortunately, that change was part of a larger refactor that allowed a quirk to be implemented for Quark, which has a non-standard memory layout for capsules, and we have slightly painted ourselves into a corner by allowing quirk code to mangle the capsule header and memory layout. So we need to fix this without breaking Quark. Fortunately, Quark does not appear to care about the virtual mapping, and so we can simply do a partial revert of commit 2a457fb31df6 ("efi/capsule-loader: Use page addresses rather than struct page pointers"), and create a vmap() mapping of the entire capsule (including header) based on the reinstated struct page array, unless running on Quark, in which case we pass the capsule header copy as before. Reported-by: Ge Song Tested-by: Bryan O'Donoghue Tested-by: Ge Song Cc: Matt Fleming Cc: Fixes: 82c3768b8d68 ("efi/capsule-loader: Use a cached copy of the capsule header") Signed-off-by: Ard Biesheuvel --- arch/x86/platform/efi/quirks.c | 13 +++++++++- drivers/firmware/efi/capsule-loader.c | 45 ++++++++++++++++++++++++++++------- include/linux/efi.h | 4 +++- 3 files changed, 52 insertions(+), 10 deletions(-) -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 8a99a2e96537..5b513ccffde4 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -592,7 +592,18 @@ static int qrk_capsule_setup_info(struct capsule_info *cap_info, void **pkbuff, /* * Update the first page pointer to skip over the CSH header. */ - cap_info->pages[0] += csh->headersize; + cap_info->phys[0] += csh->headersize; + + /* + * cap_info->capsule should point at a virtual mapping of the entire + * capsule, starting at the capsule header. Our image has the Quark + * security header prepended, so we cannot rely on the default vmap() + * mapping created by the generic capsule code. + * Given that the Quark firmware does not appear to care about the + * virtual mapping, let's just point cap_info->capsule at our copy + * of the capsule header. + */ + cap_info->capsule = &cap_info->header; return 1; } diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index ec8ac5c4dd84..055e2e8f985a 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -20,10 +20,6 @@ #define NO_FURTHER_WRITE_ACTION -1 -#ifndef phys_to_page -#define phys_to_page(x) pfn_to_page((x) >> PAGE_SHIFT) -#endif - /** * efi_free_all_buff_pages - free all previous allocated buffer pages * @cap_info: pointer to current instance of capsule_info structure @@ -35,7 +31,7 @@ static void efi_free_all_buff_pages(struct capsule_info *cap_info) { while (cap_info->index > 0) - __free_page(phys_to_page(cap_info->pages[--cap_info->index])); + __free_page(cap_info->pages[--cap_info->index]); cap_info->index = NO_FURTHER_WRITE_ACTION; } @@ -71,6 +67,14 @@ int __efi_capsule_setup_info(struct capsule_info *cap_info) cap_info->pages = temp_page; + temp_page = krealloc(cap_info->phys, + pages_needed * sizeof(phys_addr_t *), + GFP_KERNEL | __GFP_ZERO); + if (!temp_page) + return -ENOMEM; + + cap_info->phys = temp_page; + return 0; } @@ -105,9 +109,24 @@ int __weak efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, **/ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info) { + bool do_vunmap = false; int ret; - ret = efi_capsule_update(&cap_info->header, cap_info->pages); + /* + * cap_info->capsule may have been assigned already by a quirk + * handler, so only overwrite it if it is NULL + */ + if (!cap_info->capsule) { + cap_info->capsule = vmap(cap_info->pages, cap_info->index, + VM_MAP, PAGE_KERNEL); + if (!cap_info->capsule) + return -ENOMEM; + do_vunmap = true; + } + + ret = efi_capsule_update(cap_info->capsule, cap_info->phys); + if (do_vunmap) + vunmap(cap_info->capsule); if (ret) { pr_err("capsule update failed\n"); return ret; @@ -165,10 +184,12 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, goto failed; } - cap_info->pages[cap_info->index++] = page_to_phys(page); + cap_info->pages[cap_info->index] = page; + cap_info->phys[cap_info->index] = page_to_phys(page); cap_info->page_bytes_remain = PAGE_SIZE; + cap_info->index++; } else { - page = phys_to_page(cap_info->pages[cap_info->index - 1]); + page = cap_info->pages[cap_info->index - 1]; } kbuff = kmap(page); @@ -252,6 +273,7 @@ static int efi_capsule_release(struct inode *inode, struct file *file) struct capsule_info *cap_info = file->private_data; kfree(cap_info->pages); + kfree(cap_info->phys); kfree(file->private_data); file->private_data = NULL; return 0; @@ -281,6 +303,13 @@ static int efi_capsule_open(struct inode *inode, struct file *file) return -ENOMEM; } + cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL); + if (!cap_info->phys) { + kfree(cap_info->pages); + kfree(cap_info); + return -ENOMEM; + } + file->private_data = cap_info; return 0; diff --git a/include/linux/efi.h b/include/linux/efi.h index d813f7b04da7..29fdf8029cf6 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -140,11 +140,13 @@ struct efi_boot_memmap { struct capsule_info { efi_capsule_header_t header; + efi_capsule_header_t *capsule; int reset_type; long index; size_t count; size_t total_size; - phys_addr_t *pages; + struct page **pages; + phys_addr_t *phys; size_t page_bytes_remain; };