From patchwork Sat Feb 2 09:41:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157329 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1509904jaa; Sat, 2 Feb 2019 01:41:41 -0800 (PST) X-Google-Smtp-Source: ALg8bN4Czam5U0Z30sZmeJmf73lM9yEehZlgS4z+Pp1OFoJ+Zmr/CPHStq4d9jHcyZVwznGbKoS2 X-Received: by 2002:a62:c505:: with SMTP id j5mr42912392pfg.149.1549100501620; Sat, 02 Feb 2019 01:41:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100501; cv=none; d=google.com; s=arc-20160816; b=QX/6eQlu9LuIxwljbzzQFMfqNPoriDzomOkkN6i2LOr+iILiQrOBDJguhhqlPyEP/A tfNlfiUFUzWDVyOeQBX+SUuw92QDbjnBwuEKRUsbIrdqtc+Uq10ocoKbw7oJ3NyK78dT N2fvOCDb25esZW4iZG2yhfOoOEp6Dfs+c7YcBS15RIsue3qL/altXJSJ6bOYewUatumE xcQwDgljIpg1SM0cMEhGnM07WZQIyLWwXPTGP7kPR8U6uczqyRq9+7bhms0/cYa2o8OS xtaTDhSwP7MrQcMVFaI7GDXjX6cXA75akMSCebZjOz9TJPfdKzsohShfyLUnlDvm0iDW 7CYg== 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; bh=VnHL/tmyQ/nmJdmXB8BwoJMtf/z3HpXcbnlekvTL8qE=; b=cKT/USdazHPSRxvXPWSrb8CWmknspJRXCbd/RmdzVihXzkx6z1nOMHTg1kG9Zz2Qa4 pU9Xcw2iILxDDcuJZDTFybYX6/vgYezC3/Ji90rojbx56ZDviQGgZIofSJlIXuvfmYJS zTPMKjULn5SDJi/a1tNrniIEM3M9qHNn9ZVLmaaPijaYdWtk6GPt3k9Z7+ind9nkzUjK mhoaxtxdtUZh3gL8ymbERj1qfk/eFdfjwjn9ztEXESdv1LsZKmA04S66i9tjSlhyPY3a BCoBp2aomZzTjxVY8+xi3L4+28P/DXnfCiCRsnJZSrRiXLKphBfFB0uNuEgN3mhI+Rlk 7H0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=V05dsxDK; 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 y10si8686394pgp.348.2019.02.02.01.41.41; Sat, 02 Feb 2019 01:41:41 -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=V05dsxDK; 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 S1727654AbfBBJlj (ORCPT + 31 others); Sat, 2 Feb 2019 04:41:39 -0500 Received: from mail-ed1-f67.google.com ([209.85.208.67]:41326 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727316AbfBBJld (ORCPT ); Sat, 2 Feb 2019 04:41:33 -0500 Received: by mail-ed1-f67.google.com with SMTP id a20so7454023edc.8 for ; Sat, 02 Feb 2019 01:41:31 -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=VnHL/tmyQ/nmJdmXB8BwoJMtf/z3HpXcbnlekvTL8qE=; b=V05dsxDKpEJx8VqkofrBqNtw0L9sGiPN/nfAWcCVkL8lv5z5E7e4MJ1g3i381ft3mF f13PIu4aRvvoneCN440k082S5FYCrwoPGgHKQRqOX3TGjyUXHqlosrxJSuZC5Qnm5AP6 glxgzKTwH4ZgjyGX/oqDoj3IH4yxKeunsukOM= 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=VnHL/tmyQ/nmJdmXB8BwoJMtf/z3HpXcbnlekvTL8qE=; b=kXZhSzyZZeYXovhw8o3ks9O2eRfI2Lzb/9D4WOkCvolBtGnjnBFNpR/M0XaO/VPckS 4d+TG/TI2YagZzMzwhGuO0Vkv4vIKHxfb/rPD4r89+5FDWiZd+p/aru3FOBlXGjq5zJT 7JKk6EfJO89y9jovR8t4DOpp7/ySaNWX4JX79qdwSUM/GKmqHSap5XF26oRonq6Y7dGn Yk1RDbeCgm+uBjrnbupGxRahKl3VfHLP+F01av7CGQOxm0KrSWRgGtJm0oxqQIlZDOWc e4a9J2+uZzLeqMboBgPVWjoa4kDzsLs0aWL6QgV+bt9aw5TZDWn9ZF0Aursnck5Fnu39 HqNQ== X-Gm-Message-State: AJcUukcgMjfl6PSIvsaVJiIeX2FefoJqDCt0VOsIx9gYEqfaKl5jK8GI mQFOrnsRwvUGOMN0ccKq9ihk/FPHcvyz1A== X-Received: by 2002:a50:c2d9:: with SMTP id u25mr42951775edf.280.1549100490160; Sat, 02 Feb 2019 01:41:30 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:28 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 02/10] x86/efi: Return error status if mapping EFI regions fail Date: Sat, 2 Feb 2019 10:41:11 +0100 Message-Id: <20190202094119.13230-3-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sai Praneeth Prakhya efi_map_region() creates VA mappings for an given EFI region using any one of the two helper functions (namely __map_region() and old_map_region()). These helper functions *could* fail while creating mappings and presently their return value is not checked. Not checking for the return value of these functions might create issues because after these functions return "md->virt_addr" is set to the requested virtual address (so it's assumed that these functions always succeed which is not quite true). This assumption leads to "md->virt_addr" having invalid mapping should any of __map_region() or old_map_region() fail. Hence, check for the return value of these functions and if indeed they fail, turn off EFI Runtime Services forever because kernel cannot prioritize among EFI regions. This also fixes the comment "FIXME: add error handling" in kexec_enter_virtual_mode(). Signed-off-by: Sai Praneeth Prakhya Cc: Borislav Petkov Cc: Ingo Molnar Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/efi.h | 6 +++--- arch/x86/platform/efi/efi.c | 21 +++++++++++++----- arch/x86/platform/efi/efi_32.c | 6 +++--- arch/x86/platform/efi/efi_64.c | 39 ++++++++++++++++++++++------------ 4 files changed, 48 insertions(+), 24 deletions(-) -- 2.17.1 diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 107283b1eb1e..a37378f986ec 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -125,12 +125,12 @@ extern pgd_t * __init efi_call_phys_prolog(void); extern void __init efi_call_phys_epilog(pgd_t *save_pgd); extern void __init efi_print_memmap(void); extern void __init efi_memory_uc(u64 addr, unsigned long size); -extern void __init efi_map_region(efi_memory_desc_t *md); -extern void __init efi_map_region_fixed(efi_memory_desc_t *md); +extern int __init efi_map_region(efi_memory_desc_t *md); +extern int __init efi_map_region_fixed(efi_memory_desc_t *md); extern void efi_sync_low_kernel_mappings(void); extern int __init efi_alloc_page_tables(void); extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); -extern void __init old_map_region(efi_memory_desc_t *md); +extern int __init old_map_region(efi_memory_desc_t *md); extern void __init runtime_code_page_mkexec(void); extern void __init efi_runtime_update_mappings(void); extern void __init efi_dump_pagetable(void); diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index e1cb01a22fa8..3d43ec58775b 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -581,7 +581,7 @@ void __init efi_memory_uc(u64 addr, unsigned long size) set_memory_uc(addr, npages); } -void __init old_map_region(efi_memory_desc_t *md) +int __init old_map_region(efi_memory_desc_t *md) { u64 start_pfn, end_pfn, end; unsigned long size; @@ -601,10 +601,14 @@ void __init old_map_region(efi_memory_desc_t *md) va = efi_ioremap(md->phys_addr, size, md->type, md->attribute); - md->virt_addr = (u64) (unsigned long) va; - if (!va) + if (!va) { pr_err("ioremap of 0x%llX failed!\n", (unsigned long long)md->phys_addr); + return -ENOMEM; + } + + md->virt_addr = (u64)(unsigned long)va; + return 0; } /* Merge contiguous regions of the same type and attribute */ @@ -797,7 +801,9 @@ static void * __init efi_map_regions(int *count, int *pg_shift) if (!should_map_region(md)) continue; - efi_map_region(md); + if (efi_map_region(md)) + return NULL; + get_systab_virt_addr(md); if (left < desc_size) { @@ -849,7 +855,12 @@ static void __init kexec_enter_virtual_mode(void) * fixed addr which was used in first kernel of a kexec boot. */ for_each_efi_memory_desc(md) { - efi_map_region_fixed(md); /* FIXME: add error handling */ + if (efi_map_region_fixed(md)) { + pr_err("Error mapping EFI regions, EFI runtime non-functional!\n"); + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + get_systab_virt_addr(md); } diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index 9959657127f4..4d369118391a 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -58,12 +58,12 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) return 0; } -void __init efi_map_region(efi_memory_desc_t *md) +int __init efi_map_region(efi_memory_desc_t *md) { - old_map_region(md); + return old_map_region(md); } -void __init efi_map_region_fixed(efi_memory_desc_t *md) {} +int __init efi_map_region_fixed(efi_memory_desc_t *md) { return 0; } void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} pgd_t * __init efi_call_phys_prolog(void) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index cf0347f61b21..ba83e2e2664b 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -408,7 +408,7 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) return 0; } -static void __init __map_region(efi_memory_desc_t *md, u64 va) +static int __init __map_region(efi_memory_desc_t *md, u64 va) { unsigned long flags = _PAGE_RW; unsigned long pfn; @@ -421,12 +421,16 @@ static void __init __map_region(efi_memory_desc_t *md, u64 va) flags |= _PAGE_ENC; pfn = md->phys_addr >> PAGE_SHIFT; - if (kernel_map_pages_in_pgd(pgd, pfn, va, md->num_pages, flags)) - pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n", - md->phys_addr, va); + if (kernel_map_pages_in_pgd(pgd, pfn, va, md->num_pages, flags)) { + pr_err("Error mapping PA 0x%llx -> VA 0x%llx!\n", + md->phys_addr, va); + return -ENOMEM; + } + + return 0; } -void __init efi_map_region(efi_memory_desc_t *md) +int __init efi_map_region(efi_memory_desc_t *md) { unsigned long size = md->num_pages << PAGE_SHIFT; u64 pa = md->phys_addr; @@ -439,7 +443,8 @@ void __init efi_map_region(efi_memory_desc_t *md) * firmware which doesn't update all internal pointers after switching * to virtual mode and would otherwise crap on us. */ - __map_region(md, md->phys_addr); + if (__map_region(md, md->phys_addr)) + return -ENOMEM; /* * Enforce the 1:1 mapping as the default virtual address when @@ -448,7 +453,7 @@ void __init efi_map_region(efi_memory_desc_t *md) */ if (!efi_is_native () && IS_ENABLED(CONFIG_EFI_MIXED)) { md->virt_addr = md->phys_addr; - return; + return 0; } efi_va -= size; @@ -468,13 +473,16 @@ void __init efi_map_region(efi_memory_desc_t *md) } if (efi_va < EFI_VA_END) { - pr_warn(FW_WARN "VA address range overflow!\n"); - return; + pr_err(FW_WARN "VA address range overflow!\n"); + return -ENOMEM; } /* Do the VA map */ - __map_region(md, efi_va); + if (__map_region(md, efi_va)) + return -ENOMEM; + md->virt_addr = efi_va; + return 0; } /* @@ -482,10 +490,15 @@ void __init efi_map_region(efi_memory_desc_t *md) * md->virt_addr is the original virtual address which had been mapped in kexec * 1st kernel. */ -void __init efi_map_region_fixed(efi_memory_desc_t *md) +int __init efi_map_region_fixed(efi_memory_desc_t *md) { - __map_region(md, md->phys_addr); - __map_region(md, md->virt_addr); + if (__map_region(md, md->phys_addr)) + return -ENOMEM; + + if (__map_region(md, md->virt_addr)) + return -ENOMEM; + + return 0; } void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, From patchwork Sat Feb 2 09:41:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157328 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1509829jaa; Sat, 2 Feb 2019 01:41:37 -0800 (PST) X-Google-Smtp-Source: ALg8bN71GluCc4tdes+5RboAmNPKF9iKoAvICp7fgOfbq5WNMLcWAcMnfuIWVyRg0lVkTNEfdg4u X-Received: by 2002:a17:902:f091:: with SMTP id go17mr44230664plb.235.1549100497001; Sat, 02 Feb 2019 01:41:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100496; cv=none; d=google.com; s=arc-20160816; b=j3sUZ6qcLwybmhb/GfnxKKMROfaoc4LnJL1tQBotY0lc6Uwr7LzhgUaSVro2mcVcbi COLR73ZC0xQDWJBK1Y0cu0pXJ6oUK7GrVOq9tniFqMUt7BgSnOMQ2D64bxkAA6jhAp6K TiYsFJkcmkewIkwv574YZiBZ2NsdwF6S7gj24qqIBj0J0ZZWy7K96cZQru/cjftSpDwP 0thv6V0NiBURS4x2wjVcTVlt/9NcjvXtuQQCAV3c8PvEG4gHgKxYORjZUV+1Ss/f6Ozm Sux3Fsz5aIZD00HQfYXnq7wl6I8naJ9JtEuuE+kn6owalREOty8Q86MWlovTKA/8Q82P T3Ug== 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; bh=bEfMhHDa9MBTeWUj0T9jDKJ2/Es/s2oL+argjHikJPY=; b=gwtX99UnnsIjwBQdZmpSMCzfu2ZkGg8YxJXXnxKNDXpTqJZiCoj5RIfOZMdiOnsyhR n8d9eZPVG/T5rqayVNwRDvl39cuqNSl3b1t5cZg7BZD2/9w3ci1eqpA1EkU6uWppZrvs JAPkRpPntVP8GGUkZMTMrXfp1+VGMNI+U73f8LZ32WZhawjxgqGuNnxePzTUBrvBpQpr 4vddWkLfeJYbm6qlLozH9c0heTLc7o/5m0dgQWDXUaFcJ3xVkoyH09ZICg9tpVPY6feb g6/LlMA04167mpI3v+u64zF15HEJBkMCZSJsSHNV6ozGDQxoZfruCU6ukSo0G/U5j8Iz Ry8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jv3prsbY; 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 d2si10149373plh.426.2019.02.02.01.41.36; Sat, 02 Feb 2019 01:41:36 -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=jv3prsbY; 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 S1727539AbfBBJlf (ORCPT + 31 others); Sat, 2 Feb 2019 04:41:35 -0500 Received: from mail-ed1-f66.google.com ([209.85.208.66]:42426 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727341AbfBBJld (ORCPT ); Sat, 2 Feb 2019 04:41:33 -0500 Received: by mail-ed1-f66.google.com with SMTP id y20so7435136edw.9 for ; Sat, 02 Feb 2019 01:41:32 -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=bEfMhHDa9MBTeWUj0T9jDKJ2/Es/s2oL+argjHikJPY=; b=jv3prsbYfPGToN9VYrtVBCDnGVwI8FCguEqVr+vLr2YpkkYZHDJMVCxtU+fiLdmTpN zmvoRLA4S3QqE5tsaD9iSZh5IiG8DQu+09Or4V6zx5yVIlyDo9qkJov7pM0wG/Yw4Rc2 NdocXwjOLMUrNN6GL6G3VW1GlFlkMkZUxgxaA= 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=bEfMhHDa9MBTeWUj0T9jDKJ2/Es/s2oL+argjHikJPY=; b=MguvFMtxzal2gH7q7avAy2PCWND/ytXmeueTZ4uR+8ye4k2qF/oRRSWhgdAA2Pd7Vc ibSBzywRS0LVdVwPd8bkLDGpuO82osvF6Bi5Yl2pbkx4vqG9HGac33TkoeVipka3IrA8 H3mpzXW/xkTL9hhfNfVGqEl0QoB2393cM9tzLS1Y6g2eSsve9Bzt2HXfLxtWNpLCk7+L RL5s14y8WJhsRxWlZsoiPROCOA7hGRSIr6JoFFvBHEgXuHggeuYdu4TSeXyNgQgTQfjO baWaVJwicSwF/7U7ywsmCpJ6qCsBtllPrt62QTeTbHp+GrTe4VDz7tbCXuZIxvkQQMG0 Pd5Q== X-Gm-Message-State: AJcUukfliDTKT4b0xAS395ve9/otMFNdoya8Ttp8kZ7t2XcDPuY9eb+F QwKj5uqc42jsDAA+jUrAXucpVA== X-Received: by 2002:a50:ba5c:: with SMTP id 28mr41749211eds.91.1549100491572; Sat, 02 Feb 2019 01:41:31 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:30 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 03/10] efi: memattr: don't bail on zero VA if it equals the region's PA Date: Sat, 2 Feb 2019 10:41:12 +0100 Message-Id: <20190202094119.13230-4-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The EFI memory attributes code cross-references the EFI memory map with the more granular EFI memory attributes table to ensure that they are in sync before applying the strict permissions to the regions it describes. Since we always install virtual mappings for the EFI runtime regions to which these strict permissions apply, we currently perform a sanity check on the EFI memory descriptor, and ensure that the EFI_MEMORY_RUNTIME bit is set, and that the virtual address has been assigned. However, in cases where a runtime region exists at physical address 0x0, and the virtual mapping equals the physical mapping, e.g., when running in mixed mode on x86, we encounter a memory descriptor with the runtime attribute and virtual address 0x0, and incorrectly draw the conclusion that a runtime region exists for which no virtual mapping was installed, and give up altogether. The consequence of this is that firmware mappings retain their read-write-execute permissions, making the system more vulnerable to attacks. So let's only bail if the virtual address of 0x0 has been assigned to a physical region that does not reside at address 0x0. Fixes: 10f0d2f577053 ("efi: Implement generic support for the Memory ...") Acked-by: Sai Praneeth Prakhya Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/memattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.17.1 diff --git a/drivers/firmware/efi/memattr.c b/drivers/firmware/efi/memattr.c index 8986757eafaf..aac972b056d9 100644 --- a/drivers/firmware/efi/memattr.c +++ b/drivers/firmware/efi/memattr.c @@ -94,7 +94,7 @@ static bool entry_is_valid(const efi_memory_desc_t *in, efi_memory_desc_t *out) if (!(md->attribute & EFI_MEMORY_RUNTIME)) continue; - if (md->virt_addr == 0) { + if (md->virt_addr == 0 && md->phys_addr != 0) { /* no virtual mapping has been installed by the stub */ break; } From patchwork Sat Feb 2 09:41:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157336 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1510372jaa; Sat, 2 Feb 2019 01:42:17 -0800 (PST) X-Google-Smtp-Source: AHgI3IZqpt/NmRP7R1S1s1nV51w2ZwdUNXhp6JdLqcQggAuWeDB49ViTBp3hTjEizdrGJAHVhkMP X-Received: by 2002:a63:c503:: with SMTP id f3mr5443214pgd.431.1549100537517; Sat, 02 Feb 2019 01:42:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100537; cv=none; d=google.com; s=arc-20160816; b=SDoOLn9P2uy2nJldM9gfl7dwTaiAdsiGn9cV/I7MWmRMKF81v6Pe3cZ40tHz8eSp0h OCNqmXz1TkHo74PKAPlcC6yuecXz13Ib+kLNs5/Ppn6aVYVamUxMcyzzj+ePXOp5zXAN i0A/WF+8DQhqjFvIS7SF9/sp7NNhdwi+9PDK7UHU6enMgF4upar8Hg2gY+zNEu3HRh4g 152bsEIBU/kPeLepobJHQC3E6P9iR05k/rl2BmzXbOQcmIgaCrlDXxO9VoJwiZcFIEj3 +/jfuE22KyC7/O1jB8luWbhi3tE2/lSM5VO/UcZydoS4volRfLk+Q4OrodU/UhAE9F0K LSLQ== 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; bh=O2XzZIsl3vvBFchu48mWrW+Bva6lWuZ8ML/K496KFP0=; b=kfVCPp1Nf4OqxJ/I3bsOnQ2oPtsrKeIAJV/FsgbhL4j9+a1nCAmwqS3W0bP2/2wVGC JKSjjIyo0zclkx06jqtKyJrkHo1sqswn0mwIaxGB52KC+OJ5q9tvUvlCGTDDoNGE7wC9 wG33xSMZ8rwOJbZLuLond4DtMYpB7tRfjn7IMk0JIoRbgfvt3Pk5E3eCJYwctx7sXfpH dTT+faPLlPG8gtKW+oWwQ6QkLjdJ/jUCDZcrOVSE28G3INi21QfYrJUlq5XjQCVOJ8If oA0CPgzyfAxsqIxsRFZ/p1khFVEFku+WX4A4ozeCXfebaJ2wa2OvIvTPGzMOcF3SXRvf v5zw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Xc+QCRFS; 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 y26si9951364pfd.25.2019.02.02.01.42.17; Sat, 02 Feb 2019 01:42:17 -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=Xc+QCRFS; 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 S1727944AbfBBJmP (ORCPT + 31 others); Sat, 2 Feb 2019 04:42:15 -0500 Received: from mail-ed1-f68.google.com ([209.85.208.68]:43845 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727397AbfBBJle (ORCPT ); Sat, 2 Feb 2019 04:41:34 -0500 Received: by mail-ed1-f68.google.com with SMTP id f9so7433609eds.10 for ; Sat, 02 Feb 2019 01:41:33 -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=O2XzZIsl3vvBFchu48mWrW+Bva6lWuZ8ML/K496KFP0=; b=Xc+QCRFSH4rqU01My7TyOmCVs82S37Gb0U7UVb81L0TmzDKVp8+pcJ2GFBFc8va+6e AaUZ5V2dYbFTTxdtn+JqRTVL6YdqY01wU8MGQU+B49KXGri7yYJCRO+P0qWdmu13XECE hkRppfRYCgn3xjhy4ITLLr4rYe/BvRaH1K3Nk= 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=O2XzZIsl3vvBFchu48mWrW+Bva6lWuZ8ML/K496KFP0=; b=XG23/YCFkLzQLFkwrwt0lNzq9h3OKg+IIToF0BX+bQq8tglWYVPvIv/IuVlZS/TeWG 7GGD+t92P0cQDcA/QUOXyTXmf2tSvEyJHeydtnNoDbNteCGJdK3ylXJ5y4ULUXWdL2jN YiLlBoqoQoiwUDXzAxmiSsGpzx8rJgvwTFMd9ZjjVePpHxHVXH8qGgYt1qxopp8uthc+ mSSMnFq9Ruw85VLtW406SdTHaCMQpjr7/UynRboM4KrvcLSjYGwc/Pd0oKdYU5XGhkXx RWv81r14+dHv2shcOSweelQt4o+Kqum48l3hd2K2WSzMSZvXd6mr65dCvFy1h4MplXhG P2Hw== X-Gm-Message-State: AJcUukcsnCDXf5TkqYhe9xtQ9saM0s48GMwC/uRrrLQfTc0qlYy00Mu6 3ffScxGC8V75v5QHfH4voS6+mw== X-Received: by 2002:aa7:d9d6:: with SMTP id v22mr41768865eds.265.1549100492978; Sat, 02 Feb 2019 01:41:32 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:32 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 04/10] efi: use 32-bit alignment for efi_guid_t Date: Sat, 2 Feb 2019 10:41:13 +0100 Message-Id: <20190202094119.13230-5-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The UEFI spec and EDK2 reference implementation both define EFI_GUID as struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied alignment is 32 bits not 8 bits like our guid_t. In some cases (i.e., on 32-bit ARM), this means that firmware services invoked by the kernel may assume that efi_guid_t* arguments are 32-bit aligned, and use memory accessors that do not tolerate misalignment. So let's set the minimum alignment to 32 bits. Note that the UEFI spec as well as some comments in the EDK2 code base suggest that EFI_GUID should be 64-bit aligned, but this appears to be a mistake, given that no code seems to exist that actually enforces that or relies on it. Reported-by: Heinrich Schuchardt Reviewed-by: Leif Lindholm Signed-off-by: Ard Biesheuvel --- include/linux/efi.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) -- 2.17.1 diff --git a/include/linux/efi.h b/include/linux/efi.h index 45ff763fba76..be08518c2553 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -48,7 +48,20 @@ typedef u16 efi_char16_t; /* UNICODE character */ typedef u64 efi_physical_addr_t; typedef void *efi_handle_t; -typedef guid_t efi_guid_t; +/* + * The UEFI spec and EDK2 reference implementation both define EFI_GUID as + * struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied alignment + * is 32 bits not 8 bits like our guid_t. In some cases (i.e., on 32-bit ARM), + * this means that firmware services invoked by the kernel may assume that + * efi_guid_t* arguments are 32-bit aligned, and use memory accessors that + * do not tolerate misalignment. So let's set the minimum alignment to 32 bits. + * + * Note that the UEFI spec as well as some comments in the EDK2 code base + * suggest that EFI_GUID should be 64-bit aligned, but this appears to be + * a mistake, given that no code seems to exist that actually enforces that + * or relies on it. + */ +typedef guid_t efi_guid_t __aligned(__alignof__(u32)); #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) From patchwork Sat Feb 2 09:41:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157335 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1510318jaa; Sat, 2 Feb 2019 01:42:12 -0800 (PST) X-Google-Smtp-Source: ALg8bN6xMgYIeT3d2WqPwmggsaPFNxVQDRArwmGAMdBHP9Ly6JW5xkaS7CljFPhXPgE8j9oJ0jNv X-Received: by 2002:a17:902:15a8:: with SMTP id m37mr43700159pla.129.1549100532542; Sat, 02 Feb 2019 01:42:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100532; cv=none; d=google.com; s=arc-20160816; b=CanMU2MwyjU2MN8EUnZp6AMbR4ESNLBALykP+wYiasCZtjXPMEhajgOOP30m1kumgd EZxEYOrEAGfadgxHtMKAAcJCgt65zK78JnZLMrE2m41ix79WhJARqrG+s6XhFpU7w9eF kQulNrPFemtUrjFB3DpY19miDIuhIwqoGRH8hPn9yWqS/5yDjUroDnWAad+VrUvJXm8O N3nDB6oimATbVWSMI1KXg/jG833e1mRCTWtw1SXYVviYnJhRkuTzeo4l99QSUAVojYLg JK3tVHSY6BvVir6nfCHQ9FTULZx4tJxjV45oIE2LIVAyEX2IPp+LmNXcmW3wiUL2IMhx pizQ== 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; bh=Iyk48dpEixeAa0E0PkK5cjP8Munu8KzVEGJfUmsPdvc=; b=r0LnO+PDNv9jGNvEV5OODDCOFO7lDZw3SOPJmTfPo+T/oItDBse6kfRyidaPt7uqWO l645zcT43ZCeXchwqfz3Jr808Bmy8bsieI/GmKKTJpRMMlTx12xECxvxtmkTThzeXZ3B OVAwNpOxKhv7koJY02eeOBz5vQtgfxyHZc4ZgBfoitG5gpFA0YysmXkq2Seua/M5zSwd s7v4bQkaNxfKMmhl+FTOGCoSiPyNVDXe2IPoDMpDfvE3r1z7AmzysaQLjYaS0/1S/SVR 8VcsZ6R3AlESc2OjZc9SXARXeuyuRcxSXBHG5Gpr8JEKHX4F6k6OBhSkm+7+g6QOzNK3 kTbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=T1GdfZ8s; 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 v19si10253402pfa.80.2019.02.02.01.42.12; Sat, 02 Feb 2019 01:42:12 -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=T1GdfZ8s; 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 S1727913AbfBBJmK (ORCPT + 31 others); Sat, 2 Feb 2019 04:42:10 -0500 Received: from mail-ed1-f68.google.com ([209.85.208.68]:38725 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727550AbfBBJli (ORCPT ); Sat, 2 Feb 2019 04:41:38 -0500 Received: by mail-ed1-f68.google.com with SMTP id h50so7470806ede.5 for ; Sat, 02 Feb 2019 01:41:35 -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=Iyk48dpEixeAa0E0PkK5cjP8Munu8KzVEGJfUmsPdvc=; b=T1GdfZ8sHCp9iwJmGmItcoaodR9FlEXAuSSYLMZhS3qlRjmWhY6PBzGNd15SraNoMq +pj+1kanclfz9r8brUXEBG+fm0XOOl186CHVBAYXEqKifbaP09Smq4NnXl24xeyxLcou 7vmpEydf6y59SGWKijKm3BEZx8Xw1kcRDIuNE= 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=Iyk48dpEixeAa0E0PkK5cjP8Munu8KzVEGJfUmsPdvc=; b=hs0RebUjn6CvY+yPFNcxlTM39y5yZPap9E76IgZ9XrHoN18E5POSzqgbzm3hOImOF9 aGv6pU0LS+QG539HfDPnEYpOlGYRCz2wlGDi3zdyq1THpIpFEKvypo6v+2mK9l4Qd3Ox GF35KH79HdpqN3b/r+0kCKwBCftEwDBE048y9CVoAJmMQnW4jarN0MvTUYu9J94M0tCC y94KGXQGxw2tvkQOkE59lEhl7va0f6CHXZavsy5SZYPoSKkr7NYtP95O7Vd0YWI8xP5S OV9rpjJJ5ypIsLdgJ6wIH1xR/6Lh5oxZum52qR/QyRBFZJb1ibdVvIDX/zGXfmyOE3CR m3rw== X-Gm-Message-State: AJcUukfjfFkBLIoE4swTIAsKrMfH1MXmlfT+FvF3W95lRjfszQR7NZmQ u6OlGCMg+X8ngSv6R5tXXtfN4w== X-Received: by 2002:a17:906:78cf:: with SMTP id r15mr37341737ejn.96.1549100494651; Sat, 02 Feb 2019 01:41:34 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:33 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 05/10] efi/fdt: More cleanups Date: Sat, 2 Feb 2019 10:41:14 +0100 Message-Id: <20190202094119.13230-6-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ingo Molnar Apply a number of cleanups: - Introduce fdt_setprop_*var() helper macros to simplify and shorten repetitive sequences - this also makes it less likely that the wrong variable size is passed in. This change makes a lot of the property-setting calls single-line and easier to read. - Harmonize comment style: capitalization, punctuation, whitespaces, etc. - Fix some whitespace noise in the libstub Makefile which I happened to notice. - Use the standard tabular initialization style: - map.map = &runtime_map; - map.map_size = &map_size; - map.desc_size = &desc_size; - map.desc_ver = &desc_ver; - map.key_ptr = &mmap_key; - map.buff_size = &buff_size; + map.map = &runtime_map; + map.map_size = &map_size; + map.desc_size = &desc_size; + map.desc_ver = &desc_ver; + map.key_ptr = &mmap_key; + map.buff_size = &buff_size; - Use tabular structure definition for better readability. - Make all pr*() lines single-line, even if they marginally exceed 80 cols - this makes them visually less intrusive. - Unbreak line breaks into single lines when the length exceeds 80 cols only marginally, for better readability. - Move assignment closer to the actual usage site. - Plus some other smaller cleanups, spelling fixes, etc. No change in functionality intended. Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Ingo Molnar [ardb: move changes to upstream libfdt into local header] Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/Makefile | 4 +- drivers/firmware/efi/libstub/efistub.h | 11 +++ drivers/firmware/efi/libstub/fdt.c | 107 ++++++++++++------------- 3 files changed, 64 insertions(+), 58 deletions(-) -- 2.17.1 diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index d9845099635e..b0103e16fc1b 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -52,7 +52,7 @@ lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \ lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o -CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) +CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # # arm64 puts the stub in the kernel proper, which will unnecessarily retain all @@ -89,7 +89,7 @@ quiet_cmd_stubcopy = STUBCPY $@ cmd_stubcopy = if $(STRIP) --strip-debug $(STUBCOPY_RM-y) -o $@ $<; \ then if $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y); \ then (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \ - rm -f $@; /bin/false); \ + rm -f $@; /bin/false); \ else $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@; fi \ else /bin/false; fi diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 32799cf039ef..cefcf6ba3150 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -64,4 +64,15 @@ efi_status_t check_platform_features(efi_system_table_t *sys_table_arg); efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg); +/* Helper macros for the usual case of using simple C variables: */ +#ifndef fdt_setprop_inplace_var +#define fdt_setprop_inplace_var(fdt, node_offset, name, var) \ + fdt_setprop_inplace((fdt), (node_offset), (name), &(var), sizeof(var)) +#endif + +#ifndef fdt_setprop_var +#define fdt_setprop_var(fdt, node_offset, name, var) \ + fdt_setprop((fdt), (node_offset), (name), &(var), sizeof(var)) +#endif + #endif diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index 0dc7b4987cc2..d474964b873b 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -26,10 +26,8 @@ static void fdt_update_cell_size(efi_system_table_t *sys_table, void *fdt) offset = fdt_path_offset(fdt, "/"); /* Set the #address-cells and #size-cells values for an empty tree */ - fdt_setprop_u32(fdt, offset, "#address-cells", - EFI_DT_ADDR_CELLS_DEFAULT); - - fdt_setprop_u32(fdt, offset, "#size-cells", EFI_DT_SIZE_CELLS_DEFAULT); + fdt_setprop_u32(fdt, offset, "#address-cells", EFI_DT_ADDR_CELLS_DEFAULT); + fdt_setprop_u32(fdt, offset, "#size-cells", EFI_DT_SIZE_CELLS_DEFAULT); } static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, @@ -42,7 +40,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, u32 fdt_val32; u64 fdt_val64; - /* Do some checks on provided FDT, if it exists*/ + /* Do some checks on provided FDT, if it exists: */ if (orig_fdt) { if (fdt_check_header(orig_fdt)) { pr_efi_err(sys_table, "Device Tree header not valid!\n"); @@ -50,7 +48,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, } /* * We don't get the size of the FDT if we get if from a - * configuration table. + * configuration table: */ if (orig_fdt_size && fdt_totalsize(orig_fdt) > orig_fdt_size) { pr_efi_err(sys_table, "Truncated device tree! foo!\n"); @@ -64,8 +62,8 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, status = fdt_create_empty_tree(fdt, new_fdt_size); if (status == 0) { /* - * Any failure from the following function is non - * critical + * Any failure from the following function is + * non-critical: */ fdt_update_cell_size(sys_table, fdt); } @@ -86,12 +84,13 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, if (node < 0) { node = fdt_add_subnode(fdt, 0, "chosen"); if (node < 0) { - status = node; /* node is error code when negative */ + /* 'node' is an error code when negative: */ + status = node; goto fdt_set_fail; } } - if ((cmdline_ptr != NULL) && (strlen(cmdline_ptr) > 0)) { + if (cmdline_ptr != NULL && strlen(cmdline_ptr) > 0) { status = fdt_setprop(fdt, node, "bootargs", cmdline_ptr, strlen(cmdline_ptr) + 1); if (status) @@ -103,13 +102,12 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, u64 initrd_image_end; u64 initrd_image_start = cpu_to_fdt64(initrd_addr); - status = fdt_setprop(fdt, node, "linux,initrd-start", - &initrd_image_start, sizeof(u64)); + status = fdt_setprop_var(fdt, node, "linux,initrd-start", initrd_image_start); if (status) goto fdt_set_fail; + initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size); - status = fdt_setprop(fdt, node, "linux,initrd-end", - &initrd_image_end, sizeof(u64)); + status = fdt_setprop_var(fdt, node, "linux,initrd-end", initrd_image_end); if (status) goto fdt_set_fail; } @@ -117,30 +115,28 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, /* Add FDT entries for EFI runtime services in chosen node. */ node = fdt_subnode_offset(fdt, 0, "chosen"); fdt_val64 = cpu_to_fdt64((u64)(unsigned long)sys_table); - status = fdt_setprop(fdt, node, "linux,uefi-system-table", - &fdt_val64, sizeof(fdt_val64)); + + status = fdt_setprop_var(fdt, node, "linux,uefi-system-table", fdt_val64); if (status) goto fdt_set_fail; fdt_val64 = U64_MAX; /* placeholder */ - status = fdt_setprop(fdt, node, "linux,uefi-mmap-start", - &fdt_val64, sizeof(fdt_val64)); + + status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); if (status) goto fdt_set_fail; fdt_val32 = U32_MAX; /* placeholder */ - status = fdt_setprop(fdt, node, "linux,uefi-mmap-size", - &fdt_val32, sizeof(fdt_val32)); + + status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); if (status) goto fdt_set_fail; - status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-size", - &fdt_val32, sizeof(fdt_val32)); + status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32); if (status) goto fdt_set_fail; - status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-ver", - &fdt_val32, sizeof(fdt_val32)); + status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); if (status) goto fdt_set_fail; @@ -150,8 +146,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, efi_status = efi_get_random_bytes(sys_table, sizeof(fdt_val64), (u8 *)&fdt_val64); if (efi_status == EFI_SUCCESS) { - status = fdt_setprop(fdt, node, "kaslr-seed", - &fdt_val64, sizeof(fdt_val64)); + status = fdt_setprop_var(fdt, node, "kaslr-seed", fdt_val64); if (status) goto fdt_set_fail; } else if (efi_status != EFI_NOT_FOUND) { @@ -159,7 +154,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, } } - /* shrink the FDT back to its minimum size */ + /* Shrink the FDT back to its minimum size: */ fdt_pack(fdt); return EFI_SUCCESS; @@ -182,26 +177,26 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) return EFI_LOAD_ERROR; fdt_val64 = cpu_to_fdt64((unsigned long)*map->map); - err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start", - &fdt_val64, sizeof(fdt_val64)); + + err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); if (err) return EFI_LOAD_ERROR; fdt_val32 = cpu_to_fdt32(*map->map_size); - err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size", - &fdt_val32, sizeof(fdt_val32)); + + err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); if (err) return EFI_LOAD_ERROR; fdt_val32 = cpu_to_fdt32(*map->desc_size); - err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-size", - &fdt_val32, sizeof(fdt_val32)); + + err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32); if (err) return EFI_LOAD_ERROR; fdt_val32 = cpu_to_fdt32(*map->desc_ver); - err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-ver", - &fdt_val32, sizeof(fdt_val32)); + + err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); if (err) return EFI_LOAD_ERROR; @@ -209,13 +204,13 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) } #ifndef EFI_FDT_ALIGN -#define EFI_FDT_ALIGN EFI_PAGE_SIZE +# define EFI_FDT_ALIGN EFI_PAGE_SIZE #endif struct exit_boot_struct { - efi_memory_desc_t *runtime_map; - int *runtime_entry_count; - void *new_fdt_addr; + efi_memory_desc_t *runtime_map; + int *runtime_entry_count; + void *new_fdt_addr; }; static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg, @@ -235,7 +230,7 @@ static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg, } #ifndef MAX_FDT_SIZE -#define MAX_FDT_SIZE SZ_2M +# define MAX_FDT_SIZE SZ_2M #endif /* @@ -266,16 +261,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, unsigned long mmap_key; efi_memory_desc_t *memory_map, *runtime_map; efi_status_t status; - int runtime_entry_count = 0; + int runtime_entry_count; struct efi_boot_memmap map; struct exit_boot_struct priv; - map.map = &runtime_map; - map.map_size = &map_size; - map.desc_size = &desc_size; - map.desc_ver = &desc_ver; - map.key_ptr = &mmap_key; - map.buff_size = &buff_size; + map.map = &runtime_map; + map.map_size = &map_size; + map.desc_size = &desc_size; + map.desc_ver = &desc_ver; + map.key_ptr = &mmap_key; + map.buff_size = &buff_size; /* * Get a copy of the current memory map that we will use to prepare @@ -289,15 +284,13 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, return status; } - pr_efi(sys_table, - "Exiting boot services and installing virtual address map...\n"); + pr_efi(sys_table, "Exiting boot services and installing virtual address map...\n"); map.map = &memory_map; status = efi_high_alloc(sys_table, MAX_FDT_SIZE, EFI_FDT_ALIGN, new_fdt_addr, max_addr); if (status != EFI_SUCCESS) { - pr_efi_err(sys_table, - "Unable to allocate memory for new device tree.\n"); + pr_efi_err(sys_table, "Unable to allocate memory for new device tree.\n"); goto fail; } @@ -318,11 +311,12 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, goto fail_free_new_fdt; } - priv.runtime_map = runtime_map; - priv.runtime_entry_count = &runtime_entry_count; - priv.new_fdt_addr = (void *)*new_fdt_addr; - status = efi_exit_boot_services(sys_table, handle, &map, &priv, - exit_boot_func); + runtime_entry_count = 0; + priv.runtime_map = runtime_map; + priv.runtime_entry_count = &runtime_entry_count; + priv.new_fdt_addr = (void *)*new_fdt_addr; + + status = efi_exit_boot_services(sys_table, handle, &map, &priv, exit_boot_func); if (status == EFI_SUCCESS) { efi_set_virtual_address_map_t *svam; @@ -363,6 +357,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, fail: sys_table->boottime->free_pool(runtime_map); + return EFI_LOAD_ERROR; } From patchwork Sat Feb 2 09:41:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157332 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1509996jaa; Sat, 2 Feb 2019 01:41:48 -0800 (PST) X-Google-Smtp-Source: AHgI3IayXKUuhsb4vZEv0fFLnoYgOjIN0e4dQknE12PPSDr63Hm+ezGbHf6civFTA+Olvbb7bA6s X-Received: by 2002:a63:1013:: with SMTP id f19mr5622336pgl.38.1549100508309; Sat, 02 Feb 2019 01:41:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100508; cv=none; d=google.com; s=arc-20160816; b=Jr+K/IxTh1jy+SMPaYJpj8DmNCto8dGD/E9eVNkd8MTdTYW8jCNzUGRjcqrrpGHEfS q3W/ukpeykgpWByTV1B1LyX4pKkt/YJNpd31EraLrQuTqS6w9vlHE+oM9weVUwVLkoRm f/LNR+sLevXoq4i+UctmE6Zug1v5LzWLQvkFOx6lXIUKFihdLbKnJiXcxlO2RwQwo6T+ fUkm7YE2rlkJBbW9EM7+xUuS39s+NEqHS8OpyaejgrqD3Ccp5+xtCrYYnwwaxUwUpfF9 vP5X85ux2uQ6rqbbxC7TUwqgzG9bB7KD7gkXKVnLfNPdznIk2rmKDyEsHFcP2yNpmPr6 bVbQ== 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; bh=iULYkK79KzQBLjCzo7CPIeChw9PmIPBpwpuo29dYAvY=; b=h32kVJe1ERX4CE0g0CWey+JvJ7ljW8sBiQlphSk3izkHVvGMJjNpLPg1PbHaIxzP4u iHRDnzgLcla+WRs40n7h4u5V/lQB/WwQLPFrfnierapCYtwIL/ZqIDtBLTV+LCm8Z/MA PZyOgO5nVDmIAJP4yfbchie2vD/FJ8UQHgcDISnU1rJano7L+iydkYXrzoAI463iALnt v8YdFIppfr8laHM6xEkpL/07Elt4dlJ8KbarlSUKVS9bMPM07DHRS8BVp3JHtR2xobgN A0C1XWN18UHZ5xg9qVIbCficaeZVsy2ukvxG8YoVVn4jl3jlXpgJFhQsbYI8xoSkHVNf ZX7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=T3vgkLIZ; 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 c65si10100500pfe.202.2019.02.02.01.41.48; Sat, 02 Feb 2019 01:41:48 -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=T3vgkLIZ; 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 S1727827AbfBBJlq (ORCPT + 31 others); Sat, 2 Feb 2019 04:41:46 -0500 Received: from mail-ed1-f67.google.com ([209.85.208.67]:34305 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727662AbfBBJlk (ORCPT ); Sat, 2 Feb 2019 04:41:40 -0500 Received: by mail-ed1-f67.google.com with SMTP id b3so7516301ede.1 for ; Sat, 02 Feb 2019 01:41:39 -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=iULYkK79KzQBLjCzo7CPIeChw9PmIPBpwpuo29dYAvY=; b=T3vgkLIZXa0V+j0poP/GqVK5uMWVYHB5KT1wpcxU8+sWPsMPj3VSoA1cLPuqgiTIvK DFPkzouQE0soyhlw+bXv8OqICmb76KmSNL4cxWJBi0UeaOV1fjBHdcbQWQZImYVfwwlv 4WniOgtSiPG/V0nai9ug659D5v2uzCMlRc0A4= 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=iULYkK79KzQBLjCzo7CPIeChw9PmIPBpwpuo29dYAvY=; b=IJ8vtVmo3iMuAE5Y/jQPKrI6NycQ/NT+kb+p0Dc1vYseoH72vvMUinb/bPu0auEKJo VLGNDsvf/s6Ld8U7U7Eu1Waecbo8u0fDBAON6n2NUjJlPVeE15HH/h+rN6T2IHVWhFc/ sFSfEYHQXO2GVPi4QnaSvvZHDntir4GIvlr0fVMB2roJw6uIOnMGo3VvhHVRXZD2Wy+F egPTAg89yj8UpBAhVclAYAAk/FrYt6qUB8q7MZbTA39RTRXqBBlch4/vJrTpQbDl55Gr ZaEqlx08qsAKMe+wLIlK6xLhg9eR+YC15gzQ+pV5XePPnVcfHmEdC49Y++FUxQOY+d+N HH4w== X-Gm-Message-State: AJcUukcumAvlsxJbAGhZm46swnUVNhGyGb8UowcdPNmMP6LSZZooiN17 5QjVVZzQzCZ6hEcXNyFUudjG9A== X-Received: by 2002:a50:9b1d:: with SMTP id o29mr40373314edi.246.1549100498944; Sat, 02 Feb 2019 01:41:38 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:38 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 08/10] x86: make ARCH_USE_MEMREMAP_PROT a generic Kconfig symbol Date: Sat, 2 Feb 2019 10:41:17 +0100 Message-Id: <20190202094119.13230-9-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Turn ARCH_USE_MEMREMAP_PROT into a generic Kconfig symbol, and fix the dependency expression to reflect that AMD_MEM_ENCRYPT depends on it, instead of the other way around. This will permit ARCH_USE_MEMREMAP_PROT to be selected by other architectures. Note that the encryption related early memremap routines in arch/x86/mm/ioremap.c cannot be built for 32-bit x86 without triggering the following warning: arch/x86//mm/ioremap.c: In function 'early_memremap_encrypted': >> arch/x86/include/asm/pgtable_types.h:193:27: warning: conversion from 'long long unsigned int' to 'long unsigned int' changes value from '9223372036854776163' to '355' [-Woverflow] #define __PAGE_KERNEL_ENC (__PAGE_KERNEL | _PAGE_ENC) ^~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86//mm/ioremap.c:713:46: note: in expansion of macro '__PAGE_KERNEL_ENC' return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_ENC); which essentially means they are 64-bit only anyway. However, we cannot make them dependent on CONFIG_ARCH_HAS_MEM_ENCRYPT, since that is always defined, even for i386 (and changing that results in a slew of build errors) So instead, build those routines only if CONFIG_AMD_MEM_ENCRYPT is defined. Signed-off-by: Ard Biesheuvel --- arch/Kconfig | 3 +++ arch/x86/Kconfig | 5 +---- arch/x86/mm/ioremap.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) -- 2.17.1 diff --git a/arch/Kconfig b/arch/Kconfig index 4cfb6de48f79..9f0213213da8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -885,6 +885,9 @@ config HAVE_ARCH_PREL32_RELOCATIONS architectures, and don't require runtime relocation on relocatable kernels. +config ARCH_USE_MEMREMAP_PROT + bool + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 15af091611e2..09c2c5600579 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1510,6 +1510,7 @@ config AMD_MEM_ENCRYPT bool "AMD Secure Memory Encryption (SME) support" depends on X86_64 && CPU_SUP_AMD select DYNAMIC_PHYSICAL_MASK + select ARCH_USE_MEMREMAP_PROT ---help--- Say yes to enable support for the encryption of system memory. This requires an AMD processor that supports Secure Memory @@ -1529,10 +1530,6 @@ config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT If set to N, then the encryption of system memory can be activated with the mem_encrypt=on command line option. -config ARCH_USE_MEMREMAP_PROT - def_bool y - depends on AMD_MEM_ENCRYPT - # Common NUMA Features config NUMA bool "Numa Memory Allocation and Scheduler Support" diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 5378d10f1d31..0029604af8a4 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -705,7 +705,7 @@ bool phys_mem_access_encrypted(unsigned long phys_addr, unsigned long size) return arch_memremap_can_ram_remap(phys_addr, size, 0); } -#ifdef CONFIG_ARCH_USE_MEMREMAP_PROT +#ifdef CONFIG_AMD_MEM_ENCRYPT /* Remap memory with encryption */ void __init *early_memremap_encrypted(resource_size_t phys_addr, unsigned long size) @@ -747,7 +747,7 @@ void __init *early_memremap_decrypted_wp(resource_size_t phys_addr, return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC_WP); } -#endif /* CONFIG_ARCH_USE_MEMREMAP_PROT */ +#endif /* CONFIG_AMD_MEM_ENCRYPT */ static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss; From patchwork Sat Feb 2 09:41:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157334 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1510099jaa; Sat, 2 Feb 2019 01:41:57 -0800 (PST) X-Google-Smtp-Source: ALg8bN7qnKbIkPtiWd4RnivyHU3CWip2iwfKHRnAd/Y8yYvLqWvtOMhQGP6k5BDBr3hMxXQrzXca X-Received: by 2002:a62:75d1:: with SMTP id q200mr42938053pfc.254.1549100516949; Sat, 02 Feb 2019 01:41:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100516; cv=none; d=google.com; s=arc-20160816; b=EARxxLsTD6BRdB9jZE9DY9iM4cRqEwVL1HDGJaMp2ZQn9MvYWVmNhU/cSXdxrtvMsi FDBYk4XwvnxlRR7AWqqBBy/8lpqYGkXnqNMFH2V9DtzSH1tUctYOViBSGO1IFBLc1Dki e6Nzy1l/x8tmHFkYH0/+xavQLBUgw693SovIQEnyS/6ZNUfUwoTXIpuYhftLm6XxI9VQ pnmezEJWgUBOsBsSXo2wuTQYUy3Q05ED3tpkLjAaguqc5AUIbSKj+jrhaFJI8j3cp0EF kR0zgc7Tc0QZ2cMrY/BcjTz6thRg+sY8aNScJoO0fStEgrDPQ80m66Tv6eECcBnYKzZz DMaw== 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; bh=mwg5Ah8nIeO+W6wCFX0pD1gr7HS/By0xQ7PGiMwrE2s=; b=KlVqrUKTMt4lni/9VMYijfEY8KuBM4OWcz6mLimytMSVf5sHndYE9gqIGzyHSn2aN4 2lA7B+RM59+5oMU5JNtmROg5G4gXbR+X86nDMS23e9BP47cc/HCf0pM5lwVfmSopHOX5 e7ucVeQKTeN0WEyYleulgngvsiXusI4tURXcDwTaFrLU5PFI7gTJZKTCGFJ7l4JkTlaN +apOtLsPOOk1Cn1MuZm4GlHTjHwThTHwCWqDFu+L9O/5uKVSgIlv5R4kOk+crdxGfyle VFoJV0UtSePBiJHkyC7rFBR0XrGB2aykVCYa613kpmqduwmurvJsI3c+xGUjAgeQCwD0 LUXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CE6Ftvng; 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 v32si3031854plb.369.2019.02.02.01.41.56; Sat, 02 Feb 2019 01:41:56 -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=CE6Ftvng; 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 S1727847AbfBBJlt (ORCPT + 31 others); Sat, 2 Feb 2019 04:41:49 -0500 Received: from mail-ed1-f65.google.com ([209.85.208.65]:45611 "EHLO mail-ed1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727694AbfBBJlm (ORCPT ); Sat, 2 Feb 2019 04:41:42 -0500 Received: by mail-ed1-f65.google.com with SMTP id d39so7431581edb.12 for ; Sat, 02 Feb 2019 01:41:41 -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=mwg5Ah8nIeO+W6wCFX0pD1gr7HS/By0xQ7PGiMwrE2s=; b=CE6FtvngQ/Bk90WPH8q8dXWzZR+FGcM7FXzD34i3EMmRJQmixmgPeO4jH2QAdNePH/ /LJSL7e2cQZOrZxBhEp97axtCzh1JbCqV4PK7LZaRo/ieFSQAvGtuuuE/70ebSfHkk+x Sxlmholng5PLaqxZsC+QV+OnCHqBQUCkLUtJg= 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=mwg5Ah8nIeO+W6wCFX0pD1gr7HS/By0xQ7PGiMwrE2s=; b=DAwOa6A1OOG9UZD7aSbn6Dskr9WjBhpRPZuwn9OhtlxKCN3e3GAYPrD6gw9S9XuARa zJYoJgbBoRIv3eaBDFUlSLrrUetbBVVGcsPH8eqe4B4wlAOaK/IE87JWmMfxxbv0XZCd EhhI1YcKD5348pwRuSIyB9Nv2jKL8avwK3AItvkZemL+XRihSVSjqN4kFguPD9H3/bKT qyIcD+33WzIgzfNyL3/HwTTo3tZZUXA/dLkVzPcad0A6Hpd84yR18uni5dDtqxDG3KQV vq+s7FxLu67Ca+f21tS+RNT3jwk8H4ASr8JGciPONbaAEUpyqTWn2N5yQq2/dBhCceIL v7Kw== X-Gm-Message-State: AJcUukcGWqUGxDQ2D7s6Fr6oFX7viNkXWGkkKvFOccuxirINABNN74T0 2zkzBRbH+IsrUZz9BGJHrL7a6w== X-Received: by 2002:a17:906:f110:: with SMTP id gv16mr22414567ejb.223.1549100500406; Sat, 02 Feb 2019 01:41:40 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:39 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 09/10] efi: x86: convert x86 EFI earlyprintk into generic earlycon implementation Date: Sat, 2 Feb 2019 10:41:18 +0100 Message-Id: <20190202094119.13230-10-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Move the x86 EFI earlyprintk implementation to a shared location under drivers/firmware and tweak it slightly so we can expose it as an earlycon implementation (which is generic) rather than earlyprintk (which is only implemented for a few architectures) This also involves switching to write-combine mappings by default (which is required on ARM since device mappings lack memory semantics, and so memcpy/memset may not be used on them), and adding support for shared memory framebuffers on cache coherent non-x86 systems (which do not tolerate mismatched attributes) Note that 32-bit ARM does not populate its struct screen_info early enough for earlycon=efifb to work, so it is disabled there. Reviewed-by: Alexander Graf Signed-off-by: Ard Biesheuvel --- .../admin-guide/kernel-parameters.txt | 8 +- arch/x86/Kconfig.debug | 10 -- arch/x86/include/asm/efi.h | 1 - arch/x86/kernel/early_printk.c | 4 - arch/x86/platform/efi/Makefile | 1 - drivers/firmware/efi/Kconfig | 6 + drivers/firmware/efi/Makefile | 1 + .../firmware/efi/earlycon.c | 134 +++++++----------- 8 files changed, 64 insertions(+), 101 deletions(-) rename arch/x86/platform/efi/early_printk.c => drivers/firmware/efi/earlycon.c (42%) -- 2.17.1 diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index b799bcf67d7b..76dd3baa31e0 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1073,9 +1073,15 @@ specified address. The serial port must already be setup and configured. Options are not yet supported. + efifb,[options] + Start an early, unaccelerated console on the EFI + memory mapped framebuffer (if available). On cache + coherent non-x86 systems that use system memory for + the framebuffer, pass the 'ram' option so that it is + mapped with the correct attributes. + earlyprintk= [X86,SH,ARM,M68k,S390] earlyprintk=vga - earlyprintk=efi earlyprintk=sclp earlyprintk=xen earlyprintk=serial[,ttySn[,baudrate]] diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 0723dff17e6c..15d0fbe27872 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -40,16 +40,6 @@ config EARLY_PRINTK_DBGP with klogd/syslogd or the X server. You should normally say N here, unless you want to debug such a crash. You need usb debug device. -config EARLY_PRINTK_EFI - bool "Early printk via the EFI framebuffer" - depends on EFI && EARLY_PRINTK - select FONT_SUPPORT - ---help--- - Write kernel log output directly into the EFI framebuffer. - - This is useful for kernel debugging when your machine crashes very - early before the console code is initialized. - config EARLY_PRINTK_USB_XDBC bool "Early printk via the xHCI debug port" depends on EARLY_PRINTK && PCI diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index a37378f986ec..08ebb2270d87 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -170,7 +170,6 @@ static inline bool efi_runtime_supported(void) return false; } -extern struct console early_efi_console; extern void parse_efi_setup(u64 phys_addr, u32 data_len); extern void efifb_setup_from_dmi(struct screen_info *si, const char *opt); diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 374a52fa5296..9b33904251a9 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -388,10 +388,6 @@ static int __init setup_early_printk(char *buf) if (!strncmp(buf, "xen", 3)) early_console_register(&xenboot_console, keep); #endif -#ifdef CONFIG_EARLY_PRINTK_EFI - if (!strncmp(buf, "efi", 3)) - early_console_register(&early_efi_console, keep); -#endif #ifdef CONFIG_EARLY_PRINTK_USB_XDBC if (!strncmp(buf, "xdbc", 4)) early_xdbc_parse_parameter(buf + 4); diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index e4dc3862d423..fe29f3f5d384 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -3,5 +3,4 @@ OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y OBJECT_FILES_NON_STANDARD_efi_stub_$(BITS).o := y obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o -obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 89110dfc7127..190be0b1d109 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -198,3 +198,9 @@ config EFI_DEV_PATH_PARSER bool depends on ACPI default n + +config EFI_EARLYCON + def_bool y + depends on SERIAL_EARLYCON && !ARM && !IA64 + select FONT_SUPPORT + select ARCH_USE_MEMREMAP_PROT diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 5f9f5039de50..d2d0d2030620 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -30,5 +30,6 @@ arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o obj-$(CONFIG_ARM) += $(arm-obj-y) obj-$(CONFIG_ARM64) += $(arm-obj-y) obj-$(CONFIG_EFI_CAPSULE_LOADER) += capsule-loader.o +obj-$(CONFIG_EFI_EARLYCON) += earlycon.o obj-$(CONFIG_UEFI_CPER_ARM) += cper-arm.o obj-$(CONFIG_UEFI_CPER_X86) += cper-x86.o diff --git a/arch/x86/platform/efi/early_printk.c b/drivers/firmware/efi/earlycon.c similarity index 42% rename from arch/x86/platform/efi/early_printk.c rename to drivers/firmware/efi/earlycon.c index 7138bc7a265c..dc1ae14ea4cf 100644 --- a/arch/x86/platform/efi/early_printk.c +++ b/drivers/firmware/efi/earlycon.c @@ -1,8 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2013 Intel Corporation; author Matt Fleming - * - * This file is part of the Linux kernel, and is made available under - * the terms of the GNU General Public License version 2. */ #include @@ -10,104 +8,68 @@ #include #include #include -#include +#include +#include + +#include static const struct font_desc *font; static u32 efi_x, efi_y; -static void *efi_fb; -static bool early_efi_keep; - -/* - * efi earlyprintk need use early_ioremap to map the framebuffer. - * But early_ioremap is not usable for earlyprintk=efi,keep, ioremap should - * be used instead. ioremap will be available after paging_init() which is - * earlier than initcall callbacks. Thus adding this early initcall function - * early_efi_map_fb to map the whole efi framebuffer. - */ -static __init int early_efi_map_fb(void) -{ - u64 base, size; +static u64 fb_base; +static pgprot_t fb_prot; - if (!early_efi_keep) - return 0; - - base = boot_params.screen_info.lfb_base; - if (boot_params.screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) - base |= (u64)boot_params.screen_info.ext_lfb_base << 32; - size = boot_params.screen_info.lfb_size; - efi_fb = ioremap(base, size); - - return efi_fb ? 0 : -ENOMEM; -} -early_initcall(early_efi_map_fb); - -/* - * early_efi_map maps efi framebuffer region [start, start + len -1] - * In case earlyprintk=efi,keep we have the whole framebuffer mapped already - * so just return the offset efi_fb + start. - */ -static __ref void *early_efi_map(unsigned long start, unsigned long len) +static __ref void *efi_earlycon_map(unsigned long start, unsigned long len) { - u64 base; - - base = boot_params.screen_info.lfb_base; - if (boot_params.screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) - base |= (u64)boot_params.screen_info.ext_lfb_base << 32; - - if (efi_fb) - return (efi_fb + start); - else - return early_ioremap(base + start, len); + return early_memremap_prot(fb_base + start, len, pgprot_val(fb_prot)); } -static __ref void early_efi_unmap(void *addr, unsigned long len) +static __ref void efi_earlycon_unmap(void *addr, unsigned long len) { - if (!efi_fb) - early_iounmap(addr, len); + early_memunmap(addr, len); } -static void early_efi_clear_scanline(unsigned int y) +static void efi_earlycon_clear_scanline(unsigned int y) { unsigned long *dst; u16 len; - len = boot_params.screen_info.lfb_linelength; - dst = early_efi_map(y*len, len); + len = screen_info.lfb_linelength; + dst = efi_earlycon_map(y*len, len); if (!dst) return; memset(dst, 0, len); - early_efi_unmap(dst, len); + efi_earlycon_unmap(dst, len); } -static void early_efi_scroll_up(void) +static void efi_earlycon_scroll_up(void) { unsigned long *dst, *src; u16 len; u32 i, height; - len = boot_params.screen_info.lfb_linelength; - height = boot_params.screen_info.lfb_height; + len = screen_info.lfb_linelength; + height = screen_info.lfb_height; for (i = 0; i < height - font->height; i++) { - dst = early_efi_map(i*len, len); + dst = efi_earlycon_map(i*len, len); if (!dst) return; - src = early_efi_map((i + font->height) * len, len); + src = efi_earlycon_map((i + font->height) * len, len); if (!src) { - early_efi_unmap(dst, len); + efi_earlycon_unmap(dst, len); return; } memmove(dst, src, len); - early_efi_unmap(src, len); - early_efi_unmap(dst, len); + efi_earlycon_unmap(src, len); + efi_earlycon_unmap(dst, len); } } -static void early_efi_write_char(u32 *dst, unsigned char c, unsigned int h) +static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h) { const u32 color_black = 0x00000000; const u32 color_white = 0x00ffffff; @@ -128,14 +90,14 @@ static void early_efi_write_char(u32 *dst, unsigned char c, unsigned int h) } static void -early_efi_write(struct console *con, const char *str, unsigned int num) +efi_earlycon_write(struct console *con, const char *str, unsigned int num) { struct screen_info *si; unsigned int len; const char *s; void *dst; - si = &boot_params.screen_info; + si = &screen_info; len = si->lfb_linelength; while (num) { @@ -155,7 +117,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num) for (h = 0; h < font->height; h++) { unsigned int n, x; - dst = early_efi_map((efi_y + h) * len, len); + dst = efi_earlycon_map((efi_y + h) * len, len); if (!dst) return; @@ -164,12 +126,12 @@ early_efi_write(struct console *con, const char *str, unsigned int num) x = efi_x; while (n-- > 0) { - early_efi_write_char(dst + x*4, *s, h); + efi_earlycon_write_char(dst + x*4, *s, h); x += font->width; s++; } - early_efi_unmap(dst, len); + efi_earlycon_unmap(dst, len); } num -= count; @@ -192,26 +154,39 @@ early_efi_write(struct console *con, const char *str, unsigned int num) u32 i; efi_y -= font->height; - early_efi_scroll_up(); + efi_earlycon_scroll_up(); for (i = 0; i < font->height; i++) - early_efi_clear_scanline(efi_y + i); + efi_earlycon_clear_scanline(efi_y + i); } } } -static __init int early_efi_setup(struct console *con, char *options) +static int __init efi_earlycon_setup(struct earlycon_device *device, + const char *opt) { struct screen_info *si; u16 xres, yres; u32 i; - si = &boot_params.screen_info; + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) + return -ENODEV; + + fb_base = screen_info.lfb_base; + if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) + fb_base |= (u64)screen_info.ext_lfb_base << 32; + + if (opt && !strcmp(opt, "ram")) + fb_prot = PAGE_KERNEL; + else + fb_prot = pgprot_writecombine(PAGE_KERNEL); + + si = &screen_info; xres = si->lfb_width; yres = si->lfb_height; /* - * early_efi_write_char() implicitly assumes a framebuffer with + * efi_earlycon_write_char() implicitly assumes a framebuffer with * 32-bits per pixel. */ if (si->lfb_depth != 32) @@ -223,18 +198,9 @@ static __init int early_efi_setup(struct console *con, char *options) efi_y = rounddown(yres, font->height) - font->height; for (i = 0; i < (yres - efi_y) / font->height; i++) - early_efi_scroll_up(); + efi_earlycon_scroll_up(); - /* early_console_register will unset CON_BOOT in case ,keep */ - if (!(con->flags & CON_BOOT)) - early_efi_keep = true; + device->con->write = efi_earlycon_write; return 0; } - -struct console early_efi_console = { - .name = "earlyefi", - .write = early_efi_write, - .setup = early_efi_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; +EARLYCON_DECLARE(efifb, efi_earlycon_setup); From patchwork Sat Feb 2 09:41:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157333 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1510059jaa; Sat, 2 Feb 2019 01:41:53 -0800 (PST) X-Google-Smtp-Source: ALg8bN6eidTMIh75kEkNSfKUT0VG9dS3nKAZYjtn5X+Hu4eUpvEGrXWVIszy6cqrG/Y9iP3NsZFc X-Received: by 2002:a62:60c5:: with SMTP id u188mr43136303pfb.4.1549100513596; Sat, 02 Feb 2019 01:41:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100513; cv=none; d=google.com; s=arc-20160816; b=hXYVe2PuFD9c3SzMmK5HI8fkq9s2H89aOb7occd8+w4n2r3NpD8ZS9SAVOd05RmWpv 2q7G26PuImjL0SAg4ayOozaIAoInani6ye0IKuWovayeu+06et2m8E91fsy/kniaoX2M k7vDHRunZMDL9XaXj2oXMeq/QszHdVBMdfVqD995A+4CgRM6cI/BbYPrD1YzRUXfDbnv mA5SXpQtpXHXNEgTqjlZ6RLuTzyLMemxi8YTRy5IIMGUHFCkskx3t6B7YaugXT7vWpO7 tVvez2A9ftBJ1UPfGqjLiT/SuEgHzfdtnmYAurhkbLXziwjBoN4zTWu6hIE5K3MjlnNx AEXw== 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; bh=UG8rnIGuuYCyn1MgwH5GL70RHIkJGZksj7iIE3TwONc=; b=aSDkQqWdLxx0iU4FyhM5wXh7igxkq0nZexC372S70ZoNGaMGhP93WKg6yvkxvRz5LR Vf42839R2MR41SSo+lNCUNCwqfGlHVDgAduhQ+9tTJuIGgPpDVt1wMmjIw3IAGHPkvy0 T2kxbifY9HGB2SR2iMVcy1beZKWHgsD28TZcl5zJ7LcuYfMZmXpQsvY8PkUosEZG+1T+ CFmxAMrGVV8U38G/ICPARHyBgqKkwHGJZdpFSxNPiJLeeHrAbj9qK72eNK74DZxgbhNg RPv5xLUYuKSCKMzTSU0fuyAbTrTpJ7xY0hHPAQLXaRnngKbzFmwownE9Elx4mGuNki2y N/Yw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=d5TInvlr; 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 s2si9671120pgr.285.2019.02.02.01.41.53; Sat, 02 Feb 2019 01:41: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=d5TInvlr; 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 S1727876AbfBBJlv (ORCPT + 31 others); Sat, 2 Feb 2019 04:41:51 -0500 Received: from mail-ed1-f65.google.com ([209.85.208.65]:38737 "EHLO mail-ed1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727733AbfBBJln (ORCPT ); Sat, 2 Feb 2019 04:41:43 -0500 Received: by mail-ed1-f65.google.com with SMTP id h50so7470982ede.5 for ; Sat, 02 Feb 2019 01:41:42 -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=UG8rnIGuuYCyn1MgwH5GL70RHIkJGZksj7iIE3TwONc=; b=d5TInvlr3vrCCCTqz+QDeLqjtprI+ae3HlnrRs/HIONGa8vKX5qRi0zJKVT0ef/Bu1 d1SptAbgHOc6fqPtTWbgc+Y47+sTeEU4zDOpVFwsTToZaQZUAIkxLSuQG05bd4eavPYI S9An9oaksIlSlmSdyn923Ov+JNGWVq9DhcxHQ= 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=UG8rnIGuuYCyn1MgwH5GL70RHIkJGZksj7iIE3TwONc=; b=YxovqAVBaicaO157edxXfDC/MP53Imlw50kqgy/resosHHWiPoQeNr4Alo42Idnqpi QplztZCRL9wzo/o9v/WyOUyN4BdW/vg/npgTCynqQWaMky5sCMWME8nTxv4BIEDxMLiE m1rxgeflPUgvz6gox+sPaKlJg3nbyhDBLqvjkv6GZOKsnbE/xIGXO60BMDkdRCvbl3QP 27r6P4UlMIqH0zwGv46eylHK4JJ/c9Err3b9lGRdVvD8h0sx7cwpv+HDgTkAgluBxPJQ SCtlFfC/kuIDjCatXwVCzfkM9yWg06Cjmg316xONicE00Ur+C33X7SQW+YzzhpsGDOvG pbQQ== X-Gm-Message-State: AJcUukfG8gbd5exI6+9SGCkJVltISD+tJsba7UcNp64hNnyafT6TyU5s crDfCdxcFTfd/0c60IwmAV3M6w== X-Received: by 2002:a17:906:5e43:: with SMTP id b3mr38434394eju.200.1549100502004; Sat, 02 Feb 2019 01:41:42 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:40 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 10/10] acpi: bgrt: parse BGRT to obtain BMP address before it gets clobbered Date: Sat, 2 Feb 2019 10:41:19 +0100 Message-Id: <20190202094119.13230-11-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The bitmap left in the framebuffer by the firmware is described by an ACPI table called "BGRT", which describes the size, pixel format and the address of a BMP image in memory. While the BGRT ACPI table is guaranteed to reside in a "ACPI reclaim" memory region, which is never touched by Linux. The BMP image, however, typically resides in EFI Boot Services Memory, which may have been overwritten by the time the BGRT discovery routine runs. So instead, drop the handling from the ACPI init code, and call the BGRT parsing code immediately after going over the EFI configuration table array, at which time no memory has been touched yet except for the .data/.bss regions covered by the static kernel image. Unfortunately, this involves a non-trivial amount of ACPI entry point and root table parsing, but we cannot rely on the normal ACPI infrastructure yet this early in the boot. Also note that we cannot take the 'acpi_disabled' global variable into account, since it may not have assumed the correct value yet (on arm64, the default value is '1' which is overridden to '0' if no DT description has been made available by the firmware) Cc: Peter Jones Signed-off-by: Ard Biesheuvel --- arch/arm64/kernel/acpi.c | 2 - arch/x86/kernel/acpi/boot.c | 2 - drivers/acpi/bgrt.c | 6 --- drivers/firmware/efi/efi-bgrt.c | 84 ++++++++++++++++++++++++++++++--- drivers/firmware/efi/efi.c | 13 +++++ include/linux/efi-bgrt.h | 4 +- 6 files changed, 92 insertions(+), 19 deletions(-) -- 2.17.1 diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index 44e3c351e1ea..7429a811f76d 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -230,8 +230,6 @@ void __init acpi_boot_table_init(void) early_init_dt_scan_chosen_stdout(); } else { acpi_parse_spcr(earlycon_acpi_spcr_enable, true); - if (IS_ENABLED(CONFIG_ACPI_BGRT)) - acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); } } diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 2624de16cd7a..2d3535b62752 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1633,8 +1633,6 @@ int __init acpi_boot_init(void) acpi_process_madt(); acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); - if (IS_ENABLED(CONFIG_ACPI_BGRT)) - acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); if (!acpi_noirq) x86_init.pci.init = pci_acpi_init; diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c index 75af78361ce5..048413e06898 100644 --- a/drivers/acpi/bgrt.c +++ b/drivers/acpi/bgrt.c @@ -81,12 +81,6 @@ static const struct attribute_group bgrt_attribute_group = { .bin_attrs = bgrt_bin_attributes, }; -int __init acpi_parse_bgrt(struct acpi_table_header *table) -{ - efi_bgrt_init(table); - return 0; -} - static int __init bgrt_init(void) { int ret; diff --git a/drivers/firmware/efi/efi-bgrt.c b/drivers/firmware/efi/efi-bgrt.c index a2384184a7de..9c50d453b143 100644 --- a/drivers/firmware/efi/efi-bgrt.c +++ b/drivers/firmware/efi/efi-bgrt.c @@ -24,24 +24,94 @@ struct bmp_header { u32 size; } __packed; -void __init efi_bgrt_init(struct acpi_table_header *table) +void __init efi_bgrt_init(unsigned long rsdp_phys) { void *image; struct bmp_header bmp_header; struct acpi_table_bgrt *bgrt = &bgrt_tab; + struct acpi_table_bgrt *table = NULL; + struct acpi_table_rsdp *rsdp; + struct acpi_table_header *hdr; + u64 xsdt_phys = 0; + u32 rsdt_phys = 0; + size_t len; - if (acpi_disabled) + if (!efi_enabled(EFI_MEMMAP)) return; - if (!efi_enabled(EFI_MEMMAP)) + /* map the root pointer table to find the xsdt/rsdt values */ + rsdp = early_memremap_ro(rsdp_phys, sizeof(*rsdp)); + if (rsdp) { + if (ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) { + xsdt_phys = rsdp->xsdt_physical_address; + rsdt_phys = rsdp->rsdt_physical_address; + } + early_memunmap(rsdp, sizeof(*rsdp)); + } + + if (WARN_ON(!xsdt_phys && !rsdt_phys)) return; - if (table->length < sizeof(bgrt_tab)) { - pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n", - table->length, sizeof(bgrt_tab)); + /* obtain the length of whichever table we will be using */ + hdr = early_memremap_ro(xsdt_phys ?: rsdt_phys, sizeof(*hdr)); + if (WARN_ON(!hdr)) + return; + len = hdr->length; + early_memunmap(hdr, sizeof(*hdr)); + + /* remap with the correct length */ + hdr = early_memremap_ro(xsdt_phys ?: rsdt_phys, len); + if (WARN_ON(!hdr)) + return; + + if (xsdt_phys) { + struct acpi_table_xsdt *xsdt = (void *)hdr; + int i; + + for (i = 0; i < (len - sizeof(*hdr)) / sizeof(u64); i++) { + table = early_memremap_ro(xsdt->table_offset_entry[i], + sizeof(*table)); + if (WARN_ON(!table)) + break; + + if (ACPI_COMPARE_NAME(table->header.signature, + ACPI_SIG_BGRT)) + break; + early_memunmap(table, sizeof(*table)); + table = NULL; + } + } else if (rsdt_phys) { + struct acpi_table_rsdt *rsdt = (void *)hdr; + int i; + + for (i = 0; i < (len - sizeof(*hdr)) / sizeof(u32); i++) { + table = early_memremap_ro(rsdt->table_offset_entry[i], + sizeof(*table)); + if (WARN_ON(!table)) + break; + + if (ACPI_COMPARE_NAME(table->header.signature, + ACPI_SIG_BGRT)) + break; + early_memunmap(table, sizeof(*table)); + table = NULL; + } + } + early_memunmap(hdr, len); + + if (!table) return; + + len = table->header.length; + memcpy(bgrt, table, min(len, sizeof(bgrt_tab))); + early_memunmap(table, sizeof(*table)); + + if (len < sizeof(bgrt_tab)) { + pr_notice("Ignoring BGRT: invalid length %zu (expected %zu)\n", + len, sizeof(bgrt_tab)); + goto out; } - *bgrt = *(struct acpi_table_bgrt *)table; + if (bgrt->version != 1) { pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n", bgrt->version); diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 4c46ff6f2242..e5ef5c0eacc1 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -592,6 +593,18 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, early_memunmap(tbl, sizeof(*tbl)); } + + /* + * We need to parse the BGRT table (which is an ACPI table not a UEFI + * configuration table) by hand and figure out where the bitmap it + * describes lives in memory so we can reserve it early on. Otherwise, + * it may be clobbered by the time we get to it during the ordinary ACPI + * table init sequence. + */ + if (IS_ENABLED(CONFIG_ACPI_BGRT) && + efi.acpi20 != EFI_INVALID_TABLE_ADDR) + efi_bgrt_init(efi.acpi20); + return 0; } diff --git a/include/linux/efi-bgrt.h b/include/linux/efi-bgrt.h index e6cd51005633..528ea62d99ec 100644 --- a/include/linux/efi-bgrt.h +++ b/include/linux/efi-bgrt.h @@ -6,7 +6,7 @@ #ifdef CONFIG_ACPI_BGRT -void efi_bgrt_init(struct acpi_table_header *table); +void efi_bgrt_init(unsigned long rsdp_phys); int __init acpi_parse_bgrt(struct acpi_table_header *table); /* The BGRT data itself; only valid if bgrt_image != NULL. */ @@ -15,7 +15,7 @@ extern struct acpi_table_bgrt bgrt_tab; #else /* !CONFIG_ACPI_BGRT */ -static inline void efi_bgrt_init(struct acpi_table_header *table) {} +static inline void efi_bgrt_init(unsigned long rsdp_phys) {} static inline int __init acpi_parse_bgrt(struct acpi_table_header *table) { return 0;