[PATCH 0/4] riscv: Enable kexec handover and live update
From: Chen Pei
Date: Fri Oct 23 2026 - 07:16:43 EST
Host kernel updates in the cloud should not require draining the
machine: next to live migration to another host, replacing the kernel
in place while preserving selected workload state ("live update") is
what KHO/LUO were built for, and LUO's documentation names hypervisor
hosts as its primary use case. This series closes the gap for riscv64
and validates it with both upstream test runners.
KHO has been architecture independent since it was merged: 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, and the
incoming kernel collects both while scanning that node -- which is why
the arm64 integration (commit 274cdcb1c004) needed only three lines of
arch code.
RISC-V already walks those same generic paths (load_extra_segments() ->
of_kexec_alloc_and_setup_fdt(), parse_dtb() -> early_init_dt_scan()).
The one real blocker is ordering: setup_arch() runs early_ioremap_setup()
*after* parse_dtb(), so kho_populate()'s early_memremap() of the handover
FDT returns "offset + 0" -- NULL for a page aligned address -- and the
handover is dropped:
KHO: setup: failed to memremap FDT (0x810bb000)
KHO: disabling KHO revival
Patch 1 fixes that ordering, matching arm64/x86 and standing on its own
regardless of KHO. Patch 2 enables ARCH_SUPPORTS_KEXEC_HANDOVER as
"def_bool 64BIT && MMU" rather than arm64's "def_bool y":
ARCH_SUPPORTS_KEXEC_FILE is already 64BIT-only, and KEXEC_HANDOVER
selects CMA, which depends on MMU. Patches 3 and 4 teach the two
upstream vmtest runners about riscv64. LIVEUPDATE depends only on
KEXEC_HANDOVER, so patch 2 makes it selectable on riscv as well.
No DT schema changes are needed: linux,kho-fdt / linux,kho-scratch are
the properties arm64 introduced (commit 274cdcb1c004), and their
binding lives in the external dt-schema repository [1] rather than in
Documentation.
[1] https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/chosen.yaml
Test
----
Testing on qemu-system-riscv64 (virt, -cpu max, TCG); method and logs
under the --- of patches 3 and 4:
- kho vmtest: "ok 1 KHO succeeded"
- liveupdate vmtest, all four suites PASSED (simple, multi-session,
500 files, 2000 sessions)
- riscv defconfig with and without CONFIG_KEXEC_HANDOVER both boot to
userspace unchanged; builds: riscv defconfig (+KHO), rv32_defconfig,
arm64, x86_64
Additionally, a workload-continuity test was run on the same setup,
outside the selftests: a counter process was snapshot with criu 4.3,
the dump was carried across the kexec in an LUO-preserved memfd, and
criu restored it in the new kernel. The process resumed with the same
PID and open log file and kept counting from where it was dumped
(500006 -> 500007, no lost or duplicated ticks).
Chen Pei (4):
riscv: Call early_ioremap_setup() before parsing the DTB
riscv: Add support for kexec handover (KHO)
selftests: kho: Add riscv support
selftests: liveupdate: Add riscv support
arch/riscv/Kconfig | 3 +++
arch/riscv/kernel/setup.c | 2 +-
tools/testing/selftests/kho/riscv.conf | 9 +++++++++
tools/testing/selftests/kho/vmtest.sh | 3 ++-
tools/testing/selftests/liveupdate/config.riscv64 | 3 +++
tools/testing/selftests/liveupdate/run-vmtests.sh | 2 +-
tools/testing/selftests/liveupdate/vmtest.sh | 8 +++++++-
7 files changed, 26 insertions(+), 4 deletions(-)
create mode 100644 tools/testing/selftests/kho/riscv.conf
create mode 100644 tools/testing/selftests/liveupdate/config.riscv64
--
2.50.1