* [PATCH 1/4] riscv: Call early_ioremap_setup() before parsing the DTB
2026-10-23 11:16 [PATCH 0/4] riscv: Enable kexec handover and live update Chen Pei
@ 2026-10-23 11:16 ` Chen Pei
2026-10-23 11:16 ` [PATCH 2/4] riscv: Add support for kexec handover (KHO) Chen Pei
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Chen Pei @ 2026-10-23 11:16 UTC (permalink / raw)
To: pjw, palmer, alex, rppt, pasha.tatashin, pratyush, graf, shuah
Cc: guoren, linux-riscv, linux-kernel, linux-mm, linux-kselftest, kexec
early_ioremap_setup() fills in the slot_virt[] array whose entries the
return value of early_ioremap()/early_memremap() is composed from. On
RISC-V it ran after parse_dtb(), so an early_memremap() reached from
the device tree scan returned "offset + 0" -- NULL for a page aligned
address -- and the caller could only report a mapping failure. This
stayed latent because nothing reached from parse_dtb() asked for an
early mapping before; the DT based kexec handover parsing is the first
such caller, as kho_populate() maps the handover FDT and the scratch
descriptor array with early_memremap().
Move the call to the top of setup_arch(), which is how arm64 and x86
already order it (early_fixmap_init()/early_ioremap_init() before
setup_machine_fdt()/parse_setup_data()). The BTMAP window is mapped
into early_pg_dir by setup_vm(), and RISC-V neither calls
early_ioremap_reset() nor defines __late_set_fixmap(), so the virtual
addresses stay identical across the switch to the final page tables
and nothing else in setup_arch() depends on the previous ordering.
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
arch/riscv/kernel/setup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index d79f99b86033..45e2ef9d32fa 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -308,12 +308,12 @@ extern void __init init_rt_signal_env(void);
void __init setup_arch(char **cmdline_p)
{
+ early_ioremap_setup();
parse_dtb();
setup_initial_init_mm(_stext, _etext, _edata, _end);
*cmdline_p = boot_command_line;
- early_ioremap_setup();
sbi_init();
jump_label_init();
parse_early_param();
--
2.50.1
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/4] riscv: Add support for kexec handover (KHO)
2026-10-23 11:16 [PATCH 0/4] riscv: Enable kexec handover and live update Chen Pei
2026-10-23 11:16 ` [PATCH 1/4] riscv: Call early_ioremap_setup() before parsing the DTB Chen Pei
@ 2026-10-23 11:16 ` Chen Pei
2026-10-23 11:16 ` [PATCH 3/4] selftests: kho: Add riscv support Chen Pei
2026-10-23 11:16 ` [PATCH 4/4] selftests: liveupdate: " Chen Pei
3 siblings, 0 replies; 5+ messages in thread
From: Chen Pei @ 2026-10-23 11:16 UTC (permalink / raw)
To: pjw, palmer, alex, rppt, pasha.tatashin, pratyush, graf, shuah
Cc: guoren, linux-riscv, linux-kernel, linux-mm, linux-kselftest, kexec
KHO is architecture independent: the outgoing kernel publishes the
handover FDT and the scratch descriptor array in the /chosen node of
the DTB it builds for the incoming kernel (kho_add_chosen(), reached
from of_kexec_alloc_and_setup_fdt()), and the incoming kernel picks
both up while scanning that node (early_init_dt_check_kho() ->
kho_populate()).
RISC-V already builds that DTB in load_extra_segments() and passes it
to the incoming kernel in a1, so only the architecture symbol is
missing. Depend on 64BIT to match ARCH_SUPPORTS_KEXEC_FILE, and on
MMU because KEXEC_HANDOVER selects CMA, which depends on MMU.
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
arch/riscv/Kconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5874ca30f4f6..4f7d2f3f80b1 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -1125,6 +1125,9 @@ config ARCH_SELECTS_KEXEC_FILE
config ARCH_SUPPORTS_KEXEC_PURGATORY
def_bool ARCH_SUPPORTS_KEXEC_FILE
+config ARCH_SUPPORTS_KEXEC_HANDOVER
+ def_bool 64BIT && MMU
+
config ARCH_SUPPORTS_CRASH_DUMP
def_bool y
--
2.50.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/4] selftests: kho: Add riscv support
2026-10-23 11:16 [PATCH 0/4] riscv: Enable kexec handover and live update Chen Pei
2026-10-23 11:16 ` [PATCH 1/4] riscv: Call early_ioremap_setup() before parsing the DTB Chen Pei
2026-10-23 11:16 ` [PATCH 2/4] riscv: Add support for kexec handover (KHO) Chen Pei
@ 2026-10-23 11:16 ` Chen Pei
2026-10-23 11:16 ` [PATCH 4/4] selftests: liveupdate: " Chen Pei
3 siblings, 0 replies; 5+ messages in thread
From: Chen Pei @ 2026-10-23 11:16 UTC (permalink / raw)
To: pjw, palmer, alex, rppt, pasha.tatashin, pratyush, graf, shuah
Cc: guoren, linux-riscv, linux-kernel, linux-mm, linux-kselftest, kexec
Teach the KHO vmtest runner about riscv64: map the target to ARCH
riscv and describe the QEMU virt machine, the kernel image and its
console -- a 16550A port probed from the device tree on virt, hence
the SERIAL_8250{,_CONSOLE} and SERIAL_OF_PLATFORM symbols. Also
select CONFIG_SPARSEMEM_MANUAL: the runner requires
CONFIG_DEFERRED_STRUCT_PAGE_INIT, which depends on SPARSEMEM, while
riscv falls back to FLATMEM (no ARCH_SPARSEMEM_DEFAULT), so without
it the test would just be skipped.
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
Test: qemu-system-riscv64 (virt, -cpu max, TCG), in-tree runner
"tools/testing/selftests/kho/vmtest.sh -t riscv64" (boots the Image
and kexec'es into the same Image).
KHO: found kexec handover data.
KHO: exec from: 7.3.0-rc7-00108-gc6e90ee4ccbb (count 1)
test_kho: KHO restore succeeded
ok 1 KHO succeeded
# Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0
tools/testing/selftests/kho/riscv.conf | 9 +++++++++
tools/testing/selftests/kho/vmtest.sh | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/kho/riscv.conf
diff --git a/tools/testing/selftests/kho/riscv.conf b/tools/testing/selftests/kho/riscv.conf
new file mode 100644
index 000000000000..ec2a46cd45d5
--- /dev/null
+++ b/tools/testing/selftests/kho/riscv.conf
@@ -0,0 +1,9 @@
+QEMU_CMD="qemu-system-riscv64 -M virt -cpu max"
+QEMU_KCONFIG="
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SPARSEMEM_MANUAL=y
+"
+KERNEL_IMAGE="Image"
+KERNEL_CMDLINE="console=ttyS0"
diff --git a/tools/testing/selftests/kho/vmtest.sh b/tools/testing/selftests/kho/vmtest.sh
index 0014bd76e88d..325af59f653a 100755
--- a/tools/testing/selftests/kho/vmtest.sh
+++ b/tools/testing/selftests/kho/vmtest.sh
@@ -21,7 +21,7 @@ Options:
-d) path to the kernel build directory
-j) number of jobs for compilation, similar to -j in make
-t) run test for target_arch, requires CROSS_COMPILE set
- supported targets: aarch64, x86_64
+ supported targets: aarch64, x86_64, riscv64
-h) display this help
EOF
}
@@ -127,6 +127,7 @@ function target_to_arch() {
case $target in
aarch64) echo "arm64" ;;
x86_64) echo "x86" ;;
+ riscv64) echo "riscv" ;;
*) skip "architecture $target is not supported"
esac
}
--
2.50.1
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 4/4] selftests: liveupdate: Add riscv support
2026-10-23 11:16 [PATCH 0/4] riscv: Enable kexec handover and live update Chen Pei
` (2 preceding siblings ...)
2026-10-23 11:16 ` [PATCH 3/4] selftests: kho: Add riscv support Chen Pei
@ 2026-10-23 11:16 ` Chen Pei
3 siblings, 0 replies; 5+ messages in thread
From: Chen Pei @ 2026-10-23 11:16 UTC (permalink / raw)
To: pjw, palmer, alex, rppt, pasha.tatashin, pratyush, graf, shuah
Cc: guoren, linux-riscv, linux-kernel, linux-mm, linux-kselftest, kexec
Teach the live update vmtest runner about riscv64: map the target to ARCH
riscv, describe the QEMU virt machine, the kernel image and its console,
and add the arch config fragment holding the three symbols needed to get
a console on the virt machine's 16550A port.
KHO is the only dependency of LIVEUPDATE (kernel/liveupdate/Kconfig), so
now that riscv has KHO the LUO tests only need the runner to stop
rejecting the architecture.
Add riscv64 to the CROSS_COMPILE auto-detection list and to the target
list of the batch runner as well, matching the existing aarch64/x86_64
entries.
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
Test: qemu-system-riscv64 (virt, -cpu max, -m 1G, -smp 2, TCG), in-tree
runner "tools/testing/selftests/liveupdate/vmtest.sh -t riscv64 -T <suite>",
all four suites:
luo_kexec_simple: SIMPLE KEXEC TEST PASSED
luo_multi_session: MULTI-SESSION KEXEC TEST PASSED
luo_stress_files: MANY-FILES KEXEC TEST PASSED (500 files)
luo_stress_sessions: MANY-SESSIONS KEXEC TEST PASSED (2000 sessions)
The simple suite's serial log shows the full handover round trip:
KHO: found kexec handover data.
luo: Retrieved live update data, liveupdate number: 1
# [STAGE 2] Test data verified successfully.
--- SIMPLE KEXEC TEST PASSED ---
tools/testing/selftests/liveupdate/config.riscv64 | 3 +++
tools/testing/selftests/liveupdate/run-vmtests.sh | 2 +-
tools/testing/selftests/liveupdate/vmtest.sh | 8 +++++++-
3 files changed, 11 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/liveupdate/config.riscv64
diff --git a/tools/testing/selftests/liveupdate/config.riscv64 b/tools/testing/selftests/liveupdate/config.riscv64
new file mode 100644
index 000000000000..edbc551199b0
--- /dev/null
+++ b/tools/testing/selftests/liveupdate/config.riscv64
@@ -0,0 +1,3 @@
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
diff --git a/tools/testing/selftests/liveupdate/run-vmtests.sh b/tools/testing/selftests/liveupdate/run-vmtests.sh
index d656ce58c5a7..2e3f5f6f96b3 100755
--- a/tools/testing/selftests/liveupdate/run-vmtests.sh
+++ b/tools/testing/selftests/liveupdate/run-vmtests.sh
@@ -4,7 +4,7 @@
SCRIPT_DIR=$(dirname "$(realpath "$0")")
TEST_RUNNER="$SCRIPT_DIR/vmtest.sh"
-TARGETS=("x86_64" "aarch64")
+TARGETS=("x86_64" "aarch64" "riscv64")
GREEN='\033[0;32m'
RED='\033[0;31m'
diff --git a/tools/testing/selftests/liveupdate/vmtest.sh b/tools/testing/selftests/liveupdate/vmtest.sh
index 64fd2ab55b76..ee554d889e1b 100755
--- a/tools/testing/selftests/liveupdate/vmtest.sh
+++ b/tools/testing/selftests/liveupdate/vmtest.sh
@@ -25,6 +25,10 @@ function get_arch_conf() {
QEMU_CMD="qemu-system-x86_64"
KERNEL_IMAGE="bzImage"
KERNEL_CMDLINE="console=ttyS0"
+ elif [[ "$arch" == "riscv" ]]; then
+ QEMU_CMD="qemu-system-riscv64 -M virt -cpu max"
+ KERNEL_IMAGE="Image"
+ KERNEL_CMDLINE="console=ttyS0"
else
echo "Unsupported architecture: $arch"
exit 1
@@ -37,7 +41,7 @@ $0 [-d build_dir] [-j jobs] [-t target_arch] [-T test_name] [-w workspace_dir] [
Options:
-d) path to the kernel build directory (default: .luo_test_build.<arch>)
-j) number of jobs for compilation
- -t) run test for target_arch (aarch64, x86_64)
+ -t) run test for target_arch (aarch64, x86_64, riscv64)
-T) test name to run (default: luo_kexec_simple)
-w) custom workspace directory (default: creates temp dir)
-k) keep workspace directory after successful test
@@ -87,6 +91,7 @@ function detect_cross_compile() {
case "$target" in
aarch64) candidate="aarch64-linux-gnu-" ;;
x86_64) candidate="x86_64-linux-gnu-" ;;
+ riscv64) candidate="riscv64-linux-gnu-" ;;
*) skip "Auto-detection for target '$target' not supported. Please set CROSS_COMPILE manually." ;;
esac
@@ -194,6 +199,7 @@ function target_to_arch() {
case $target in
aarch64) echo "arm64" ;;
x86_64) echo "x86" ;;
+ riscv64) echo "riscv" ;;
*) skip "architecture $target is not supported"
esac
}
--
2.50.1
^ permalink raw reply [flat|nested] 5+ messages in thread