From patchwork Wed Feb 19 15:24:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 11391671 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9B9FB138D for ; Wed, 19 Feb 2020 15:25:12 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6F36924654 for ; Wed, 19 Feb 2020 15:25:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="PX/0cA8c"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="1jVDtel0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6F36924654 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=oeBma11Swamo+UXFA2UJ8O6PXvbnzO0SAvFsgH3GUxk=; b=PX/0cA8cm6xV7YsgnqOMnnDg9h JCCwpWNx/rMeTyC/7pt9SE4A+phbI9pxaLvreuCduiv8r8Hgi9GJngoxwL5wbV1RpfQQxb1364H/a xMTdQeAfMFXj4B8zW2P9ZSE06py9IGWmDwSvC4wLVPsVPpSP+ufU9SJ/MIQK6CyoKn3CkaQG9fuCG SFEVOzXFI4z350LGCK/qxx+C0ePRPezgO7bDCTyxdULK9W0UBPtXGxVm7cad5mIEZ4Nxnv8rB29F3 ehgc0dAzs09NxhNty4GYXc9174EwVT67+y4L+eWXoGSLqSJ3BxXUvRdglKZOeI5kgHy38aikJ5Ba2 AkE7K4Bg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4RDg-0006Uk-Tk; Wed, 19 Feb 2020 15:25:00 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4RDU-0006KL-1M for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2020 15:24:49 +0000 Received: from cam-smtp0.cambridge.arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 24D6D24670; Wed, 19 Feb 2020 15:24:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1582125887; bh=p6quxa+3E1BfuMVMn0x0SwwnZ3l7CEP0hQbWAuv0qCk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1jVDtel0N9HhxINANEq48Icp6Exc9PIYAypzVzF6G//GZTvaBBZVRZwl2DWtNYCF0 aAqhznkAtkxMAmooWgMec5bpAlLzRrnXFHPicbgRRigANfthD3bXTFTKUrXaYPG3M2 17sT8GJul4EXa08RmFfx3JNdMjfHf/D2wRXLbWjY= From: Ard Biesheuvel To: linux-efi@vger.kernel.org Subject: [PATCH 1/3] efi/arm: move FDT param discovery code out of efi.c Date: Wed, 19 Feb 2020 16:24:38 +0100 Message-Id: <20200219152440.11561-2-ardb@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200219152440.11561-1-ardb@kernel.org> References: <20200219152440.11561-1-ardb@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200219_072448_126310_2D6124FA X-CRM114-Status: GOOD ( 19.48 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: atish.patra@wdc.com, leif@nuviainc.com, Ard Biesheuvel , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org On ARM systems, we discover the UEFI system table address and memory map address from the /chosen node in the device tree, or in the Xen case, from a similar node under /hypervisor. Before making some functional changes to that code, move it into its own file that only gets built if CONFIG_EFI_PARAMS_FROM_FDT=y. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/efi.c | 135 ------------------- drivers/firmware/efi/fdtparams.c | 142 ++++++++++++++++++++ 3 files changed, 143 insertions(+), 135 deletions(-) diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 554d795270d9..3c5a9690de04 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -13,6 +13,7 @@ KASAN_SANITIZE_runtime-wrappers.o := n obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o tpm.o obj-$(CONFIG_EFI) += capsule.o memmap.o +obj-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdtparams.o obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_ESRT) += esrt.o obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 55570ed751e8..69a585106d30 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -656,140 +655,6 @@ void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr, vendor); } -#ifdef CONFIG_EFI_PARAMS_FROM_FDT - -#define UEFI_PARAM(name, prop, field) \ - { \ - { name }, \ - { prop }, \ - offsetof(struct efi_fdt_params, field), \ - sizeof_field(struct efi_fdt_params, field) \ - } - -struct params { - const char name[32]; - const char propname[32]; - int offset; - int size; -}; - -static __initdata struct params fdt_params[] = { - UEFI_PARAM("System Table", "linux,uefi-system-table", system_table), - UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap), - UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size), - UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size), - UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) -}; - -static __initdata struct params xen_fdt_params[] = { - UEFI_PARAM("System Table", "xen,uefi-system-table", system_table), - UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap), - UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size), - UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size), - UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver) -}; - -#define EFI_FDT_PARAMS_SIZE ARRAY_SIZE(fdt_params) - -static __initdata struct { - const char *uname; - const char *subnode; - struct params *params; -} dt_params[] = { - { "hypervisor", "uefi", xen_fdt_params }, - { "chosen", NULL, fdt_params }, -}; - -struct param_info { - int found; - void *params; - const char *missing; -}; - -static int __init __find_uefi_params(unsigned long node, - struct param_info *info, - struct params *params) -{ - const void *prop; - void *dest; - u64 val; - int i, len; - - for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) { - prop = of_get_flat_dt_prop(node, params[i].propname, &len); - if (!prop) { - info->missing = params[i].name; - return 0; - } - - dest = info->params + params[i].offset; - info->found++; - - val = of_read_number(prop, len / sizeof(u32)); - - if (params[i].size == sizeof(u32)) - *(u32 *)dest = val; - else - *(u64 *)dest = val; - - if (efi_enabled(EFI_DBG)) - pr_info(" %s: 0x%0*llx\n", params[i].name, - params[i].size * 2, val); - } - - return 1; -} - -static int __init fdt_find_uefi_params(unsigned long node, const char *uname, - int depth, void *data) -{ - struct param_info *info = data; - int i; - - for (i = 0; i < ARRAY_SIZE(dt_params); i++) { - const char *subnode = dt_params[i].subnode; - - if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) { - info->missing = dt_params[i].params[0].name; - continue; - } - - if (subnode) { - int err = of_get_flat_dt_subnode_by_name(node, subnode); - - if (err < 0) - return 0; - - node = err; - } - - return __find_uefi_params(node, info, dt_params[i].params); - } - - return 0; -} - -int __init efi_get_fdt_params(struct efi_fdt_params *params) -{ - struct param_info info; - int ret; - - pr_info("Getting EFI parameters from FDT:\n"); - - info.found = 0; - info.params = params; - - ret = of_scan_flat_dt(fdt_find_uefi_params, &info); - if (!info.found) - pr_info("UEFI not found.\n"); - else if (!ret) - pr_err("Can't find '%s' in device tree!\n", - info.missing); - - return ret; -} -#endif /* CONFIG_EFI_PARAMS_FROM_FDT */ - static __initdata char memory_type_name[][20] = { "Reserved", "Loader Code", diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c new file mode 100644 index 000000000000..3de343faffc6 --- /dev/null +++ b/drivers/firmware/efi/fdtparams.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define pr_fmt(fmt) "efi: " fmt + +#include +#include +#include +#include +#include + +#include + +#define UEFI_PARAM(name, prop, field) \ + { \ + { name }, \ + { prop }, \ + offsetof(struct efi_fdt_params, field), \ + sizeof_field(struct efi_fdt_params, field) \ + } + +struct params { + const char name[32]; + const char propname[32]; + int offset; + int size; +}; + +static __initdata struct params fdt_params[] = { + UEFI_PARAM("System Table", "linux,uefi-system-table", system_table), + UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap), + UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size), + UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size), + UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) +}; + +static __initdata struct params xen_fdt_params[] = { + UEFI_PARAM("System Table", "xen,uefi-system-table", system_table), + UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap), + UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size), + UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size), + UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver) +}; + +#define EFI_FDT_PARAMS_SIZE ARRAY_SIZE(fdt_params) + +static __initdata struct { + const char *uname; + const char *subnode; + struct params *params; +} dt_params[] = { + { "hypervisor", "uefi", xen_fdt_params }, + { "chosen", NULL, fdt_params }, +}; + +struct param_info { + int found; + void *params; + const char *missing; +}; + +static int __init __find_uefi_params(unsigned long node, + struct param_info *info, + struct params *params) +{ + const void *prop; + void *dest; + u64 val; + int i, len; + + for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) { + prop = of_get_flat_dt_prop(node, params[i].propname, &len); + if (!prop) { + info->missing = params[i].name; + return 0; + } + + dest = info->params + params[i].offset; + info->found++; + + val = of_read_number(prop, len / sizeof(u32)); + + if (params[i].size == sizeof(u32)) + *(u32 *)dest = val; + else + *(u64 *)dest = val; + + if (efi_enabled(EFI_DBG)) + pr_info(" %s: 0x%0*llx\n", params[i].name, + params[i].size * 2, val); + } + + return 1; +} + +static int __init fdt_find_uefi_params(unsigned long node, const char *uname, + int depth, void *data) +{ + struct param_info *info = data; + int i; + + for (i = 0; i < ARRAY_SIZE(dt_params); i++) { + const char *subnode = dt_params[i].subnode; + + if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) { + info->missing = dt_params[i].params[0].name; + continue; + } + + if (subnode) { + int err = of_get_flat_dt_subnode_by_name(node, subnode); + + if (err < 0) + return 0; + + node = err; + } + + return __find_uefi_params(node, info, dt_params[i].params); + } + + return 0; +} + +int __init efi_get_fdt_params(struct efi_fdt_params *params) +{ + struct param_info info; + int ret; + + pr_info("Getting EFI parameters from FDT:\n"); + + info.found = 0; + info.params = params; + + ret = of_scan_flat_dt(fdt_find_uefi_params, &info); + if (!info.found) + pr_info("UEFI not found.\n"); + else if (!ret) + pr_err("Can't find '%s' in device tree!\n", + info.missing); + + return ret; +} From patchwork Wed Feb 19 15:24:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 11391673 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6F95C138D for ; Wed, 19 Feb 2020 15:25:24 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4E10C24654 for ; Wed, 19 Feb 2020 15:25:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="nr2SG5IR"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="VtSsGXif" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4E10C24654 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=JEONj14dkAypTAxxjPGNw4UKHgspLbDUpy6JFsL56iI=; b=nr2SG5IRJjLFiOrToHwe17nMsX ddtik9H4kTM6EVIeAMWb646k3UTyMBDy7C36KKKkf0PamFKnk3rrxhOEWXXLAXRtEhXYZphLNQMMT 9B1ac2tn89B2GRLK4TPtkjOVqYOooHm3IdTPzZx1nyNbsgYyW/zr/KNnzaedhkFFDD/ZSULwytmJn qaWtH8EhB/B9gx3/dyVVrk0oKEcqDa2xibYFsEAvezR+9NclVthKTHsedCzT1YrZdJbgWVhLewLgf whRvRR1LpJZqVujlN2rpQi8ifTdBgnnFv38+zs+ir9UtNvV30d8uBO5GucMfxHj2/+YD7T2KGgka/ qB5CK33g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4RDz-0007vn-6P; Wed, 19 Feb 2020 15:25:19 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4RDW-0006LW-7M for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2020 15:24:51 +0000 Received: from cam-smtp0.cambridge.arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 44E4E24654; Wed, 19 Feb 2020 15:24:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1582125889; bh=PDvat8kqeig3BTT+VeV1np0/DyvF6xBQeL7xe9NzH90=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VtSsGXifZA5RnZW/dPBhY07N+PB9khG0s6OLmhnznF/9pY/EO70fxGiclxOuG/8Xm nFjfpnZrM+5BWB0EULVD24qOOX6sgCcRWlG6ktv3fwoftsvZkG7TY8iM9377H4Y6AJ Nnp01MRNoJKenob3pOBPLL2i/161bFa/c6sLgSm4= From: Ard Biesheuvel To: linux-efi@vger.kernel.org Subject: [PATCH 2/3] efi/arm: move FDT specific definitions into fdtparams.c Date: Wed, 19 Feb 2020 16:24:39 +0100 Message-Id: <20200219152440.11561-3-ardb@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200219152440.11561-1-ardb@kernel.org> References: <20200219152440.11561-1-ardb@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200219_072450_348573_BE91886E X-CRM114-Status: GOOD ( 15.89 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: atish.patra@wdc.com, leif@nuviainc.com, Ard Biesheuvel , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Push the FDT params specific types and definition into fdtparams.c, and instead, pass a reference to the memory map data structure and populate it directly, and return the system table address as the return value. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/arm-init.c | 17 ++++------- drivers/firmware/efi/fdtparams.c | 30 +++++++++++++++----- include/linux/efi.h | 10 +------ 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 76bf5b22e49e..2791a8048f30 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -205,17 +205,13 @@ static __init void reserve_regions(void) void __init efi_init(void) { struct efi_memory_map_data data; - struct efi_fdt_params params; + u64 efi_system_table; /* Grab UEFI information placed in FDT by stub */ - if (!efi_get_fdt_params(¶ms)) + efi_system_table = efi_get_fdt_params(&data); + if (!efi_system_table) return; - data.desc_version = params.desc_ver; - data.desc_size = params.desc_size; - data.size = params.mmap_size; - data.phys_map = params.mmap; - if (efi_memmap_init_early(&data) < 0) { /* * If we are booting via UEFI, the UEFI memory map is the only @@ -229,7 +225,7 @@ void __init efi_init(void) "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", efi.memmap.desc_version); - if (uefi_init(params.system_table) < 0) { + if (uefi_init(efi_system_table) < 0) { efi_memmap_unmap(); return; } @@ -237,9 +233,8 @@ void __init efi_init(void) reserve_regions(); efi_esrt_init(); - memblock_reserve(params.mmap & PAGE_MASK, - PAGE_ALIGN(params.mmap_size + - (params.mmap & ~PAGE_MASK))); + memblock_reserve(data.phys_map & PAGE_MASK, + PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); init_screen_info(); diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c index 3de343faffc6..7a384b307c56 100644 --- a/drivers/firmware/efi/fdtparams.c +++ b/drivers/firmware/efi/fdtparams.c @@ -18,6 +18,14 @@ sizeof_field(struct efi_fdt_params, field) \ } +struct efi_fdt_params { + u64 system_table; + u64 mmap; + u32 mmap_size; + u32 desc_size; + u32 desc_ver; +}; + struct params { const char name[32]; const char propname[32]; @@ -121,22 +129,30 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname, return 0; } -int __init efi_get_fdt_params(struct efi_fdt_params *params) +u64 __init efi_get_fdt_params(struct efi_memory_map_data *memmap) { + struct efi_fdt_params params; struct param_info info; int ret; pr_info("Getting EFI parameters from FDT:\n"); info.found = 0; - info.params = params; + info.params = ¶ms; ret = of_scan_flat_dt(fdt_find_uefi_params, &info); - if (!info.found) + if (!info.found) { pr_info("UEFI not found.\n"); - else if (!ret) - pr_err("Can't find '%s' in device tree!\n", - info.missing); + return 0; + } else if (!ret) { + pr_err("Can't find '%s' in device tree!\n", info.missing); + return 0; + } + + memmap->desc_version = params.desc_ver; + memmap->desc_size = params.desc_size; + memmap->size = params.mmap_size; + memmap->phys_map = params.mmap; - return ret; + return params.system_table; } diff --git a/include/linux/efi.h b/include/linux/efi.h index a36bbd20e3ac..2ab33d5d6ca5 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -478,14 +478,6 @@ struct efi_mem_range { u64 attribute; }; -struct efi_fdt_params { - u64 system_table; - u64 mmap; - u32 mmap_size; - u32 desc_size; - u32 desc_ver; -}; - typedef struct { u32 version; u32 length; @@ -661,7 +653,7 @@ extern void efi_mem_reserve(phys_addr_t addr, u64 size); extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size); extern void efi_initialize_iomem_resources(struct resource *code_resource, struct resource *data_resource, struct resource *bss_resource); -extern int efi_get_fdt_params(struct efi_fdt_params *params); +extern u64 efi_get_fdt_params(struct efi_memory_map_data *data); extern struct kobject *efi_kobj; extern int efi_reboot_quirk_mode; From patchwork Wed Feb 19 15:24:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 11391675 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F513139A for ; Wed, 19 Feb 2020 15:25:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7647024654 for ; Wed, 19 Feb 2020 15:25:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="hEIfOw8N"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="rmvh1uFH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7647024654 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=0k8au1otu9K2zbzQJ+jkTLfGvdWnaytC7mqyJdduSWY=; b=hEIfOw8N4BsjbgTv95jKjJtkeT 30sQ+3gRvf2fAOOJkpHltjAyAQUH893eX3puKe8uwJTigjTY5MV2QhJOsgXWiEsUv3C/5QKhXEYPm KPqGifLr33szvLRgQkLDeeeSa2Mntdaq4y37Q5FVA46dggZ14qpFfsy96vb/l68gtQ+1xo5mSpNZ9 9FLz2NdW0SR6DBh+m3pNUIRXuxkAtpM/tV4YrwtxqVjhrpIFH0cMmHFwY3ncgvoK5ZWk5Zdbxk6uy jAE2Ykw85Wk8gIsUDdrL8z1IYjbny/OOc8v4pb7iM0Sy792z3QU6hRiOc7f5UcO1wLo0ZDFGezpMQ cDdAs2XA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4RED-0008C2-UW; Wed, 19 Feb 2020 15:25:34 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4RDY-0006NA-5T for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2020 15:24:54 +0000 Received: from cam-smtp0.cambridge.arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 43EC224671; Wed, 19 Feb 2020 15:24:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1582125891; bh=2Yifru4+OPwrLC2fBvFPYWlusQrWYJhTcoUViaqei20=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rmvh1uFHrKb/9y86IWBe2/WFT5fhsXXm1bR0kRnF7Wjcd2LxxzQHUTfJlA4Q4dbPg kXg8vS8qGAyC+AY1UDBbz646bLwsc7kxVxhg0/6LxA653TJhQtLz6iLxIYnKklNSbL UViUXPRmvpVg8MAv38IcDRaJYhbjCWwqaL9kANBo= From: Ard Biesheuvel To: linux-efi@vger.kernel.org Subject: [PATCH 3/3] efi/arm: rewrite FDT param discovery routines Date: Wed, 19 Feb 2020 16:24:40 +0100 Message-Id: <20200219152440.11561-4-ardb@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200219152440.11561-1-ardb@kernel.org> References: <20200219152440.11561-1-ardb@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200219_072452_253770_158B1E0B X-CRM114-Status: GOOD ( 17.03 ) X-Spam-Score: -5.2 (-----) X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: Content analysis details: (-5.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [198.145.29.99 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: atish.patra@wdc.com, leif@nuviainc.com, Ard Biesheuvel , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The efi_get_fdt_params() routine uses the early OF device tree traversal helpers, that iterate over each node in the DT and invoke a caller provided callback that can inspect the node's contents and look for the required data. This requires a special param struct to be passed around, with pointers into param enumeration structs that contain (and duplicate) property names and offsets into yet another struct that carries the collected data. Since we know the data we look for is either under /hypervisor/uefi or under /chosen, it is much simpler to use the libfdt routines directly, and try to grab a reference to either node directly, and read each property in sequence. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/fdtparams.c | 203 ++++++++------------ 1 file changed, 85 insertions(+), 118 deletions(-) diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c index 7a384b307c56..23af4062e913 100644 --- a/drivers/firmware/efi/fdtparams.c +++ b/drivers/firmware/efi/fdtparams.c @@ -5,154 +5,121 @@ #include #include #include -#include +#include #include -#include +#include -#define UEFI_PARAM(name, prop, field) \ - { \ - { name }, \ - { prop }, \ - offsetof(struct efi_fdt_params, field), \ - sizeof_field(struct efi_fdt_params, field) \ - } - -struct efi_fdt_params { - u64 system_table; - u64 mmap; - u32 mmap_size; - u32 desc_size; - u32 desc_ver; -}; - -struct params { - const char name[32]; - const char propname[32]; - int offset; - int size; +enum { + SYSTAB, + MMBASE, + MMSIZE, + DCSIZE, + DCVERS, }; -static __initdata struct params fdt_params[] = { - UEFI_PARAM("System Table", "linux,uefi-system-table", system_table), - UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap), - UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size), - UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size), - UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) +static __initconst const char name[][22] = { + [SYSTAB] = "System Table ", + [MMBASE] = "MemMap Address ", + [MMSIZE] = "MemMap Size ", + [DCSIZE] = "MemMap Desc. Size ", + [DCVERS] = "MemMap Desc. Version ", }; -static __initdata struct params xen_fdt_params[] = { - UEFI_PARAM("System Table", "xen,uefi-system-table", system_table), - UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap), - UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size), - UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size), - UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver) -}; - -#define EFI_FDT_PARAMS_SIZE ARRAY_SIZE(fdt_params) - -static __initdata struct { - const char *uname; - const char *subnode; - struct params *params; +static __initconst const struct { + const char path[17]; + const char params[5][26]; } dt_params[] = { - { "hypervisor", "uefi", xen_fdt_params }, - { "chosen", NULL, fdt_params }, -}; - -struct param_info { - int found; - void *params; - const char *missing; +#ifdef CONFIG_XEN + { + "/hypervisor/uefi", + { + [SYSTAB] = "xen,uefi-system-table", + [MMBASE] = "xen,uefi-mmap-start", + [MMSIZE] = "xen,uefi-mmap-size", + [DCSIZE] = "xen,uefi-mmap-desc-size", + [DCVERS] = "xen,uefi-mmap-desc-ver", + } + }, +#endif + { + "/chosen", + { + [SYSTAB] = "linux,uefi-system-table", + [MMBASE] = "linux,uefi-mmap-start", + [MMSIZE] = "linux,uefi-mmap-size", + [DCSIZE] = "linux,uefi-mmap-desc-size", + [DCVERS] = "linux,uefi-mmap-desc-ver", + } + } }; -static int __init __find_uefi_params(unsigned long node, - struct param_info *info, - struct params *params) +static int __init efi_get_fdt_prop(const void *fdt, int node, int dtp, int pp, + void *var, int size) { const void *prop; - void *dest; + int len; u64 val; - int i, len; - for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) { - prop = of_get_flat_dt_prop(node, params[i].propname, &len); - if (!prop) { - info->missing = params[i].name; - return 0; - } - - dest = info->params + params[i].offset; - info->found++; + prop = fdt_getprop(fdt, node, dt_params[dtp].params[pp], &len); + if (!prop) { + pr_err("Can't find property '%s' in device tree!\n", + dt_params[dtp].params[pp]); + return 1; + } - val = of_read_number(prop, len / sizeof(u32)); + val = (len == 4) ? (u64)be32_to_cpup(prop) : get_unaligned_be64(prop); - if (params[i].size == sizeof(u32)) - *(u32 *)dest = val; - else - *(u64 *)dest = val; + if (size == 8) + *(u64 *)var = val; + else + *(u32 *)var = (val <= U32_MAX) ? val : U32_MAX; // saturate - if (efi_enabled(EFI_DBG)) - pr_info(" %s: 0x%0*llx\n", params[i].name, - params[i].size * 2, val); - } + if (efi_enabled(EFI_DBG)) + pr_info(" %s: 0x%0*llx\n", name[pp], size * 2, val); - return 1; + return 0; } -static int __init fdt_find_uefi_params(unsigned long node, const char *uname, - int depth, void *data) +u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) { - struct param_info *info = data; + const void *fdt = initial_boot_params; + unsigned long systab; + struct { + void *var; + int size; + } target[] = { + [SYSTAB] = { &systab, sizeof(systab) }, + [MMBASE] = { &mm->phys_map, sizeof(mm->phys_map) }, + [MMSIZE] = { &mm->size, sizeof(mm->size) }, + [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, + [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, + }; int i; + BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); + BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(dt_params[0].params)); + for (i = 0; i < ARRAY_SIZE(dt_params); i++) { - const char *subnode = dt_params[i].subnode; + int node; + int j; - if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) { - info->missing = dt_params[i].params[0].name; + node = fdt_path_offset(fdt, dt_params[i].path); + if (node < 0) continue; - } - if (subnode) { - int err = of_get_flat_dt_subnode_by_name(node, subnode); + if (efi_enabled(EFI_DBG)) + pr_info("Getting UEFI parameters from %s in DT:\n", + dt_params[i].path); - if (err < 0) + for (j = 0; j < ARRAY_SIZE(target); j++) { + if (efi_get_fdt_prop(fdt, node, i, j, target[j].var, + target[j].size)) { return 0; - - node = err; + } } - - return __find_uefi_params(node, info, dt_params[i].params); + return systab; } - + pr_info("UEFI not found.\n"); return 0; } - -u64 __init efi_get_fdt_params(struct efi_memory_map_data *memmap) -{ - struct efi_fdt_params params; - struct param_info info; - int ret; - - pr_info("Getting EFI parameters from FDT:\n"); - - info.found = 0; - info.params = ¶ms; - - ret = of_scan_flat_dt(fdt_find_uefi_params, &info); - if (!info.found) { - pr_info("UEFI not found.\n"); - return 0; - } else if (!ret) { - pr_err("Can't find '%s' in device tree!\n", info.missing); - return 0; - } - - memmap->desc_version = params.desc_ver; - memmap->desc_size = params.desc_size; - memmap->size = params.mmap_size; - memmap->phys_map = params.mmap; - - return params.system_table; -}