From patchwork Thu Sep 17 22:37:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11783663 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 6F9A5112E for ; Thu, 17 Sep 2020 22:37:50 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 360922087D for ; Thu, 17 Sep 2020 22:37:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="T3BxU6T8"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="X7/Pfuyk" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 360922087D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=P21K4yyaNkh24BmgRqN/kfnLUOvrBIG1+Iz4ZI5tfho=; b=T3BxU6T8lS0Mgld+U8iyslLwq KBdXK2SQAid2ceK/B4J1QrVWefGBTUjOvsLutInjpFGZJyu5CZRaRjoil1fpUTZPQyfTh7/Y00kpL 67skFGroS3fltOWf8U0vAIP3emCxYFfSm+Iw2wNLMt4129spjXszIapagNhUsd7nAcuIM9UyxmN7K GBwjrau0EzDHosZPlrP0aj5rb3PoBgNSpO/BOrYf0tGs5aCLHzGiEl2C38x9kTMeA90Bh4lCuQ5ER CazUh0VY5uEMtAYcXWwnhPKu+phG2nTxiXlNSyS3TWKd37tHIgEFB3uu/Yz5+o3mO9peZGrQ3sZne xFNr2sxFw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XA-0005iJ-Ui; Thu, 17 Sep 2020 22:37:44 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2X6-0005fc-Qs for linux-riscv@lists.infradead.org; Thu, 17 Sep 2020 22:37:41 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1600382260; x=1631918260; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cF20uOFMMd9tTFHAC0Pjs+HW70yT62Ub+JgCsnEO3VM=; b=X7/Pfuykaq+5gZC4Y/jHPC9CeP00JOs6AkzpyvpJqPeDu7822C2TiSoN deJsccRhlYFtQua0S0rf/qAiySH6cGwo42MQP2iTwJ6S8V8LZ31zA3+o5 JEJnEzRa/yCoOKVA9jfN9DboF8y+pwfM991O5xC1Ym0rN2fjtu9qmrlhF n/dIweRBLGZyQeWprf3GY5AZUe6Pk2yVGW0+xGZa2K4aOrLvCgUxHUlNT PzFfVcDBh1qwe0Fc7FF6xwdwmYuWCB3iEfzK17qh6HZh6OnuY12mxP3G9 6nmzEqihr6FbVinKRtAs1ZYbO52ExHRJs2lVV2Ps5j2ZrZoxc2HUA+QTp A==; IronPort-SDR: FDKKiLh2HSnn0XZyNkd/8It+DbpYlGnd9ML7BEPsEMQepQ6a0mv3rZp2byxg4fwffksI3emsR1 FLJM9Stk+rLa34oPV/UKuaIteQGtnj5cRAprp9Bj60FzdJPYRy44rkdH6CwumcEQadLtecSqvL 13h8HTYsCP6X8CoEkAFUoQBsz1+QcQFYA38FcGrKEDZuyy6lMFlYlfCEoHlfsCW2MlWNcAPDmR qD/BmYXXn9x9TrocDbNrQQj5xBALTkHyK4o0wt2klA0nkytiMuya2FGLRnQlyvmuAoDOho2f1q 4Fs= X-IronPort-AV: E=Sophos;i="5.77,272,1596470400"; d="scan'208";a="257336252" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2020 06:37:37 +0800 IronPort-SDR: 272UB729zhFIIXhoxvDaQlHxaLWgr1khCbXE+CMmj87Eqt7rzVTXVq22qQYhFjnkoeKjoHfVgh U/i+l4yIl5VQ== Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2020 15:23:51 -0700 IronPort-SDR: MUPJqvCz1YSPdNZJgpZNSoQ6FVJT1OCgAetfE0XPtatLNB3mUXEOsJVh1lXfoCkcbNBcz46AxM 4WUBWHiMBg7g== WDCIronportException: Internal Received: from use204338.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.39]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Sep 2020 15:37:37 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v8 1/7] RISC-V: Move DT mapping outof fixmap Date: Thu, 17 Sep 2020 15:37:10 -0700 Message-Id: <20200917223716.2300238-2-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200917223716.2300238-1-atish.patra@wdc.com> References: <20200917223716.2300238-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_183741_006838_381696F3 X-CRM114-Status: GOOD ( 19.68 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-efi@vger.kernel.org, Palmer Dabbelt , Atish Patra , Arvind Sankar , Albert Ou , Alistair Francis , Zong Li , linux-riscv@lists.infradead.org, Ingo Molnar , Masahiro Yamada , Michal Simek , Ard Biesheuvel , Greentime Hu , Borislav Petkov , Maxim Uvarov , Kees Cook , Heiko Carstens , Paul Walmsley , Thomas Gleixner , Anup Patel , Nick Desaulniers , Palmer Dabbelt , Andrew Morton , Mike Rapoport Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org From: Anup Patel Currently, RISC-V reserves 1MB of fixmap memory for device tree. However, it maps only single PMD (2MB) space for fixmap which leaves only < 1MB space left for other kernel features such as early ioremap which requires fixmap as well. The fixmap size can be increased by another 2MB but it brings additional complexity and changes the virtual memory layout as well. If we require some additional feature requiring fixmap again, it has to be moved again. Technically, DT doesn't need a fixmap as the memory occupied by the DT is only used during boot. That's why, We map device tree in early page table using two consecutive PGD mappings at lower addresses (< PAGE_OFFSET). This frees lot of space in fixmap and also makes maximum supported device tree size supported as PGDIR_SIZE. Thus, init memory section can be used for the same purpose as well. This simplifies fixmap implementation. Signed-off-by: Anup Patel Signed-off-by: Atish Patra Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/fixmap.h | 3 --- arch/riscv/include/asm/pgtable.h | 1 + arch/riscv/kernel/head.S | 1 - arch/riscv/kernel/head.h | 2 -- arch/riscv/kernel/setup.c | 9 +++++++-- arch/riscv/mm/init.c | 26 ++++++++++++-------------- 6 files changed, 20 insertions(+), 22 deletions(-) diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h index 1ff075a8dfc7..11613f38228a 100644 --- a/arch/riscv/include/asm/fixmap.h +++ b/arch/riscv/include/asm/fixmap.h @@ -22,9 +22,6 @@ */ enum fixed_addresses { FIX_HOLE, -#define FIX_FDT_SIZE SZ_1M - FIX_FDT_END, - FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1, FIX_PTE, FIX_PMD, FIX_TEXT_POKE1, diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index eaea1f717010..815f8c959dd4 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -464,6 +464,7 @@ static inline void __kernel_map_pages(struct page *page, int numpages, int enabl #define kern_addr_valid(addr) (1) /* FIXME */ extern void *dtb_early_va; +extern uintptr_t dtb_early_pa; void setup_bootmem(void); void paging_init(void); diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 0a4e81b8dc79..c6a37e8231a8 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -259,7 +259,6 @@ clear_bss_done: #endif /* Start the kernel */ call soc_early_init - call parse_dtb tail start_kernel .Lsecondary_start: diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h index 105fb0496b24..b48dda3d04f6 100644 --- a/arch/riscv/kernel/head.h +++ b/arch/riscv/kernel/head.h @@ -16,6 +16,4 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa); extern void *__cpu_up_stack_pointer[]; extern void *__cpu_up_task_pointer[]; -void __init parse_dtb(void); - #endif /* __ASM_HEAD_H */ diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 2c6dd329312b..edea7ef88402 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -48,8 +48,9 @@ atomic_t hart_lottery __section(.sdata); unsigned long boot_cpu_hartid; static DEFINE_PER_CPU(struct cpu, cpu_devices); -void __init parse_dtb(void) +static void __init parse_dtb(void) { + /* Early scan of device tree from init memory */ if (early_init_dt_scan(dtb_early_va)) return; @@ -62,6 +63,7 @@ void __init parse_dtb(void) void __init setup_arch(char **cmdline_p) { + parse_dtb(); init_mm.start_code = (unsigned long) _stext; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; @@ -76,7 +78,10 @@ void __init setup_arch(char **cmdline_p) #if IS_ENABLED(CONFIG_BUILTIN_DTB) unflatten_and_copy_device_tree(); #else - unflatten_device_tree(); + if (early_init_dt_verify(__va(dtb_early_pa))) + unflatten_device_tree(); + else + pr_err("No DTB found in kernel mappings\n"); #endif #ifdef CONFIG_SWIOTLB diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 787c75f751a5..2b651f63f5c4 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -28,7 +28,9 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] EXPORT_SYMBOL(empty_zero_page); extern char _start[]; -void *dtb_early_va; +#define DTB_EARLY_BASE_VA PGDIR_SIZE +void *dtb_early_va __initdata; +uintptr_t dtb_early_pa __initdata; static void __init zone_sizes_init(void) { @@ -141,8 +143,6 @@ static void __init setup_initrd(void) } #endif /* CONFIG_BLK_DEV_INITRD */ -static phys_addr_t dtb_early_pa __initdata; - void __init setup_bootmem(void) { struct memblock_region *reg; @@ -399,7 +399,7 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) asmlinkage void __init setup_vm(uintptr_t dtb_pa) { - uintptr_t va, end_va; + uintptr_t va, pa, end_va; uintptr_t load_pa = (uintptr_t)(&_start); uintptr_t load_sz = (uintptr_t)(&_end) - load_pa; uintptr_t map_size = best_map_size(load_pa, MAX_EARLY_MAPPING_SIZE); @@ -448,16 +448,13 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) load_pa + (va - PAGE_OFFSET), map_size, PAGE_KERNEL_EXEC); - /* Create fixed mapping for early FDT parsing */ - end_va = __fix_to_virt(FIX_FDT) + FIX_FDT_SIZE; - for (va = __fix_to_virt(FIX_FDT); va < end_va; va += PAGE_SIZE) - create_pte_mapping(fixmap_pte, va, - dtb_pa + (va - __fix_to_virt(FIX_FDT)), - PAGE_SIZE, PAGE_KERNEL); - - /* Save pointer to DTB for early FDT parsing */ - dtb_early_va = (void *)fix_to_virt(FIX_FDT) + (dtb_pa & ~PAGE_MASK); - /* Save physical address for memblock reservation */ + /* Create two consecutive PGD mappings for FDT early scan */ + pa = dtb_pa & ~(PGDIR_SIZE - 1); + create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, + pa, PGDIR_SIZE, PAGE_KERNEL); + create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE, + pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); + dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); dtb_early_pa = dtb_pa; } @@ -516,6 +513,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) #else dtb_early_va = (void *)dtb_pa; #endif + dtb_early_pa = dtb_pa; } static inline void setup_vm_final(void) From patchwork Thu Sep 17 22:37:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11783673 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 37451112C for ; Thu, 17 Sep 2020 22:38:05 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 048C52087D for ; Thu, 17 Sep 2020 22:38:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="17c6gBiR"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="gqf7YnJb" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 048C52087D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=e84znuZCv5y349sF+VxBkoUHxZWwaIZeCb5X73jDSLQ=; b=17c6gBiRhtDYDXbel5obYIG/U onpdubeMMP0CKRh0kTpv+zLw94SlSEnKCYjII2yvzAd1Ob1msILxjGPiPsR1hd6xhTQlG6XztRjPg IaTaw/EolqR6s2KnT8Gi6VXGntmcjMSX9zjBTho90reBBdYZKmmfmj5FRs+wZsswmXaB8CZNCZI93 0KLdrZI6Un664ANM5QNcn/sphWXghrPwQ4412DqKL6t3nANAWj+OYOyeWS96T5ddqNjBdsjU77PTj y9Nwy7SXG7/IZfiFWdr4Qtd9Zob3wuc9bc5w63KrPr7ykCFwG7niWqI3Cx1aWlCq1m8IzJuKOWJUg sfnzDtm/g==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XE-0005jO-Ic; Thu, 17 Sep 2020 22:37:48 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2X7-0005fT-G8 for linux-riscv@lists.infradead.org; Thu, 17 Sep 2020 22:37:43 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1600382261; x=1631918261; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lhOc3WWtQwFeHFYUWyapAldP7DuySUtkVYHUOa8roXg=; b=gqf7YnJbe9/UOFfoTaQosMWlM2NCWuOloKB/P6Ae39C4B1c3BgwlSx16 DGYhqjJFNQToN6Pm2zlHzUp8bku93as0LEHYhfWRv+5/MFmDMAjGbLUmP F9/Ie2VBTu1VD6ZVJz5v+U7Kx8WHfW71rG3+k0imu/bZjw9SiiBlb3A32 1+TiyctNPvODf5ulGIuZmoOa0DYDZyxg2KOnr33bzTrLbJ2PmoR5C3k9d 9VxcbSQtuJGAelb6UMmZu4HGtY3eu2vtVXlH8yH3t8v5LhQOwvlx78pC3 IOXHcUMeF+W9E0QRp0xLds9H+bPOD68a1LH8siIsg6I6VHti8S4ZvWPzA g==; IronPort-SDR: f3xe1HK+pN51LVmtKklA39Kh5GGT5uI9IHowi1qHvZxCxTxHXLyf6jOA5VDx+38r8ikw8ct8Vl 8ilwzx3mnSoH/TwxL65o5HWVcSQi2ezA+888kKg57TV06Bp0jzxejbADn73wz8sn5y6McY+0/9 jSQUNGtS/VtFErRRtdB6vT6lHww6ebNOHiEbCT+3V216ZEv8+c2NyKOWwogUxKOzDQwtviGQ6Q TJpu8A7dNrUbJhD6bIg4licnFzXiNWvcjJtHgDbWxhbYKCRoOk1tcmv2Q1v//i2MbhZhCPk3Ij jdw= X-IronPort-AV: E=Sophos;i="5.77,272,1596470400"; d="scan'208";a="257336254" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2020 06:37:38 +0800 IronPort-SDR: QIKWyH08BIgBbpdMSBcFkcxM2bGZpyuSQwOWD7FbO4j37Vk+KV7tU+7dQoZ5BomclSyGpRyQKg QVtGxxs+yCXg== Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2020 15:23:52 -0700 IronPort-SDR: 8ZlNwjQorpceowXk1nDGConbDnwxgJfD0D7sz7hFJvZnmS0oH93Z2IbDhj0zQV2akqtAhrAb3L q4MDctKH/tMQ== WDCIronportException: Internal Received: from use204338.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.39]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Sep 2020 15:37:38 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v8 2/7] RISC-V: Add early ioremap support Date: Thu, 17 Sep 2020 15:37:11 -0700 Message-Id: <20200917223716.2300238-3-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200917223716.2300238-1-atish.patra@wdc.com> References: <20200917223716.2300238-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_183742_013582_E9BF318B X-CRM114-Status: GOOD ( 17.81 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-efi@vger.kernel.org, Palmer Dabbelt , Atish Patra , Arvind Sankar , Maxim Uvarov , Alistair Francis , Zong Li , linux-riscv@lists.infradead.org, Ingo Molnar , Anup Patel , Masahiro Yamada , Michal Simek , Ard Biesheuvel , Greentime Hu , Borislav Petkov , Albert Ou , Kees Cook , Heiko Carstens , Paul Walmsley , Thomas Gleixner , Anup Patel , Nick Desaulniers , Palmer Dabbelt , Andrew Morton , Mike Rapoport Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org UEFI uses early IO or memory mappings for runtime services before normal ioremap() is usable. Add the necessary fixmap bindings and pmd mappings for generic ioremap support to work. Signed-off-by: Atish Patra Reviewed-by: Anup Patel Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 1 + arch/riscv/include/asm/Kbuild | 1 + arch/riscv/include/asm/fixmap.h | 13 +++++++++++++ arch/riscv/include/asm/io.h | 1 + arch/riscv/kernel/setup.c | 2 ++ arch/riscv/mm/init.c | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 51 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index df18372861d8..5e4ace64acbc 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -37,6 +37,7 @@ config RISCV select GENERIC_ARCH_TOPOLOGY if SMP select GENERIC_ATOMIC64 if !64BIT select GENERIC_CLOCKEVENTS + select GENERIC_EARLY_IOREMAP select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO select GENERIC_IOREMAP select GENERIC_IRQ_MULTI_HANDLER diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild index 3d9410bb4de0..59dd7be55005 100644 --- a/arch/riscv/include/asm/Kbuild +++ b/arch/riscv/include/asm/Kbuild @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +generic-y += early_ioremap.h generic-y += extable.h generic-y += flat.h generic-y += kvm_para.h diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h index 11613f38228a..54cbf07fb4e9 100644 --- a/arch/riscv/include/asm/fixmap.h +++ b/arch/riscv/include/asm/fixmap.h @@ -27,6 +27,19 @@ enum fixed_addresses { FIX_TEXT_POKE1, FIX_TEXT_POKE0, FIX_EARLYCON_MEM_BASE, + + __end_of_permanent_fixed_addresses, + /* + * Temporary boot-time mappings, used by early_ioremap(), + * before ioremap() is functional. + */ +#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE) +#define FIX_BTMAPS_SLOTS 7 +#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) + + FIX_BTMAP_END = __end_of_permanent_fixed_addresses, + FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1, + __end_of_fixed_addresses }; diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index 3835c3295dc5..c025a746a148 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -14,6 +14,7 @@ #include #include #include +#include /* * MMIO access functions are separated out to break dependency cycles diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index edea7ef88402..41ef96d0d97a 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -71,6 +72,7 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = boot_command_line; + early_ioremap_setup(); parse_early_param(); setup_bootmem(); diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 2b651f63f5c4..b75ebe8e7a92 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -403,6 +403,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) uintptr_t load_pa = (uintptr_t)(&_start); uintptr_t load_sz = (uintptr_t)(&_end) - load_pa; uintptr_t map_size = best_map_size(load_pa, MAX_EARLY_MAPPING_SIZE); +#ifndef __PAGETABLE_PMD_FOLDED + pmd_t fix_bmap_spmd, fix_bmap_epmd; +#endif va_pa_offset = PAGE_OFFSET - load_pa; pfn_base = PFN_DOWN(load_pa); @@ -456,6 +459,36 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); dtb_early_pa = dtb_pa; + + /* + * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap + * range can not span multiple pmds. + */ + BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT) + != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT)); + +#ifndef __PAGETABLE_PMD_FOLDED + /* + * Early ioremap fixmap is already created as it lies within first 2MB + * of fixmap region. We always map PMD_SIZE. Thus, both FIX_BTMAP_END + * FIX_BTMAP_BEGIN should lie in the same pmd. Verify that and warn + * the user if not. + */ + fix_bmap_spmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_BEGIN))]; + fix_bmap_epmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_END))]; + if (pmd_val(fix_bmap_spmd) != pmd_val(fix_bmap_epmd)) { + WARN_ON(1); + pr_warn("fixmap btmap start [%08lx] != end [%08lx]\n", + pmd_val(fix_bmap_spmd), pmd_val(fix_bmap_epmd)); + pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n", + fix_to_virt(FIX_BTMAP_BEGIN)); + pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n", + fix_to_virt(FIX_BTMAP_END)); + + pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END); + pr_warn("FIX_BTMAP_BEGIN: %d\n", FIX_BTMAP_BEGIN); + } +#endif } static void __init setup_vm_final(void) From patchwork Thu Sep 17 22:37:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11783665 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 EF826746 for ; Thu, 17 Sep 2020 22:37:50 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 AFEEF2087D for ; Thu, 17 Sep 2020 22:37:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="X+3RqFZ4"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="ew7EZtE2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AFEEF2087D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=dXfiH2Q+KKg0jz5QeX+dF3s/wmK48S4GkxkTCjO81R8=; b=X+3RqFZ4SvrxfjbvEGrZMBKg1 +8VSIBeaIaLq8HegwiCN+h3UiYihKIfmGsaVDWzp7kjOZkMhDGJkkcn7UCHnlzBNOFigrf23HqW9L ckArd9dQx8CIDIcS+mvEsl4Sv8IIh1CWfAZZB3Gqj+lXOzxPU1qzMkaNU3ZtS2o32OZCaxWMy7kO1 3GOhKGUWqSvakOQDBw0y7sZwbZUTkak2Q9KjvYA3K46NDVoAY6S3E3HxZB+WMG7z85CbZ1c+lSupZ JEop/hnB6w+KzYLA0fYqdMegbmkQKivlSK0ueSIvQpw46WkdCeCydIxLtZH9JiGHQu1ah+0UbrRi8 DW0zeZemA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XC-0005ia-HD; Thu, 17 Sep 2020 22:37:46 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2X7-0005gG-Hr for linux-riscv@lists.infradead.org; Thu, 17 Sep 2020 22:37:43 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1600382261; x=1631918261; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0SHxP3cRZQa8gFN8WQXBGWYwQyW8SLYLuGAVjQGH2SA=; b=ew7EZtE2zfU26CpolJ4ATkpA5LAQIdsFXQIEQsZ4rmCqAi44pd00qyuq Ln8essADEFiVJMAdLWGPz8tATnZqM3o6Hdf5dIxtHeMAkURy6D5DOuJlm VYneB6ix80aoeyqPAu5jZO5eXAdabZBf3R8HHOnqJxBO6hGC8uYJVqjeY y+zWTtB7YOMTGjv0vOjAI4sSatmC+Ddt8urmRBJpIhad8OS0DZlJpYQjv PuCItCk++5kyeuoZy7+gUs6kQ324eW2zSS2qJXvXKBI+aVG+xk/5LCHsj W7JaARzxR/3yOaOiogVwBLUD9/gvJGpaORfc6qHpNnbHiZ/3jbg1cTqHl w==; IronPort-SDR: xt85BzItvSZm6hlAn0dC608gmRHjrnbxkdTdJvjGh0IIWxBjg6RUh2bXqCGzAZCff1QCRk6WTW +SeoBfQ6ZPhxul/WaswfycqL6UT6VSfeJXUZviMo7FI+TveCKemKM/L1AAw6Aw+0h89UQLqD4K BUgyXfPsSUq9g+36WNttDoZqBIuSTyYm865M/IrKMVCQWUCclsIROugHU5G5ljFMRrZ23PSnlj Ppc2PaeLX/bHVMCd4HiUCOdPE2zFJaiczOh7rpPfZrcnmMdcLNdiqITGllbqrMVP8XKXqCNdBd /q0= X-IronPort-AV: E=Sophos;i="5.77,272,1596470400"; d="scan'208";a="257336256" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2020 06:37:39 +0800 IronPort-SDR: t88Id/P2Ex316HUZOJofTWx2jucDrM1nifeydr0GKCs1FBxP75xBKEb2CnkaYlWjt03+9o24mv 83hyCgQjTVGA== Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2020 15:23:53 -0700 IronPort-SDR: XHSfKP5Xzat0/6fCWcdjbtWjNennorxEVEIAiMPBeH3C7coIU9CooIy69HUCQx/VZpDNRHj3pv 5G2HXFVW0l5A== WDCIronportException: Internal Received: from use204338.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.39]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Sep 2020 15:37:39 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v8 3/7] RISC-V: Implement late mapping page table allocation functions Date: Thu, 17 Sep 2020 15:37:12 -0700 Message-Id: <20200917223716.2300238-4-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200917223716.2300238-1-atish.patra@wdc.com> References: <20200917223716.2300238-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_183742_016077_DAE16892 X-CRM114-Status: GOOD ( 19.72 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-efi@vger.kernel.org, Ard Biesheuvel , Palmer Dabbelt , Atish Patra , Arvind Sankar , Maxim Uvarov , Alistair Francis , Zong Li , linux-riscv@lists.infradead.org, Ingo Molnar , Anup Patel , Masahiro Yamada , Michal Simek , Mike Rapoport , Greentime Hu , Borislav Petkov , Albert Ou , Kees Cook , Heiko Carstens , Paul Walmsley , Thomas Gleixner , Anup Patel , Nick Desaulniers , Palmer Dabbelt , Andrew Morton , Mike Rapoport Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org Currently, page table setup is done during setup_va_final where fixmap can be used to create the temporary mappings. The physical frame is allocated from memblock_alloc_* functions. However, this won't work if page table mapping needs to be created for a different mm context (i.e. efi mm) at a later point of time. Use generic kernel page allocation function & macros for any mapping after setup_vm_final. Signed-off-by: Atish Patra Reviewed-by: Anup Patel Acked-by: Mike Rapoport Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/init.c | 130 ++++++++++++++++++++++++++++++++----------- 1 file changed, 99 insertions(+), 31 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index b75ebe8e7a92..63acc8185bfa 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -32,6 +32,15 @@ extern char _start[]; void *dtb_early_va __initdata; uintptr_t dtb_early_pa __initdata; +struct pt_alloc_ops { + pte_t *(*get_pte_virt)(phys_addr_t pa); + phys_addr_t (*alloc_pte)(uintptr_t va); +#ifndef __PAGETABLE_PMD_FOLDED + pmd_t *(*get_pmd_virt)(phys_addr_t pa); + phys_addr_t (*alloc_pmd)(uintptr_t va); +#endif +}; + static void __init zone_sizes_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, }; @@ -203,6 +212,8 @@ void __init setup_bootmem(void) } #ifdef CONFIG_MMU +static struct pt_alloc_ops pt_ops; + unsigned long va_pa_offset; EXPORT_SYMBOL(va_pa_offset); unsigned long pfn_base; @@ -211,7 +222,6 @@ EXPORT_SYMBOL(pfn_base); pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss; pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss; pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss; -static bool mmu_enabled; #define MAX_EARLY_MAPPING_SIZE SZ_128M @@ -234,27 +244,46 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) } } -static pte_t *__init get_pte_virt(phys_addr_t pa) +static inline pte_t *__init get_pte_virt_early(phys_addr_t pa) { - if (mmu_enabled) { - clear_fixmap(FIX_PTE); - return (pte_t *)set_fixmap_offset(FIX_PTE, pa); - } else { - return (pte_t *)((uintptr_t)pa); - } + return (pte_t *)((uintptr_t)pa); } -static phys_addr_t __init alloc_pte(uintptr_t va) +static inline pte_t *__init get_pte_virt_fixmap(phys_addr_t pa) +{ + clear_fixmap(FIX_PTE); + return (pte_t *)set_fixmap_offset(FIX_PTE, pa); +} + +static inline pte_t *get_pte_virt_late(phys_addr_t pa) +{ + return (pte_t *) __va(pa); +} + +static inline phys_addr_t __init alloc_pte_early(uintptr_t va) { /* * We only create PMD or PGD early mappings so we * should never reach here with MMU disabled. */ - BUG_ON(!mmu_enabled); + BUG(); +} +static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va) +{ return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); } +static phys_addr_t alloc_pte_late(uintptr_t va) +{ + unsigned long vaddr; + + vaddr = __get_free_page(GFP_KERNEL); + if (!vaddr || !pgtable_pte_page_ctor(virt_to_page(vaddr))) + BUG(); + return __pa(vaddr); +} + static void __init create_pte_mapping(pte_t *ptep, uintptr_t va, phys_addr_t pa, phys_addr_t sz, pgprot_t prot) @@ -279,28 +308,46 @@ pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss; #endif pmd_t early_pmd[PTRS_PER_PMD * NUM_EARLY_PMDS] __initdata __aligned(PAGE_SIZE); -static pmd_t *__init get_pmd_virt(phys_addr_t pa) +static pmd_t *__init get_pmd_virt_early(phys_addr_t pa) { - if (mmu_enabled) { - clear_fixmap(FIX_PMD); - return (pmd_t *)set_fixmap_offset(FIX_PMD, pa); - } else { - return (pmd_t *)((uintptr_t)pa); - } + /* Before MMU is enabled */ + return (pmd_t *)((uintptr_t)pa); } -static phys_addr_t __init alloc_pmd(uintptr_t va) +static pmd_t *__init get_pmd_virt_fixmap(phys_addr_t pa) { - uintptr_t pmd_num; + clear_fixmap(FIX_PMD); + return (pmd_t *)set_fixmap_offset(FIX_PMD, pa); +} + +static pmd_t *get_pmd_virt_late(phys_addr_t pa) +{ + return (pmd_t *) __va(pa); +} - if (mmu_enabled) - return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); +static phys_addr_t __init alloc_pmd_early(uintptr_t va) +{ + uintptr_t pmd_num; pmd_num = (va - PAGE_OFFSET) >> PGDIR_SHIFT; BUG_ON(pmd_num >= NUM_EARLY_PMDS); return (uintptr_t)&early_pmd[pmd_num * PTRS_PER_PMD]; } +static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va) +{ + return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); +} + +static phys_addr_t alloc_pmd_late(uintptr_t va) +{ + unsigned long vaddr; + + vaddr = __get_free_page(GFP_KERNEL); + BUG_ON(!vaddr); + return __pa(vaddr); +} + static void __init create_pmd_mapping(pmd_t *pmdp, uintptr_t va, phys_addr_t pa, phys_addr_t sz, pgprot_t prot) @@ -316,28 +363,28 @@ static void __init create_pmd_mapping(pmd_t *pmdp, } if (pmd_none(pmdp[pmd_idx])) { - pte_phys = alloc_pte(va); + pte_phys = pt_ops.alloc_pte(va); pmdp[pmd_idx] = pfn_pmd(PFN_DOWN(pte_phys), PAGE_TABLE); - ptep = get_pte_virt(pte_phys); + ptep = pt_ops.get_pte_virt(pte_phys); memset(ptep, 0, PAGE_SIZE); } else { pte_phys = PFN_PHYS(_pmd_pfn(pmdp[pmd_idx])); - ptep = get_pte_virt(pte_phys); + ptep = pt_ops.get_pte_virt(pte_phys); } create_pte_mapping(ptep, va, pa, sz, prot); } #define pgd_next_t pmd_t -#define alloc_pgd_next(__va) alloc_pmd(__va) -#define get_pgd_next_virt(__pa) get_pmd_virt(__pa) +#define alloc_pgd_next(__va) pt_ops.alloc_pmd(__va) +#define get_pgd_next_virt(__pa) pt_ops.get_pmd_virt(__pa) #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ create_pmd_mapping(__nextp, __va, __pa, __sz, __prot) #define fixmap_pgd_next fixmap_pmd #else #define pgd_next_t pte_t -#define alloc_pgd_next(__va) alloc_pte(__va) -#define get_pgd_next_virt(__pa) get_pte_virt(__pa) +#define alloc_pgd_next(__va) pt_ops.alloc_pte(__va) +#define get_pgd_next_virt(__pa) pt_ops.get_pte_virt(__pa) #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ create_pte_mapping(__nextp, __va, __pa, __sz, __prot) #define fixmap_pgd_next fixmap_pte @@ -421,6 +468,12 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) BUG_ON((load_pa % map_size) != 0); BUG_ON(load_sz > MAX_EARLY_MAPPING_SIZE); + pt_ops.alloc_pte = alloc_pte_early; + pt_ops.get_pte_virt = get_pte_virt_early; +#ifndef __PAGETABLE_PMD_FOLDED + pt_ops.alloc_pmd = alloc_pmd_early; + pt_ops.get_pmd_virt = get_pmd_virt_early; +#endif /* Setup early PGD for fixmap */ create_pgd_mapping(early_pg_dir, FIXADDR_START, (uintptr_t)fixmap_pgd_next, PGDIR_SIZE, PAGE_TABLE); @@ -497,9 +550,16 @@ static void __init setup_vm_final(void) phys_addr_t pa, start, end; struct memblock_region *reg; - /* Set mmu_enabled flag */ - mmu_enabled = true; - + /** + * MMU is enabled at this point. But page table setup is not complete yet. + * fixmap page table alloc functions should be used at this point + */ + pt_ops.alloc_pte = alloc_pte_fixmap; + pt_ops.get_pte_virt = get_pte_virt_fixmap; +#ifndef __PAGETABLE_PMD_FOLDED + pt_ops.alloc_pmd = alloc_pmd_fixmap; + pt_ops.get_pmd_virt = get_pmd_virt_fixmap; +#endif /* Setup swapper PGD for fixmap */ create_pgd_mapping(swapper_pg_dir, FIXADDR_START, __pa_symbol(fixmap_pgd_next), @@ -533,6 +593,14 @@ static void __init setup_vm_final(void) /* Move to swapper page table */ csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE); local_flush_tlb_all(); + + /* generic page allocation functions must be used to setup page table */ + pt_ops.alloc_pte = alloc_pte_late; + pt_ops.get_pte_virt = get_pte_virt_late; +#ifndef __PAGETABLE_PMD_FOLDED + pt_ops.alloc_pmd = alloc_pmd_late; + pt_ops.get_pmd_virt = get_pmd_virt_late; +#endif } #else asmlinkage void __init setup_vm(uintptr_t dtb_pa) From patchwork Thu Sep 17 22:37:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11783667 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 58140746 for ; Thu, 17 Sep 2020 22:37:53 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 0A1512087D for ; Thu, 17 Sep 2020 22:37:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="y/heVqB9"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="YIIsB/UF" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0A1512087D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=06WpB6Yd7V22tR1eWxm20kNSlDUpO94ZTauAmACWMOc=; b=y/heVqB9vSMWoU39rNMKMuFYY ky4HeefrOwlg19qMB/s7Hb2xV6nkzu+NDyT/cqFYHKdNkMjWrKphhCGKBuYemgybtlvJAC3tCCL4I Vg/ZGk/Ldf8NGKQ1Bu5WtPY1WLDfJW/XgjkgT8RIQ2qMpgYa35XFGogI6upvg9rwwJABAmx/kfk6u bNAXioqglzqFQDKctzdeNnyJewC8Ij2veLeXIIAazIabGNK1PLU/rbAmjU7kx5Wc3CzQpD72y4sNK SUe6Hm+YNmfeZlKzkQLsrT1fhcvetw1TzafreGHox841dzNRIoeIPFBbaj/BRmTtCbQWkcIVQwcCl wZmZ+LRyw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XF-0005ju-MC; Thu, 17 Sep 2020 22:37:49 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2X8-0005fc-6k for linux-riscv@lists.infradead.org; Thu, 17 Sep 2020 22:37:46 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1600382261; x=1631918261; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ap/iYK+pnmmV1Gv5OQpimfoqYTDmh3HSbNS4dAG5jsc=; b=YIIsB/UFVfOZsECDwl0u6ggAsI3jhXbRmM+W0+Ni/yeY8e3lm3Vm/yQl uRFcvtLCIZW3KYvR7WfDN69f7ymd/a6CLXdA0/PC5nFvUhjgHPIFb1n5O tYCNaj8eFYu3Wj0AxKyfJZm8XWV29wjsExXQGZIyzvS0A4DOpD2KU5MBK Dw3N+DKw9mDUlu7f4va25PNDxe8LBcZgR6PlwEM+v2ea4pvI416YTT35y 8OJW9zBh7RHoHpvZXiFYXOxJGmACcJiAfL9UU/4ylShwFawkhz8zeyYLK /rvwI3d9eYk2uWfjoCRYLNVc97wD4jNhxkdCb3ZWZeZ6UX32KJo/mj5xF Q==; IronPort-SDR: MZc+yxRkf/Hxpbklcatc7f0ik4aLOToOP2A32Rm0Vj5La8PHJdh1A5X1FgybtrNiNIX9eOLcUS 6Gamv4+aUXRtaNsFxEUnuNFLftN0XW4BzrEVKqB4dA8uyL4p5KBFi5+zq65GmCQ0hlEKSFvrOT ns9U2XtE7crKEGRjm1PYSfwUMBy09LH+WS9BIQ0jCYm84PEWjQAAR+Kpe6c0E2Cp2Dw+JGs3q1 AaqGiEkTVXbRzHq/8Z+c8G7RiY5dBB0dKCHSfH0RJTdA0QKHc5Gvq6JnLDITwMVRqybTuW+rEU shU= X-IronPort-AV: E=Sophos;i="5.77,272,1596470400"; d="scan'208";a="257336257" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2020 06:37:40 +0800 IronPort-SDR: PL6pbMJNABtRakC509F7KXvb9x7GIEhPZszCLVfWiah4qBeEjunTR4SLY3QFBOIYtsqPtGwnd3 IaNKG54+5ZmQ== Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2020 15:23:54 -0700 IronPort-SDR: 6dGLN1wdEIGT1ykbMpD08Ps0OpTLygvXkRipVbHgtbCWZ3rjc+paCHdukhXcQ6sO2DFv8YIZJf wO0tY3aBoCDw== WDCIronportException: Internal Received: from use204338.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.39]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Sep 2020 15:37:39 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v8 4/7] RISC-V: Add PE/COFF header for EFI stub Date: Thu, 17 Sep 2020 15:37:13 -0700 Message-Id: <20200917223716.2300238-5-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200917223716.2300238-1-atish.patra@wdc.com> References: <20200917223716.2300238-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_183742_423814_D1CFF2CD X-CRM114-Status: GOOD ( 25.32 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-efi@vger.kernel.org, Palmer Dabbelt , Atish Patra , Arvind Sankar , Maxim Uvarov , Alistair Francis , Zong Li , linux-riscv@lists.infradead.org, Ingo Molnar , Anup Patel , Masahiro Yamada , Michal Simek , Ard Biesheuvel , Greentime Hu , Borislav Petkov , Albert Ou , Kees Cook , Heiko Carstens , Paul Walmsley , Thomas Gleixner , Anup Patel , Nick Desaulniers , Palmer Dabbelt , Andrew Morton , Mike Rapoport Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org Linux kernel Image can appear as an EFI application With appropriate PE/COFF header fields in the beginning of the Image header. An EFI application loader can directly load a Linux kernel Image and an EFI stub residing in kernel can boot Linux kernel directly. Add the necessary PE/COFF header. Signed-off-by: Atish Patra Link: https://lore.kernel.org/r/20200421033336.9663-3-atish.patra@wdc.com [ardb: - use C prefix for c.li to ensure the expected opcode is emitted - align all image sections according to PE/COFF section alignment ] Signed-off-by: Ard Biesheuvel Reviewed-by: Anup Patel Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/sections.h | 13 ++++ arch/riscv/kernel/efi-header.S | 111 ++++++++++++++++++++++++++++++ arch/riscv/kernel/head.S | 16 +++++ arch/riscv/kernel/image-vars.h | 51 ++++++++++++++ arch/riscv/kernel/vmlinux.lds.S | 23 ++++++- 5 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 arch/riscv/include/asm/sections.h create mode 100644 arch/riscv/kernel/efi-header.S create mode 100644 arch/riscv/kernel/image-vars.h diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h new file mode 100644 index 000000000000..3a9971b1210f --- /dev/null +++ b/arch/riscv/include/asm/sections.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ +#ifndef __ASM_SECTIONS_H +#define __ASM_SECTIONS_H + +#include + +extern char _start[]; +extern char _start_kernel[]; + +#endif /* __ASM_SECTIONS_H */ diff --git a/arch/riscv/kernel/efi-header.S b/arch/riscv/kernel/efi-header.S new file mode 100644 index 000000000000..8e733aa48ba6 --- /dev/null +++ b/arch/riscv/kernel/efi-header.S @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + * Adapted from arch/arm64/kernel/efi-header.S + */ + +#include +#include + + .macro __EFI_PE_HEADER + .long PE_MAGIC +coff_header: +#ifdef CONFIG_64BIT + .short IMAGE_FILE_MACHINE_RISCV64 // Machine +#else + .short IMAGE_FILE_MACHINE_RISCV32 // Machine +#endif + .short section_count // NumberOfSections + .long 0 // TimeDateStamp + .long 0 // PointerToSymbolTable + .long 0 // NumberOfSymbols + .short section_table - optional_header // SizeOfOptionalHeader + .short IMAGE_FILE_DEBUG_STRIPPED | \ + IMAGE_FILE_EXECUTABLE_IMAGE | \ + IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics + +optional_header: +#ifdef CONFIG_64BIT + .short PE_OPT_MAGIC_PE32PLUS // PE32+ format +#else + .short PE_OPT_MAGIC_PE32 // PE32 format +#endif + .byte 0x02 // MajorLinkerVersion + .byte 0x14 // MinorLinkerVersion + .long __pecoff_text_end - efi_header_end // SizeOfCode + .long __pecoff_data_virt_size // SizeOfInitializedData + .long 0 // SizeOfUninitializedData + .long __efistub_efi_pe_entry - _start // AddressOfEntryPoint + .long efi_header_end - _start // BaseOfCode +#ifdef CONFIG_32BIT + .long __pecoff_text_end - _start // BaseOfData +#endif + +extra_header_fields: + .quad 0 // ImageBase + .long PECOFF_SECTION_ALIGNMENT // SectionAlignment + .long PECOFF_FILE_ALIGNMENT // FileAlignment + .short 0 // MajorOperatingSystemVersion + .short 0 // MinorOperatingSystemVersion + .short LINUX_EFISTUB_MAJOR_VERSION // MajorImageVersion + .short LINUX_EFISTUB_MINOR_VERSION // MinorImageVersion + .short 0 // MajorSubsystemVersion + .short 0 // MinorSubsystemVersion + .long 0 // Win32VersionValue + + .long _end - _start // SizeOfImage + + // Everything before the kernel image is considered part of the header + .long efi_header_end - _start // SizeOfHeaders + .long 0 // CheckSum + .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem + .short 0 // DllCharacteristics + .quad 0 // SizeOfStackReserve + .quad 0 // SizeOfStackCommit + .quad 0 // SizeOfHeapReserve + .quad 0 // SizeOfHeapCommit + .long 0 // LoaderFlags + .long (section_table - .) / 8 // NumberOfRvaAndSizes + + .quad 0 // ExportTable + .quad 0 // ImportTable + .quad 0 // ResourceTable + .quad 0 // ExceptionTable + .quad 0 // CertificationTable + .quad 0 // BaseRelocationTable + + // Section table +section_table: + .ascii ".text\0\0\0" + .long __pecoff_text_end - efi_header_end // VirtualSize + .long efi_header_end - _start // VirtualAddress + .long __pecoff_text_end - efi_header_end // SizeOfRawData + .long efi_header_end - _start // PointerToRawData + + .long 0 // PointerToRelocations + .long 0 // PointerToLineNumbers + .short 0 // NumberOfRelocations + .short 0 // NumberOfLineNumbers + .long IMAGE_SCN_CNT_CODE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE // Characteristics + + .ascii ".data\0\0\0" + .long __pecoff_data_virt_size // VirtualSize + .long __pecoff_text_end - _start // VirtualAddress + .long __pecoff_data_raw_size // SizeOfRawData + .long __pecoff_text_end - _start // PointerToRawData + + .long 0 // PointerToRelocations + .long 0 // PointerToLineNumbers + .short 0 // NumberOfRelocations + .short 0 // NumberOfLineNumbers + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE // Characteristics + + .set section_count, (. - section_table) / 40 + + .balign 0x1000 +efi_header_end: + .endm diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index c6a37e8231a8..3631147732ee 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -13,6 +13,7 @@ #include #include #include +#include "efi-header.S" __HEAD ENTRY(_start) @@ -22,10 +23,18 @@ ENTRY(_start) * Do not modify it without modifying the structure and all bootloaders * that expects this header format!! */ +#ifdef CONFIG_EFI + /* + * This instruction decodes to "MZ" ASCII required by UEFI. + */ + c.li s4,-13 + j _start_kernel +#else /* jump to start kernel */ j _start_kernel /* reserved */ .word 0 +#endif .balign 8 #if __riscv_xlen == 64 /* Image load offset(2MB) from start of RAM */ @@ -43,7 +52,14 @@ ENTRY(_start) .ascii RISCV_IMAGE_MAGIC .balign 4 .ascii RISCV_IMAGE_MAGIC2 +#ifdef CONFIG_EFI + .word pe_head_start - _start +pe_head_start: + + __EFI_PE_HEADER +#else .word 0 +#endif .align 2 #ifdef CONFIG_MMU diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h new file mode 100644 index 000000000000..8c212efb37a6 --- /dev/null +++ b/arch/riscv/kernel/image-vars.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + * Linker script variables to be set after section resolution, as + * ld.lld does not like variables assigned before SECTIONS is processed. + * Based on arch/arm64/kerne/image-vars.h + */ +#ifndef __RISCV_KERNEL_IMAGE_VARS_H +#define __RISCV_KERNEL_IMAGE_VARS_H + +#ifndef LINKER_SCRIPT +#error This file should only be included in vmlinux.lds.S +#endif + +#ifdef CONFIG_EFI + +/* + * The EFI stub has its own symbol namespace prefixed by __efistub_, to + * isolate it from the kernel proper. The following symbols are legally + * accessed by the stub, so provide some aliases to make them accessible. + * Only include data symbols here, or text symbols of functions that are + * guaranteed to be safe when executed at another offset than they were + * linked at. The routines below are all implemented in assembler in a + * position independent manner + */ +__efistub_memcmp = memcmp; +__efistub_memchr = memchr; +__efistub_memcpy = memcpy; +__efistub_memmove = memmove; +__efistub_memset = memset; +__efistub_strlen = strlen; +__efistub_strnlen = strnlen; +__efistub_strcmp = strcmp; +__efistub_strncmp = strncmp; +__efistub_strrchr = strrchr; + +#ifdef CONFIG_KASAN +__efistub___memcpy = memcpy; +__efistub___memmove = memmove; +__efistub___memset = memset; +#endif + +__efistub__start = _start; +__efistub__start_kernel = _start_kernel; +__efistub__end = _end; +__efistub__edata = _edata; +__efistub_screen_info = screen_info; + +#endif + +#endif /* __RISCV_KERNEL_IMAGE_VARS_H */ diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index f3586e31ed1e..9795359cb9da 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -10,6 +10,7 @@ #include #include #include +#include "image-vars.h" #include OUTPUT_ARCH(riscv) @@ -17,6 +18,9 @@ ENTRY(_start) jiffies = jiffies_64; +PECOFF_SECTION_ALIGNMENT = 0x1000; +PECOFF_FILE_ALIGNMENT = 0x200; + SECTIONS { /* Beginning of code and text segment */ @@ -67,6 +71,11 @@ SECTIONS _etext = .; } +#ifdef CONFIG_EFI + . = ALIGN(PECOFF_SECTION_ALIGNMENT); + __pecoff_text_end = .; +#endif + /* Start of data section */ _sdata = .; RO_DATA(SECTION_ALIGN) @@ -83,16 +92,26 @@ SECTIONS .sdata : { __global_pointer$ = . + 0x800; *(.sdata*) - /* End of data section */ - _edata = .; } +#ifdef CONFIG_EFI + .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); } + __pecoff_data_raw_size = ABSOLUTE(. - __pecoff_text_end); +#endif + + /* End of data section */ + _edata = .; + BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) .rel.dyn : { *(.rel.dyn*) } +#ifdef CONFIG_EFI + . = ALIGN(PECOFF_SECTION_ALIGNMENT); + __pecoff_data_virt_size = ABSOLUTE(. - __pecoff_text_end); +#endif _end = .; STABS_DEBUG From patchwork Thu Sep 17 22:37:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11783675 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 6AE69746 for ; Thu, 17 Sep 2020 22:38:09 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 2F8AF2087D for ; Thu, 17 Sep 2020 22:38:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="nyOcFgIh"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="Xa+uUh4D" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2F8AF2087D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=cgljlQJxeNX8Ca1m4EIdKduG/ntgdh0G1txGqZw391A=; b=nyOcFgIhO+WyArsk2diYzvYjr xJm3Wia0XrtD3jUvU1Fw6K8Jo5Wtnf2JNM6z5P1XvOVgugf6Inl2xkq4b6uji7AD+hz+pPz7mpatt cwW13e/m0xIyx1GlHvtZzTSbqnOSeQNJsoqKV92SqNn0fIsheh1xv2HIyeVx/6kiFb7Ys02UUVtgF Eda58jRmUBVwXhdZ15Jl9QUKDfv2xciyhIEp48kl2+yEO43WY2WZpTUtH2ND8wtA7YXGQk5ydcxFa mij6mhvZJ8ngyWn3GQWlON1TdFaXlBsdidHm/XvrVAgZ2dunKrMe5Gbj1dWHgwxOdlRPNdvH3sQ3j Pt0WtpBUg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XH-0005kn-Ph; Thu, 17 Sep 2020 22:37:51 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2X9-0005gG-J1 for linux-riscv@lists.infradead.org; Thu, 17 Sep 2020 22:37:46 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1600382263; x=1631918263; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zxXH2/7YI+PwGAWZtomJ4Dd84mp5VM0rgEr3PoVuYe8=; b=Xa+uUh4DZB9abxaVhBpzI8x4oLgeL/kZwAUYrrHLzflUaWiG7PtFjz6j NvbxNxz6DA0KcSTT5lrCuYeh8KIXB8BHwN6+tFsfZ5FmGiOHg9NXGc6pP Hj1dX8F1fhblUMxqR3yeJlc/SIXja696ah3djtRBsfeqyKSIp23jWvo8c i1Xh0dNBb4j4M5jIREgNAIIw6qwSa+FHrAYhqu5iyaaTnGUQrXEa0NBaE 5EAwwPExtpCAIvNbcFs/uSXiRC8u6eqy9p6bv8wyf+iKKklVmX8VwFssQ gQxJBgq4ww3oipXGAyIhzCHiEm7/vH1+Q5VXLDHTDkVU9JKkX3mWfit/U Q==; IronPort-SDR: r7Cp+GwJBrSOlYObmVZL1i5k9JfQnup3YmDwLxVudi9vWkduJKcHDdbhULpFIa1mZxN4o8ggfP /PkLuwf5ZrgiLn15AXl8if+vsC1FEdePxtV7VYloIVbdIGdYgU3J4jaJ6xmOPVG5qbKwJ2W9Q9 HgC+QOP1hJ0lSGXJrdM8vNJBpMZf8N7Mb9y7BciO4gNa1WUtpR4cf8PTLuddOdPaRTBVJvboAK zm6onoqh78PoTIreC8utjM6Y1L7anNSBglh9icOi2NWiw/kwtNvSST715k1BfHwYQ6xt5wH9Xz Xk0= X-IronPort-AV: E=Sophos;i="5.77,272,1596470400"; d="scan'208";a="257336259" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2020 06:37:41 +0800 IronPort-SDR: 4CwhpSzFKspyFlNGP67lX8V/sekBmeFkIqXpnM1rJ2i85to8w/P8nWoxaMdtldn/wstXmWIOxN M8EEcTqplf0g== Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2020 15:23:55 -0700 IronPort-SDR: 3M5TTOgDa/WKmIQJOtZfHQzqKowTMYrkgXSd1JVb2yYsqCH6xvLdljR82hW9K0miW+L9HYoNvL r6txRRc4kZmg== WDCIronportException: Internal Received: from use204338.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.39]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Sep 2020 15:37:40 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v8 5/7] RISC-V: Add EFI stub support. Date: Thu, 17 Sep 2020 15:37:14 -0700 Message-Id: <20200917223716.2300238-6-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200917223716.2300238-1-atish.patra@wdc.com> References: <20200917223716.2300238-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_183743_802984_D368CAAE X-CRM114-Status: GOOD ( 33.81 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-efi@vger.kernel.org, Palmer Dabbelt , Atish Patra , Arvind Sankar , Maxim Uvarov , Alistair Francis , Zong Li , linux-riscv@lists.infradead.org, Ingo Molnar , Masahiro Yamada , Michal Simek , Ard Biesheuvel , Greentime Hu , Borislav Petkov , Albert Ou , Kees Cook , Heiko Carstens , Paul Walmsley , Thomas Gleixner , Anup Patel , Nick Desaulniers , Palmer Dabbelt , Andrew Morton , Mike Rapoport Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org Add a RISC-V architecture specific stub code that actually copies the actual kernel image to a valid address and jump to it after boot services are terminated. Enable UEFI related kernel configs as well for RISC-V. Signed-off-by: Atish Patra Link: https://lore.kernel.org/r/20200421033336.9663-4-atish.patra@wdc.com [ardb: - move hartid fetch into check_platform_features() - use image_size not reserve_size - select ISA_C - do not use dram_base] Signed-off-by: Ard Biesheuvel Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 22 +++++ arch/riscv/Makefile | 1 + arch/riscv/configs/defconfig | 1 + arch/riscv/include/asm/efi.h | 35 +++++++ drivers/firmware/efi/Kconfig | 3 +- drivers/firmware/efi/libstub/Makefile | 10 ++ drivers/firmware/efi/libstub/riscv-stub.c | 109 ++++++++++++++++++++++ 7 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/include/asm/efi.h create mode 100644 drivers/firmware/efi/libstub/riscv-stub.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 5e4ace64acbc..6ef2394be857 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -401,6 +401,26 @@ config CMDLINE_FORCE endchoice +config EFI_STUB + bool + +config EFI + bool "UEFI runtime support" + depends on OF + select LIBFDT + select UCS2_STRING + select EFI_PARAMS_FROM_FDT + select EFI_STUB + select EFI_GENERIC_STUB + select RISCV_ISA_C + default y + help + This option provides support for runtime services provided + by UEFI firmware (such as non-volatile variables, realtime + clock, and platform reset). A UEFI stub is also provided to + allow the kernel to be booted as an EFI application. This + is only useful on systems that have UEFI firmware. + endmenu config BUILTIN_DTB @@ -413,3 +433,5 @@ menu "Power management options" source "kernel/power/Kconfig" endmenu + +source "drivers/firmware/Kconfig" diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index fb6e37db836d..10df59f28add 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -80,6 +80,7 @@ head-y := arch/riscv/kernel/head.o core-y += arch/riscv/ libs-y += arch/riscv/lib/ +libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a PHONY += vdso_install vdso_install: diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index d58c93efb603..d222d353d86d 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -130,3 +130,4 @@ CONFIG_DEBUG_BLOCK_EXT_DEVT=y # CONFIG_RUNTIME_TESTING_MENU is not set CONFIG_MEMTEST=y # CONFIG_SYSFS_SYSCALL is not set +CONFIG_EFI=y diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h new file mode 100644 index 000000000000..bf6a40e20a8e --- /dev/null +++ b/arch/riscv/include/asm/efi.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ +#ifndef _ASM_EFI_H +#define _ASM_EFI_H + +#include +#include +#include +#include + +/* on RISC-V, the FDT may be located anywhere in system RAM */ +static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) +{ + return ULONG_MAX; +} + +/* Load initrd at enough distance from DRAM start */ +static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) +{ + return image_addr + SZ_256M; +} + +#define alloc_screen_info(x...) (&screen_info) + +static inline void free_screen_info(struct screen_info *si) +{ +} + +static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) +{ +} + +#endif /* _ASM_EFI_H */ diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 3939699e62fe..a29fbd6e657e 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -111,7 +111,7 @@ config EFI_GENERIC_STUB config EFI_ARMSTUB_DTB_LOADER bool "Enable the DTB loader" - depends on EFI_GENERIC_STUB + depends on EFI_GENERIC_STUB && !RISCV default y help Select this config option to add support for the dtb= command @@ -128,6 +128,7 @@ config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER bool "Enable the command line initrd loader" if !X86 depends on EFI_STUB && (EFI_GENERIC_STUB || X86) default y + depends on !RISCV help Select this config option to add support for the initrd= command line parameter, allowing an initrd that resides on the same volume diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 296b18fbd7a2..e9fc2ddabd5f 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -22,6 +22,8 @@ cflags-$(CONFIG_ARM64) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ cflags-$(CONFIG_ARM) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ -fno-builtin -fpic \ $(call cc-option,-mno-single-pic-base) +cflags-$(CONFIG_RISCV) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ + -fpic cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt @@ -63,6 +65,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o fdt.o string.o \ lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o lib-$(CONFIG_X86) += x86-stub.o +lib-$(CONFIG_RISCV) += riscv-stub.o CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) @@ -106,6 +109,13 @@ STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \ --prefix-symbols=__efistub_ STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS +# For RISC-V, we don't need anything special other than arm64. Keep all the +# symbols in .init section and make sure that no absolute symbols references +# doesn't exist. +STUBCOPY_FLAGS-$(CONFIG_RISCV) += --prefix-alloc-sections=.init \ + --prefix-symbols=__efistub_ +STUBCOPY_RELOC-$(CONFIG_RISCV) := R_RISCV_HI20 + $(obj)/%.stub.o: $(obj)/%.o FORCE $(call if_changed,stubcopy) diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c new file mode 100644 index 000000000000..380e4e251399 --- /dev/null +++ b/drivers/firmware/efi/libstub/riscv-stub.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ + +#include +#include + +#include +#include + +#include "efistub.h" + +/* + * RISC-V requires the kernel image to placed 2 MB aligned base for 64 bit and + * 4MB for 32 bit. + */ +#ifdef CONFIG_64BIT +#define MIN_KIMG_ALIGN SZ_2M +#else +#define MIN_KIMG_ALIGN SZ_4M +#endif + +typedef void __noreturn (*jump_kernel_func)(unsigned int, unsigned long); + +static u32 hartid; + +static u32 get_boot_hartid_from_fdt(void) +{ + const void *fdt; + int chosen_node, len; + const fdt32_t *prop; + + fdt = get_efi_config_table(DEVICE_TREE_GUID); + if (!fdt) + return U32_MAX; + + chosen_node = fdt_path_offset(fdt, "/chosen"); + if (chosen_node < 0) + return U32_MAX; + + prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len); + if (!prop || len != sizeof(u32)) + return U32_MAX; + + return fdt32_to_cpu(*prop); +} + +efi_status_t check_platform_features(void) +{ + hartid = get_boot_hartid_from_fdt(); + if (hartid == U32_MAX) { + efi_err("/chosen/boot-hartid missing or invalid!\n"); + return EFI_UNSUPPORTED; + } + return EFI_SUCCESS; +} + +void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt, + unsigned long fdt_size) +{ + unsigned long stext_offset = _start_kernel - _start; + unsigned long kernel_entry = entrypoint + stext_offset; + jump_kernel_func jump_kernel = (jump_kernel_func)kernel_entry; + + /* + * Jump to real kernel here with following constraints. + * 1. MMU should be disabled. + * 2. a0 should contain hartid + * 3. a1 should DT address + */ + csr_write(CSR_SATP, 0); + jump_kernel(hartid, fdt); +} + +efi_status_t handle_kernel_image(unsigned long *image_addr, + unsigned long *image_size, + unsigned long *reserve_addr, + unsigned long *reserve_size, + efi_loaded_image_t *image) +{ + unsigned long kernel_size = 0; + unsigned long preferred_addr; + efi_status_t status; + + kernel_size = _edata - _start; + *image_addr = (unsigned long)_start; + *image_size = kernel_size + (_end - _edata); + + /* + * RISC-V kernel maps PAGE_OFFSET virtual address to the same physical + * address where kernel is booted. That's why kernel should boot from + * as low as possible to avoid wastage of memory. Currently, dram_base + * is occupied by the firmware. So the preferred address for kernel to + * boot is next aligned address. If preferred address is not available, + * relocate_kernel will fall back to efi_low_alloc_above to allocate + * lowest possible memory region as long as the address and size meets + * the alignment constraints. + */ + preferred_addr = MIN_KIMG_ALIGN; + status = efi_relocate_kernel(image_addr, kernel_size, *image_size, + preferred_addr, MIN_KIMG_ALIGN, 0x0); + + if (status != EFI_SUCCESS) { + efi_err("Failed to relocate kernel\n"); + *image_size = 0; + } + return status; +} From patchwork Thu Sep 17 22:37:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11783669 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 E13AC746 for ; Thu, 17 Sep 2020 22:37:55 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 A40892087D for ; Thu, 17 Sep 2020 22:37:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="JRLCvwQS"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="JUlFZNP3" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A40892087D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=Gsqb6v/Dzna2ZvWi/6qIywY/AlLTRWHMhg8nahUnd2Q=; b=JRLCvwQSuxZoeb64KIbJPBHUn vybIdRu3AoCzE2TgVSu7f6JYj7EhFrsWZEOpxjbicYTKJsIPPiHn+GeF0YM19iURN8b2p+szR9YsZ A56tKNPPCSp+9EWS07SzZxfxJLahXaC2qnccj6ZvNKuuaNHS+h/sN8WDap3KzTL2+EqMS5Z45j1Ya 6uinl5DqUSHlbKUR7aP/r2Dt49M9o70ayJjn4UDoJUoAYhYXYs/ozVOaPm+qv+yBhr+bxHWkFsn1X JMRqV51ao1sQuZ5eqytxJ3ui3nOVSWFiY+n+DNfIIxYXldus3QrRGwOzvipYDANZJwx8YyGL0xTWg Dsh1/usUw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XI-0005lI-Ri; Thu, 17 Sep 2020 22:37:52 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2X9-0005fT-Jr for linux-riscv@lists.infradead.org; Thu, 17 Sep 2020 22:37:46 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1600382263; x=1631918263; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=IhVO8KqIF9i3iFOfVHcKtV7XvLvZ0VsM4lDALZ6rfXg=; b=JUlFZNP3x8GZmhWSuuD++IR+Qk6hEcW+S05DcSyHQPQvee4MfxozC0jR Te7w5smCkvcoWw7TIyxSglgH6AxJwB2AZX4eOu+J+eHix1BE1Mya9qnYv n7xdt+mpFH0nhtWYFyJtTFb4ju9bEF1TtefnFmOAQuI/vZADALJCQXCMU lphAqMhzN5ajcEFTyuYZSAAA1y+xp9rQRS2imzK80cQflBnTMseE89esX MsOIbeB2gzw8woL9pckTiQdxqcHgUA2X21uhd90cN4tdYvSkRdTJb+HQe mD0LSQOTcLta+21qav1ezmDIxmX4B9wUJNv15doptB6dv7DahGx/Etzgj g==; IronPort-SDR: Hd5AoIMSlA343yDExV65X+yfTD047M+57lGpuaUiN7h60Jc0OW6y3hs1SFjCAaBkohHfKFUYzv D3JP02hPnTkD5kCbkxUMJzGp5KKCKYPb34AjgMnKJ1WCA9roj8bpiLLiW0xVovCMhc3cOuJLQY G1WNC8CQaS2n5vFL2j72yErdISbLV8JSZHDVieZkSqPChVA9WQfFPvxxAGFuHJBhVBJLtFHSyN /OCMoe5uvz0noTyHsb0U0x1URJTn6MG4ZGhd/3Ww4uMT4LjalzF/Gpmk/88rxIY90GfS1ip3QP kQg= X-IronPort-AV: E=Sophos;i="5.77,272,1596470400"; d="scan'208";a="257336260" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2020 06:37:42 +0800 IronPort-SDR: y0uWzCaG/Zk8sTud4licRbX8RB2ZPKn4kuT+e477iwxgsOXPePAemBDhSa9UE9Dh/OOqALUSEe Jmuda71ejasg== Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2020 15:23:56 -0700 IronPort-SDR: TA7SNUHWD38uDTzjIrz6BIO+FN5SCGEk/2fWn/eUDI+ZZhvx+yng/jG4P8lU2cPvnGIN4b63cn SqQ2jbIQXegw== WDCIronportException: Internal Received: from use204338.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.39]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Sep 2020 15:37:42 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v8 6/7] RISC-V: Add EFI runtime services Date: Thu, 17 Sep 2020 15:37:15 -0700 Message-Id: <20200917223716.2300238-7-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200917223716.2300238-1-atish.patra@wdc.com> References: <20200917223716.2300238-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_183743_835639_4F683F8E X-CRM114-Status: GOOD ( 31.08 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-efi@vger.kernel.org, Palmer Dabbelt , Atish Patra , Arvind Sankar , Maxim Uvarov , Alistair Francis , Zong Li , linux-riscv@lists.infradead.org, Ingo Molnar , Masahiro Yamada , Michal Simek , Ard Biesheuvel , Greentime Hu , Borislav Petkov , Albert Ou , Kees Cook , Heiko Carstens , Paul Walmsley , Thomas Gleixner , Anup Patel , Nick Desaulniers , Palmer Dabbelt , Andrew Morton , Mike Rapoport Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org This patch adds EFI runtime service support for RISC-V. Signed-off-by: Atish Patra [ardb: - Remove the page check] Signed-off-by: Ard Biesheuvel Acked-by: Ard Biesheuvel Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 2 + arch/riscv/include/asm/efi.h | 20 ++++ arch/riscv/include/asm/mmu.h | 2 + arch/riscv/include/asm/pgtable.h | 4 + arch/riscv/kernel/Makefile | 2 + arch/riscv/kernel/efi.c | 96 ++++++++++++++++ arch/riscv/kernel/setup.c | 7 +- arch/riscv/mm/init.c | 2 +- drivers/firmware/efi/Makefile | 2 + drivers/firmware/efi/libstub/efi-stub.c | 11 +- drivers/firmware/efi/riscv-runtime.c | 143 ++++++++++++++++++++++++ 11 files changed, 287 insertions(+), 4 deletions(-) create mode 100644 arch/riscv/kernel/efi.c create mode 100644 drivers/firmware/efi/riscv-runtime.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 6ef2394be857..c8e57d77c144 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -412,7 +412,9 @@ config EFI select EFI_PARAMS_FROM_FDT select EFI_STUB select EFI_GENERIC_STUB + select EFI_RUNTIME_WRAPPERS select RISCV_ISA_C + depends on MMU default y help This option provides support for runtime services provided diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h index bf6a40e20a8e..7542282f1141 100644 --- a/arch/riscv/include/asm/efi.h +++ b/arch/riscv/include/asm/efi.h @@ -5,11 +5,28 @@ #ifndef _ASM_EFI_H #define _ASM_EFI_H +#include #include #include #include #include +#ifdef CONFIG_EFI +extern void efi_init(void); +#else +#define efi_init() +#endif + +int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); +int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); + +#define arch_efi_call_virt_setup() efi_virtmap_load() +#define arch_efi_call_virt_teardown() efi_virtmap_unload() + +#define arch_efi_call_virt(p, f, args...) p->f(args) + +#define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) + /* on RISC-V, the FDT may be located anywhere in system RAM */ static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) { @@ -32,4 +49,7 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) { } +void efi_virtmap_load(void); +void efi_virtmap_unload(void); + #endif /* _ASM_EFI_H */ diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h index 967eacb01ab5..dabcf2cfb3dc 100644 --- a/arch/riscv/include/asm/mmu.h +++ b/arch/riscv/include/asm/mmu.h @@ -20,6 +20,8 @@ typedef struct { #endif } mm_context_t; +void __init create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, + phys_addr_t sz, pgprot_t prot); #endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_MMU_H */ diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 815f8c959dd4..183f1f4b2ae6 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -100,6 +100,10 @@ #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) +#define PAGE_KERNEL_READ __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) +#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) +#define PAGE_KERNEL_READ_EXEC __pgprot((_PAGE_KERNEL & ~_PAGE_WRITE) \ + | _PAGE_EXEC) #define PAGE_TABLE __pgprot(_PAGE_TABLE) diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index dc93710f0b2f..fa896c5f7ccb 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -55,4 +55,6 @@ obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o +obj-$(CONFIG_EFI) += efi.o + clean: diff --git a/arch/riscv/kernel/efi.c b/arch/riscv/kernel/efi.c new file mode 100644 index 000000000000..024159298231 --- /dev/null +++ b/arch/riscv/kernel/efi.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + * Adapted from arch/arm64/kernel/efi.c + */ + +#include +#include + +#include +#include +#include + +/* + * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be + * executable, everything else can be mapped with the XN bits + * set. Also take the new (optional) RO/XP bits into account. + */ +static __init pgprot_t efimem_to_pgprot_map(efi_memory_desc_t *md) +{ + u64 attr = md->attribute; + u32 type = md->type; + + if (type == EFI_MEMORY_MAPPED_IO) + return PAGE_KERNEL; + + /* R-- */ + if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) == + (EFI_MEMORY_XP | EFI_MEMORY_RO)) + return PAGE_KERNEL_READ; + + /* R-X */ + if (attr & EFI_MEMORY_RO) + return PAGE_KERNEL_READ_EXEC; + + /* RW- */ + if (((attr & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP)) == + EFI_MEMORY_XP) || + type != EFI_RUNTIME_SERVICES_CODE) + return PAGE_KERNEL; + + /* RWX */ + return PAGE_KERNEL_EXEC; +} + +int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) +{ + pgprot_t prot = __pgprot(pgprot_val(efimem_to_pgprot_map(md)) & + ~(_PAGE_GLOBAL)); + int i; + + /* RISC-V maps one page at a time */ + for (i = 0; i < md->num_pages; i++) + create_pgd_mapping(mm->pgd, md->virt_addr + i * PAGE_SIZE, + md->phys_addr + i * PAGE_SIZE, + PAGE_SIZE, prot); + return 0; +} + +static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data) +{ + efi_memory_desc_t *md = data; + pte_t pte = READ_ONCE(*ptep); + unsigned long val; + + if (md->attribute & EFI_MEMORY_RO) { + val = pte_val(pte) & ~_PAGE_WRITE; + val = pte_val(pte) | _PAGE_READ; + pte = __pte(val); + } + if (md->attribute & EFI_MEMORY_XP) { + val = pte_val(pte) & ~_PAGE_EXEC; + pte = __pte(val); + } + set_pte(ptep, pte); + + return 0; +} + +int __init efi_set_mapping_permissions(struct mm_struct *mm, + efi_memory_desc_t *md) +{ + BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && + md->type != EFI_RUNTIME_SERVICES_DATA); + + /* + * Calling apply_to_page_range() is only safe on regions that are + * guaranteed to be mapped down to pages. Since we are only called + * for regions that have been mapped using efi_create_mapping() above + * (and this is checked by the generic Memory Attributes table parsing + * routines), there is no need to check that again here. + */ + return apply_to_page_range(mm, md->virt_addr, + md->num_pages << EFI_PAGE_SHIFT, + set_permissions, md); +} diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 41ef96d0d97a..4c96ac198e14 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -26,11 +27,12 @@ #include #include #include +#include #include "head.h" -#ifdef CONFIG_DUMMY_CONSOLE -struct screen_info screen_info = { +#if defined(CONFIG_DUMMY_CONSOLE) || defined(CONFIG_EFI) +struct screen_info screen_info __section(.data) = { .orig_video_lines = 30, .orig_video_cols = 80, .orig_video_mode = 0, @@ -75,6 +77,7 @@ void __init setup_arch(char **cmdline_p) early_ioremap_setup(); parse_early_param(); + efi_init(); setup_bootmem(); paging_init(); #if IS_ENABLED(CONFIG_BUILTIN_DTB) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 63acc8185bfa..c888c4470b34 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -390,7 +390,7 @@ static void __init create_pmd_mapping(pmd_t *pmdp, #define fixmap_pgd_next fixmap_pte #endif -static void __init create_pgd_mapping(pgd_t *pgdp, +void __init create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, phys_addr_t sz, pgprot_t prot) { diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 61fd1e8b26fb..4d628081bb2f 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -35,6 +35,8 @@ fake_map-$(CONFIG_X86) += x86_fake_mem.o arm-obj-$(CONFIG_EFI) := efi-init.o arm-runtime.o obj-$(CONFIG_ARM) += $(arm-obj-y) obj-$(CONFIG_ARM64) += $(arm-obj-y) +riscv-obj-$(CONFIG_EFI) := efi-init.o riscv-runtime.o +obj-$(CONFIG_RISCV) += $(riscv-obj-y) obj-$(CONFIG_EFI_CAPSULE_LOADER) += capsule-loader.o obj-$(CONFIG_EFI_EARLYCON) += earlycon.o obj-$(CONFIG_UEFI_CPER_ARM) += cper-arm.o diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 311a16802dd6..914a343c7785 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -17,7 +17,10 @@ /* * This is the base address at which to start allocating virtual memory ranges - * for UEFI Runtime Services. This is in the low TTBR0 range so that we can use + * for UEFI Runtime Services. + * + * For ARM/ARM64: + * This is in the low TTBR0 range so that we can use * any allocation we choose, and eliminate the risk of a conflict after kexec. * The value chosen is the largest non-zero power of 2 suitable for this purpose * both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can @@ -25,6 +28,12 @@ * Since 32-bit ARM could potentially execute with a 1G/3G user/kernel split, * map everything below 1 GB. (512 MB is a reasonable upper bound for the * entire footprint of the UEFI runtime services memory regions) + * + * For RISC-V: + * There is no specific reason for which, this address (512MB) can't be used + * EFI runtime virtual address for RISC-V. It also helps to use EFI runtime + * services on both RV32/RV64. Keep the same runtime virtual address for RISC-V + * as well to minimize the code churn. */ #define EFI_RT_VIRTUAL_BASE SZ_512M #define EFI_RT_VIRTUAL_SIZE SZ_512M diff --git a/drivers/firmware/efi/riscv-runtime.c b/drivers/firmware/efi/riscv-runtime.c new file mode 100644 index 000000000000..d28e715d2bcc --- /dev/null +++ b/drivers/firmware/efi/riscv-runtime.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Extensible Firmware Interface + * + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + * + * Based on Extensible Firmware Interface Specification version 2.4 + * Adapted from drivers/firmware/efi/arm-runtime.c + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static bool __init efi_virtmap_init(void) +{ + efi_memory_desc_t *md; + + efi_mm.pgd = pgd_alloc(&efi_mm); + mm_init_cpumask(&efi_mm); + init_new_context(NULL, &efi_mm); + + for_each_efi_memory_desc(md) { + phys_addr_t phys = md->phys_addr; + int ret; + + if (!(md->attribute & EFI_MEMORY_RUNTIME)) + continue; + if (md->virt_addr == 0) + return false; + + ret = efi_create_mapping(&efi_mm, md); + if (ret) { + pr_warn(" EFI remap %pa: failed to create mapping (%d)\n", + &phys, ret); + return false; + } + } + + if (efi_memattr_apply_permissions(&efi_mm, efi_set_mapping_permissions)) + return false; + + return true; +} + +/* + * Enable the UEFI Runtime Services if all prerequisites are in place, i.e., + * non-early mapping of the UEFI system table and virtual mappings for all + * EFI_MEMORY_RUNTIME regions. + */ +static int __init riscv_enable_runtime_services(void) +{ + u64 mapsize; + + if (!efi_enabled(EFI_BOOT)) { + pr_info("EFI services will not be available.\n"); + return 0; + } + + efi_memmap_unmap(); + + mapsize = efi.memmap.desc_size * efi.memmap.nr_map; + + if (efi_memmap_init_late(efi.memmap.phys_map, mapsize)) { + pr_err("Failed to remap EFI memory map\n"); + return 0; + } + + if (efi_soft_reserve_enabled()) { + efi_memory_desc_t *md; + + for_each_efi_memory_desc(md) { + int md_size = md->num_pages << EFI_PAGE_SHIFT; + struct resource *res; + + if (!(md->attribute & EFI_MEMORY_SP)) + continue; + + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (WARN_ON(!res)) + break; + + res->start = md->phys_addr; + res->end = md->phys_addr + md_size - 1; + res->name = "Soft Reserved"; + res->flags = IORESOURCE_MEM; + res->desc = IORES_DESC_SOFT_RESERVED; + + insert_resource(&iomem_resource, res); + } + } + + if (efi_runtime_disabled()) { + pr_info("EFI runtime services will be disabled.\n"); + return 0; + } + + if (efi_enabled(EFI_RUNTIME_SERVICES)) { + pr_info("EFI runtime services access via paravirt.\n"); + return 0; + } + + pr_info("Remapping and enabling EFI services.\n"); + + if (!efi_virtmap_init()) { + pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n"); + return -ENOMEM; + } + + /* Set up runtime services function pointers */ + efi_native_runtime_setup(); + set_bit(EFI_RUNTIME_SERVICES, &efi.flags); + + return 0; +} +early_initcall(riscv_enable_runtime_services); + +void efi_virtmap_load(void) +{ + preempt_disable(); + switch_mm(current->active_mm, &efi_mm, NULL); +} + +void efi_virtmap_unload(void) +{ + switch_mm(&efi_mm, current->active_mm, NULL); + preempt_enable(); +} From patchwork Thu Sep 17 22:37:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11783671 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 C8825112C for ; Thu, 17 Sep 2020 22:37:56 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 97CD72087D for ; Thu, 17 Sep 2020 22:37:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="izDYmeAl"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="HPMN5y4i" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 97CD72087D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=B8XCabI0G2rSV3u0e6aLT63udr01h1es1DWq8XeijNQ=; b=izDYmeAl7Fe/R3QyoDgPUgQEN 4uZusPAQD0PNPMsqNA7du+2IK3Hmvm+YGwZwWbqbjiK4/d+rOObthR7WZ9ykgEUIyLxdftZKqdE8g vTdb/9R7jWbPwEkai/5WCUzGqqllAsEMKNlEfTLRypSebJIt9Knc4r4Kta7x7zvhHKUX34Nd1Twsp gBEQyAEw/vLHZDL92Qnko1fAT87A6aJUhDMN/vSB9c6SCTXjiIdtGcnpdf13ElCITKmycnrAXcJV1 P88JW9Hbw5aYDdXESHkSUYrCHMMoM2kLXaZqrIvv5yvH0nByabuvQL0VjVsEW7WE8IiROnoqecR4Y v4L90aaLQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XJ-0005lm-SW; Thu, 17 Sep 2020 22:37:53 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kJ2XC-0005fc-Kx for linux-riscv@lists.infradead.org; Thu, 17 Sep 2020 22:37:48 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1600382266; x=1631918266; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=442DvRpDFEIcCxIif/4Q8FsTmegEl5WBXsmfapV7ChU=; b=HPMN5y4iiMS8wV8vDWJTJ7P/Wt4iNQJJkfN/YeHmuzqJxcbwWPe//QRy ZJ2Oc+GTR44DASZh+o2XYQfFeHkufjYcbA8gN+G+j5vBK9d9wxyiiKB91 W1mn6f6gVLNnLrbq5rIwlOF+/4XJjD4dDF4tFsUEeChmWnww4LSRF+aSw NYz8w23w1W9HMBAa8VLEQcCHYcocZ0wCJksDUH1V7EAzNVNXoTfEBKik3 nCCql7Lp8fYiGSGM9MtH3NMuCCEjdc/0iPG5vn7KS/RL391xn8teSMVkj SHX0wmF6b+fyHQDIJFZWlxa7xj9G9Gs6ywlHcTD0a4U5wkHuqrlS8Mh00 w==; IronPort-SDR: NZGKGOeRmY49rPoDCDg19csFrMkwsV3o+tabdYeW7kYORDb4DejF6AciPZF368zyJXtRPzdwMO D51lGfkVpx9uTSugGvsepAIKUSlZ9USNefQw9eQtaN9ke1J/At7/q0Oi9qMrGS7hiqS13UmdyQ Sc2uMHog237FwjWs3cep6nApokCLSBRNCgOSNHIISgt/YHmbi9jV6LBpZMLAKa7vJiGIj540Vx 15nArPP7FuuWjzJixiko1r6Azjby5cfp+cy7T40Fpwy+9DVCJ/WtVaDDas3r23g2C3nlFoo4vl I3E= X-IronPort-AV: E=Sophos;i="5.77,272,1596470400"; d="scan'208";a="257336261" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2020 06:37:43 +0800 IronPort-SDR: NtTpIw2z5aMlGj8FzvpgswwVxW0i/ihp/GttqkDx2/VGzDX2QtOs1XjOyqlTNFia7UyroNhSvv xibnBJ/tBOWQ== Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2020 15:23:57 -0700 IronPort-SDR: wrXIzonbackQ6e9XZnFifGX9ISPiDEGGrJezt3qkhBAlbQc65qc4Oo3JxmZ3qiEUgdqG4lhSUU qiYx3gppgXVw== WDCIronportException: Internal Received: from use204338.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.39]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Sep 2020 15:37:43 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v8 7/7] RISC-V: Add page table dump support for uefi Date: Thu, 17 Sep 2020 15:37:16 -0700 Message-Id: <20200917223716.2300238-8-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200917223716.2300238-1-atish.patra@wdc.com> References: <20200917223716.2300238-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_183746_869331_8F2FFA28 X-CRM114-Status: GOOD ( 16.93 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-efi@vger.kernel.org, Palmer Dabbelt , Atish Patra , Arvind Sankar , Maxim Uvarov , Alistair Francis , Zong Li , linux-riscv@lists.infradead.org, Ingo Molnar , Anup Patel , Masahiro Yamada , Michal Simek , Ard Biesheuvel , Greentime Hu , Borislav Petkov , Albert Ou , Kees Cook , Heiko Carstens , Paul Walmsley , Thomas Gleixner , Anup Patel , Nick Desaulniers , Palmer Dabbelt , Andrew Morton , Mike Rapoport Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org Extend the current page table dump support in RISC-V to include efi pages as well. Here is the output of efi runtime page table mappings. ---[ UEFI runtime start ]--- 0x0000000020002000-0x0000000020003000 0x00000000be732000 4K PTE D A . . . W R V 0x0000000020018000-0x0000000020019000 0x00000000be738000 4K PTE D A . . . W R V 0x000000002002c000-0x000000002002d000 0x00000000be73c000 4K PTE D A . . . W R V 0x0000000020031000-0x0000000020032000 0x00000000bff61000 4K PTE D A . . X W R V ---[ UEFI runtime end ]--- Signed-off-by: Atish Patra Reviewed-by: Anup Patel Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/ptdump.c | 48 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c index 0831c2e61a8f..ace74dec7492 100644 --- a/arch/riscv/mm/ptdump.c +++ b/arch/riscv/mm/ptdump.c @@ -3,6 +3,7 @@ * Copyright (C) 2019 SiFive */ +#include #include #include #include @@ -49,6 +50,14 @@ struct addr_marker { const char *name; }; +/* Private information for debugfs */ +struct ptd_mm_info { + struct mm_struct *mm; + const struct addr_marker *markers; + unsigned long base_addr; + unsigned long end; +}; + static struct addr_marker address_markers[] = { #ifdef CONFIG_KASAN {KASAN_SHADOW_START, "Kasan shadow start"}, @@ -68,6 +77,28 @@ static struct addr_marker address_markers[] = { {-1, NULL}, }; +static struct ptd_mm_info kernel_ptd_info = { + .mm = &init_mm, + .markers = address_markers, + .base_addr = KERN_VIRT_START, + .end = ULONG_MAX, +}; + +#ifdef CONFIG_EFI +static struct addr_marker efi_addr_markers[] = { + { 0, "UEFI runtime start" }, + { SZ_1G, "UEFI runtime end" }, + { -1, NULL } +}; + +static struct ptd_mm_info efi_ptd_info = { + .mm = &efi_mm, + .markers = efi_addr_markers, + .base_addr = 0, + .end = SZ_2G, +}; +#endif + /* Page Table Entry */ struct prot_bits { u64 mask; @@ -245,22 +276,22 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, } } -static void ptdump_walk(struct seq_file *s) +static void ptdump_walk(struct seq_file *s, struct ptd_mm_info *pinfo) { struct pg_state st = { .seq = s, - .marker = address_markers, + .marker = pinfo->markers, .level = -1, .ptdump = { .note_page = note_page, .range = (struct ptdump_range[]) { - {KERN_VIRT_START, ULONG_MAX}, + {pinfo->base_addr, pinfo->end}, {0, 0} } } }; - ptdump_walk_pgd(&st.ptdump, &init_mm, NULL); + ptdump_walk_pgd(&st.ptdump, pinfo->mm, NULL); } void ptdump_check_wx(void) @@ -293,7 +324,7 @@ void ptdump_check_wx(void) static int ptdump_show(struct seq_file *m, void *v) { - ptdump_walk(m); + ptdump_walk(m, m->private); return 0; } @@ -308,8 +339,13 @@ static int ptdump_init(void) for (j = 0; j < ARRAY_SIZE(pte_bits); j++) pg_level[i].mask |= pte_bits[j].mask; - debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, + debugfs_create_file("kernel_page_tables", 0400, NULL, &kernel_ptd_info, &ptdump_fops); +#ifdef CONFIG_EFI + if (efi_enabled(EFI_RUNTIME_SERVICES)) + debugfs_create_file("efi_page_tables", 0400, NULL, &efi_ptd_info, + &ptdump_fops); +#endif return 0; }