From: "Yufan Dou" <douyufan@picoheart.com>
To: <pjw@kernel.org>, <palmer@dabbelt.com>, <aou@eecs.berkeley.edu>
Cc: <alex@ghiti.fr>, <leitao@debian.org>, <akpm@linux-foundation.org>,
<ajones@ventanamicro.com>, <lizhengyu3@huawei.com>,
<liaochang1@huawei.com>, <songshuaishuai@tinylab.org>,
<bjorn@rivosinc.com>, <gaohan@iscas.ac.cn>,
<douyufan@picoheart.com>, <linux-riscv@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <yang.yicong@picoheart.com>,
<weidong.wd@picoheart.com>, <geshijian@picoheart.com>
Subject: [PATCH RESEND 1/3] riscv: kexec_file: constrain extra segments to the Sv39 direct map
Date: Wed, 2 Sep 2026 17:08:48 +0800 [thread overview]
Message-ID: <20260902090850.2601-2-douyufan@picoheart.com> (raw)
In-Reply-To: <20260902090850.2601-1-douyufan@picoheart.com>
When an Sv48 or Sv57 kernel loads an Sv39 kernel, top-down allocation
can place the initrd and other extra segments above the direct-map
range supported by the next kernel.
During early boot, setup_bootmem() limits usable memory to
phys_ram_base + KERN_VIRT_SIZE. Any segment placed above the Sv39 limit
is therefore unreachable by the next kernel. In particular, an initrd
outside this range is disabled during boot.
The max_low_pfn limit only reflects the direct map of the loading kernel
and is insufficient when the next kernel uses a narrower address space.
The paging mode of the next kernel is not known at load time, so apply
the Sv39 limit unconditionally. On a machine with more than 128 GiB this
also constrains a next kernel that would run in Sv48 or Sv57.
Limit extra segment placement to the smaller of the loading kernel's
direct-map limit and the end of the Sv39 direct map. The next kernel
derives its direct map from the start of the memory it is given, which
is the crash kernel region for a crash image, so use that region as the
base in that case. A NOMMU kernel has no direct map and keeps the limit
of the loading kernel.
Fixes: b67a1ee0db00 ("riscv: kexec_file: Constrain segment placement to direct map")
Co-developed-by: Yicong Yang <yang.yicong@picoheart.com>
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
Signed-off-by: Yufan Dou <douyufan@picoheart.com>
---
arch/riscv/kernel/machine_kexec_file.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c
index 26cd2a8bd0cd..15a3c180c558 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -239,6 +239,29 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
}
+/*
+ * The next kernel may run in Sv39 even when the current kernel runs in Sv48 or
+ * Sv57, in which case the direct map of the next kernel is narrower. Any
+ * segment placed above it is unreachable by the next kernel during early boot.
+ * The next kernel derives its direct map from the start of the memory it is
+ * given, which is the crash kernel region for a crash image. A NOMMU kernel
+ * has no direct map, so only the limit of the current kernel applies.
+ */
+static unsigned long kexec_segment_limit(struct kimage *image)
+{
+ unsigned long limit = PFN_PHYS(max_low_pfn);
+#ifdef CONFIG_MMU
+ unsigned long base = phys_ram_base;
+
+#ifdef CONFIG_CRASH_DUMP
+ if (image->type == KEXEC_TYPE_CRASH)
+ base = crashk_res.start;
+#endif
+ limit = min(limit, base + BIT(VA_BITS_SV39 - 2) - 1);
+#endif
+ return limit;
+}
+
int load_extra_segments(struct kimage *image, unsigned long kernel_start,
unsigned long kernel_len, char *initrd,
unsigned long initrd_len, char *cmdline,
@@ -252,7 +275,7 @@ int load_extra_segments(struct kimage *image, unsigned long kernel_start,
kbuf.image = image;
kbuf.buf_min = kernel_start + kernel_len;
- kbuf.buf_max = PFN_PHYS(max_low_pfn);
+ kbuf.buf_max = kexec_segment_limit(image);
#ifdef CONFIG_CRASH_DUMP
/* Add elfcorehdr */
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2026-09-02 9:09 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 9:08 [PATCH RESEND 0/3] Fix kexec_file segment placement on RISC-V Yufan Dou
2026-09-02 9:08 ` Yufan Dou [this message]
2026-09-02 9:08 ` [PATCH RESEND 2/3] riscv: kexec_file: size the ELF placement search by the load extent Yufan Dou
2026-09-02 9:08 ` [PATCH RESEND 3/3] riscv: kexec: reserve the PMD-aligned kernel image range Yufan Dou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260902090850.2601-2-douyufan@picoheart.com \
--to=douyufan@picoheart.com \
--cc=ajones@ventanamicro.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=bjorn@rivosinc.com \
--cc=gaohan@iscas.ac.cn \
--cc=geshijian@picoheart.com \
--cc=leitao@debian.org \
--cc=liaochang1@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=lizhengyu3@huawei.com \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=songshuaishuai@tinylab.org \
--cc=weidong.wd@picoheart.com \
--cc=yang.yicong@picoheart.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox