From patchwork Wed Apr 9 18:21:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?QmrDtnJuIFTDtnBlbA==?= X-Patchwork-Id: 14045225 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 55832C36002 for ; Wed, 9 Apr 2025 18:21:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=SncdOba4pLzbKjDBaF14vta3P0w2iI6GkSz9DXEvjbI=; b=SHg593Crda9132 p7oVDzujAItqRd6eaqdUyuy64/Ex3LTNt+GKS11p9gkbtxpIQJQAy2zz9/VCy+caELkmjVqbk0D1B pWk4b685qlTf/Iv4JsJnbcVC1zKXhi2kCdcULcD3YPWiT84aXrnzwc4aHR+X2nJwjkzNX6oPKrOsq rxY27Iu8lj9mmnspZxIiduRpLzeousRfRh5PZSBRayDED1CWpxRgJ9qqi2J3W5hf+258ruEKrJ1xe gfA5wcZJYKjfo1eTncQsrl4eH2sG5gZCWO62FT8XXL+0saTSB+BBWRhqGqVVo4+ve5i7/g+CUZBK1 QHbD8vUbzYHRZNZIEN/w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1u2a3Q-000000089ai-1H7j; Wed, 09 Apr 2025 18:21:40 +0000 Received: from nyc.source.kernel.org ([147.75.193.91]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1u2a3N-000000089a8-2Etv for linux-riscv@lists.infradead.org; Wed, 09 Apr 2025 18:21:39 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id A9115A49AB5; Wed, 9 Apr 2025 18:16:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1E29FC4CEE2; Wed, 9 Apr 2025 18:21:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1744222896; bh=rF/4ACsIG/tFNbGRO5wYRJcR4xBaQIyDKKhb987ERh4=; h=From:To:Cc:Subject:Date:From; b=E3oGybFgZtJlcpFYB1nP9daP5Y7GT1NLQn5PqAFqpB3CfHPMzeogJn5RVK/rEkVmY QiKQGIIH0a2MrLhZknbavuqM/KVPneU4io5Mqq3iYgbBDZxape/5JmM67z/k2SZ+ik 5DiBEPymTtxujlszDrYdWNNffNbT/sECvg+nuEepFb8uWFaDZrhhJEe62HN2ZnpI75 fXlz/9VApoFedhxBm2OIqFMVa41/6wDZz90/VxCXzr/8grn7y0Y4i4I/9E2Y5NImGL 8RzV51jPUa0fdTm0saXYA6KRygSE6G/YzvMrUYQtCsqikt2rVLSheXXM9DORj+UFbU tnZ35Bj1P1TSQ== From: =?utf-8?b?QmrDtnJuIFTDtnBlbA==?= To: Paul Walmsley , Palmer Dabbelt , Alexandre Ghiti , Nick Kossifidis , linux-riscv@lists.infradead.org Cc: =?utf-8?b?QmrDtnJuIFTDtnBlbA==?= , linux-kernel@vger.kernel.org Subject: [PATCH fixes] riscv: Properly export reserved regions in /proc/iomem Date: Wed, 9 Apr 2025 20:21:27 +0200 Message-ID: <20250409182129.634415-1-bjorn@kernel.org> X-Mailer: git-send-email 2.45.2 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250409_112137_711446_480E3DDC X-CRM114-Status: GOOD ( 18.88 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org From: Björn Töpel The /proc/iomem represents the kernel's memory map. Regions marked with "Reserved" tells the user that the range should not be tampered with. Kexec-tools, when using the older kexec_load syscall relies on the "Reserved" regions to build the memory segments, that will be the target of the new kexec'd kernel. The RISC-V port tries to expose all reserved regions to userland, but some regions were not properly exposed: Regions that resided in both the "regular" and reserved memory block, e.g. the EFI Memory Map. A missing entry could result in reserved memory being overwritten. It turns out, that arm64, and loongarch had a similar issue a while back: commit d91680e687f4 ("arm64: Fix /proc/iomem for reserved but not memory regions") commit 50d7ba36b916 ("arm64: export memblock_reserve()d regions via /proc/iomem") Similar to the other ports, resolve the issue by splitting the regions in an arch initcall, since we need a working allocator. Fixes: ffe0e5261268 ("RISC-V: Improve init_resources()") Signed-off-by: Björn Töpel Reviewed-by: Alexandre Ghiti --- arch/riscv/kernel/setup.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) base-commit: a24588245776dafc227243a01bfbeb8a59bafba9 diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index c174544eefc8..f7c9a1caa83e 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -66,6 +66,9 @@ static struct resource bss_res = { .name = "Kernel bss", }; static struct resource elfcorehdr_res = { .name = "ELF Core hdr", }; #endif +static int num_standard_resources; +static struct resource *standard_resources; + static int __init add_resource(struct resource *parent, struct resource *res) { @@ -139,7 +142,7 @@ static void __init init_resources(void) struct resource *res = NULL; struct resource *mem_res = NULL; size_t mem_res_sz = 0; - int num_resources = 0, res_idx = 0; + int num_resources = 0, res_idx = 0, non_resv_res = 0; int ret = 0; /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */ @@ -193,6 +196,7 @@ static void __init init_resources(void) /* Add /memory regions to the resource tree */ for_each_mem_region(region) { res = &mem_res[res_idx--]; + non_resv_res++; if (unlikely(memblock_is_nomap(region))) { res->name = "Reserved"; @@ -210,6 +214,9 @@ static void __init init_resources(void) goto error; } + num_standard_resources = non_resv_res; + standard_resources = &mem_res[res_idx + 1]; + /* Clean-up any unused pre-allocated resources */ if (res_idx >= 0) memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res)); @@ -221,6 +228,33 @@ static void __init init_resources(void) memblock_free(mem_res, mem_res_sz); } +static int __init reserve_memblock_reserved_regions(void) +{ + u64 i, j; + + for (i = 0; i < num_standard_resources; i++) { + struct resource *mem = &standard_resources[i]; + phys_addr_t r_start, r_end, mem_size = resource_size(mem); + + if (!memblock_is_region_reserved(mem->start, mem_size)) + continue; + + for_each_reserved_mem_range(j, &r_start, &r_end) { + resource_size_t start, end; + + start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start); + end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end); + + if (start > mem->end || end < mem->start) + continue; + + reserve_region_with_split(mem, start, end, "Reserved"); + } + } + + return 0; +} +arch_initcall(reserve_memblock_reserved_regions); static void __init parse_dtb(void) {