Skip to contentSkip to conversation

PATCH Superseded George Guo 2 participants 6 messages May 29 – May 31

Subsystems (5)

v2 of 6 Superseded Latest is v6 →

lore
Share & tools
lore

George Guo

author
#0 lore raw

From: George Guo <[email protected]>

WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?) #26:
containing only /chosen with the two KHO properties. Since DEVICE_TREE_GUID

ERROR: Invalid commit separator - some tools may have problems applying this #34:
-------------------------------

total: 2 errors, 1 warnings, 0 lines checked

Quoted 1 line

Date: Fri, 29 May 2026 21:54:01 +0800
Subject: [PATCH v2 0/4] LoongArch: add KHO support and selftests

This series adds Kexec Handover (KHO) support for LoongArch and extends the KHO selftest infrastructure to run on LoongArch under QEMU.

KHO passes metadata (the KHO state FDT and scratch area addresses) to the second kernel via the FDT /chosen node, using the linux,kho-fdt and linux,kho-scratch properties that drivers/of/kexec.c:kho_add_chosen() writes and drivers/of/fdt.c:early_init_dt_check_kho() reads.

KHO support (patches 1-2):

Patch 1 adds KHO support for FDT-based systems (initial_boot_params != NULL, e.g. QEMU virt without OVMF). kho_load_fdt() copies the running kernel's FDT, appends linux,kho-fdt and linux,kho-scratch to /chosen, and loads the result as a kexec segment. machine_kexec() updates the DEVICE_TREE_GUID entry in the EFI config table to point to this segment so the second kernel's fdt_setup() can find and parse it.

Patch 2 adds KHO support for ACPI-only systems (initial_boot_params == NULL, e.g. LoongArch servers with UEFI or QEMU with OVMF). Because no system FDT is available, kho_load_fdt() builds a minimal FDT from scratch containing only /chosen with the two KHO properties. Since DEVICE_TREE_GUID is absent from the EFI config table on ACPI-only systems, a new extended config table is built with the entry appended and loaded as a kexec segment; machine_kexec() switches st->tables to point to it before jumping. The second kernel's fdt_setup() calls efi_fdt_pointer() to detect the KHO FDT and passes it to early_init_dt_check_kho().

Selftest support (patches 3-4):

Patch 3 adds loongarch.conf and extends vmtest.sh to recognise loongarch64 as a build target. The LoongArch virt machine is FDT-only (no ACPI), so 'earlycon' must appear on the kernel cmdline or the console UART is never discovered. PS/2 input devices are also disabled since QEMU's LoongArch virt machine has no i8042 controller; the fallback port probe hits a page fault and panics before reaching userspace.

Patch 4 handles QEMU not exiting after kexec on LoongArch. QEMU provides no EFI runtime services, so machine_restart() falls through to an infinite idle loop. QEMU_NEEDS_KILL=1 in loongarch.conf signals vmtest.sh to run QEMU in the background, poll the serial output for the test verdict, and kill QEMU once it appears, so the test completes unattended.

George Guo (4):
LoongArch: kexec: add KHO support for FDT-based systems
LoongArch: kexec: add KHO support for ACPI-only systems selftests/kho: add LoongArch vmtest support selftests/kho: handle QEMU not exiting after kexec on LoongArch

 arch/loongarch/Kconfig                     |   3 +
 arch/loongarch/include/asm/kexec.h         |   7 +
 arch/loongarch/kernel/machine_kexec.c      |  38 +++
 arch/loongarch/kernel/machine_kexec_file.c | 256 +++++++++++++++++++++
 arch/loongarch/kernel/setup.c              |  21 +-
 tools/testing/selftests/kho/loongarch.conf |  13 ++
 tools/testing/selftests/kho/vmtest.sh      |  35 ++-
 7 files changed, 365 insertions(+), 8 deletions(-)
 create mode 100644 tools/testing/selftests/kho/loongarch.conf
Signature · 1 line
2.25.1
author
#1 lore raw

PATCH v2 1/4 LoongArch: kexec: add KHO support for FDT-based systems

From: George Guo <[email protected]>

Enable Kexec Handover (KHO) on LoongArch64 for FDT-based systems.

- Kconfig: select ARCH_SUPPORTS_KEXEC_HANDOVER for CONFIG_64BIT
- kexec.h: add fdt/fdt_mem fields to kimage_arch to hold the KHO FDT kexec segment virtual and physical addresses
- machine_kexec_file.c: add kho_load_fdt() which copies the running kernel's FDT (initial_boot_params), appends linux,kho-fdt and linux,kho-scratch properties to /chosen, and loads the result as a kexec segment; called from load_other_segments(). Returns -EINVAL when initial_boot_params is NULL (ACPI-only boot) since that path requires separate handling.
- machine_kexec.c: before jumping to the new kernel, update the DEVICE_TREE_GUID entry in the EFI config table to point to the KHO FDT segment so the second kernel finds it via efi_fdt_pointer() and early_init_dt_check_kho() calls kho_populate()

---
 arch/loongarch/Kconfig                     |   3 +
 arch/loongarch/include/asm/kexec.h         |   4 +
 arch/loongarch/kernel/machine_kexec.c      |  27 +++++
 arch/loongarch/kernel/machine_kexec_file.c | 118 +++++++++++++++++++++
 4 files changed, 152 insertions(+)
arch/loongarch/Kconfig +3 -0
index 606597da46b8..d494418545f5 100644
@@ -684,6 +684,9 @@ config ARCH_SUPPORTS_KEXEC
 config ARCH_SUPPORTS_KEXEC_FILE
 	def_bool 64BIT
 
+config ARCH_SUPPORTS_KEXEC_HANDOVER
+	def_bool 64BIT
+
 config ARCH_SELECTS_KEXEC_FILE
 	def_bool 64BIT
 	depends on KEXEC_FILE
arch/loongarch/include/asm/kexec.h +4 -0
index 209fa43222e1..adf54bfcdd49 100644
@@ -39,6 +39,10 @@ struct kimage_arch {
 	unsigned long efi_boot;
 	unsigned long cmdline_ptr;
 	unsigned long systable_ptr;
+#ifdef CONFIG_KEXEC_HANDOVER
+	void *fdt;		/* virtual address of KHO FDT segment buffer */
+	unsigned long fdt_mem;	/* physical address of KHO FDT segment */
+#endif
 };
 
 #ifdef CONFIG_KEXEC_FILE
arch/loongarch/kernel/machine_kexec.c +27 -0
index d7fafda1d541..130f1adfa515 100644
@@ -6,6 +6,7 @@
  */
 #include <linux/compiler.h>
 #include <linux/cpu.h>
+#include <linux/efi.h>
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
 #include <linux/delay.h>
@@ -284,6 +285,32 @@ void machine_kexec(struct kimage *image)
 	pr_notice("We will call new kernel at 0x%lx\n", start_addr);
 	pr_notice("Bye ...\n");
 
+#ifdef CONFIG_KEXEC_HANDOVER
+	/*
+	 * Point the EFI FDTPTR config table entry at the modified FDT so the
+	 * second kernel picks up the linux,kho-fdt and linux,kho-scratch
+	 * properties via early_init_dt_check_kho().
+	 */
+	if (internal->fdt_mem) {
+		/*
+		 * FDT-based system: DEVICE_TREE_GUID already exists in the EFI
+		 * config table; just update its pointer to our KHO FDT.
+		 */
+		efi_system_table_t *st =
+			(efi_system_table_t *)TO_CACHE(systable_ptr);
+		efi_config_table_t *ct =
+			(efi_config_table_t *)TO_CACHE((unsigned long)st->tables);
+		unsigned long i;
+
+		for (i = 0; i < st->nr_tables; i++) {
+			if (!efi_guidcmp(ct[i].guid, DEVICE_TREE_GUID)) {
+				ct[i].table = (void *)internal->fdt_mem;
+				break;
+			}
+		}
+	}
+#endif
+
 	/* Make reboot code buffer available to the boot CPU. */
 	flush_cache_all();
 
arch/loongarch/kernel/machine_kexec_file.c +118 -0

143 lines not on this page · raw message

Signature · 1 line
2.25.1
author
#2 lore raw

PATCH v2 2/4 LoongArch: kexec: add KHO support for ACPI-only systems

In reply to George Guo

From: George Guo <[email protected]>

On ACPI-only systems fdt_setup() returns early when it detects ACPI, so initial_boot_params remains NULL and the FDT-based kho_load_fdt() path cannot be used.

machine_kexec_file.c:
- kho_load_fdt(): add an else branch that builds a minimal FDT from scratch (SZ_1K) containing only a /chosen node with linux,kho-fdt and linux,kho-scratch properties, using the libfdt creation API.
- Since DEVICE_TREE_GUID is absent from the EFI config table on ACPI-only systems, build a new config table with DEVICE_TREE_GUID appended and load it as a kexec segment. Store the result in kimage_arch so machine_kexec() can switch st->tables before jumping.
- arch_kimage_file_post_load_cleanup(): free the efi_tables kvmalloc buffer once the kexec image has been loaded.

machine_kexec.c:
- Before jumping, update the EFI system table pointer: for FDT-based systems update the existing DEVICE_TREE_GUID entry; for ACPI-only systems switch st->tables / st->nr_tables to the new extended table.

setup.c:
- fdt_setup(): when ACPI is detected, use efi_fdt_pointer() to detect whether this is a KHO kexec boot. The first kernel switches the EFI config table to a new one that includes a DEVICE_TREE_GUID entry pointing to the minimal KHO FDT. If found, call early_init_dt_scan() so early_init_dt_check_kho() can consume linux,kho-fdt and linux,kho-scratch, then reset initial_boot_params to NULL so the rest of the ACPI boot path is unaffected.

kexec.h:
- Add efi_tables, efi_tables_mem, efi_tables_cnt to kimage_arch.

---
 arch/loongarch/include/asm/kexec.h         |   3 +
 arch/loongarch/kernel/machine_kexec.c      |  11 ++
 arch/loongarch/kernel/machine_kexec_file.c | 162 +++++++++++++++++++--
 arch/loongarch/kernel/setup.c              |  21 ++-
 4 files changed, 184 insertions(+), 13 deletions(-)
arch/loongarch/include/asm/kexec.h +3 -0
index adf54bfcdd49..e1abaf40b06a 100644
@@ -42,6 +42,9 @@ struct kimage_arch {
 #ifdef CONFIG_KEXEC_HANDOVER
 	void *fdt;		/* virtual address of KHO FDT segment buffer */
 	unsigned long fdt_mem;	/* physical address of KHO FDT segment */
+	void *efi_tables;		/* new EFI config table buffer (virtual) */
+	unsigned long efi_tables_mem;	/* physical address of new EFI config table */
+	unsigned long efi_tables_cnt;	/* number of entries in new EFI config table */
 #endif
 };
 
arch/loongarch/kernel/machine_kexec.c +11 -0
index 130f1adfa515..4ee9a433d2de 100644
@@ -308,6 +308,17 @@ void machine_kexec(struct kimage *image)
 				break;
 			}
 		}
+	} else if (internal->efi_tables_mem) {
+		/*
+		 * ACPI-only system: DEVICE_TREE_GUID was not in the original
+		 * EFI config table.  Switch to the new table that was built in
+		 * kho_load_fdt() with DEVICE_TREE_GUID appended.
+		 */
+		efi_system_table_t *st =
+			(efi_system_table_t *)TO_CACHE(systable_ptr);
+
+		st->tables    = internal->efi_tables_mem;
+		st->nr_tables = internal->efi_tables_cnt;
 	}
 #endif
 
arch/loongarch/kernel/machine_kexec_file.c +150 -12

198 lines not on this page · raw message

arch/loongarch/kernel/setup.c +20 -1
index 839b23edee87..c82067d1dc75 100644
@@ -286,8 +286,27 @@ static void __init fdt_setup(void)
 	void *fdt_pointer;
 
 	/* ACPI-based systems do not require parsing fdt */
-	if (acpi_os_get_root_pointer())
+	if (acpi_os_get_root_pointer()) {
+#ifdef CONFIG_KEXEC_HANDOVER
+		/*
+		 * On a KHO kexec boot the first kernel builds a minimal FDT
+		 * containing only /chosen with linux,kho-fdt and
+		 * linux,kho-scratch, and switches the EFI config table to a
+		 * new one that includes a DEVICE_TREE_GUID entry pointing to
+		 * it.  Use efi_fdt_pointer() to detect this case.
+		 *
+		 * Call early_init_dt_scan() to let early_init_dt_check_kho()
+		 * consume the KHO data, then reset initial_boot_params so the
+		 * rest of the ACPI boot path is not confused by this FDT.
+		 */
+		fdt_pointer = efi_fdt_pointer();
+		if (fdt_pointer && !fdt_check_header(fdt_pointer)) {
+			early_init_dt_scan(fdt_pointer, __pa(fdt_pointer));
+			initial_boot_params = NULL;
+		}
+#endif
 		return;
+	}
 
 	/* Prefer to use built-in dtb, checking its legality first. */
 	if (IS_ENABLED(CONFIG_BUILTIN_DTB) && !fdt_check_header(__dtb_start))
Signature · 1 line
2.25.1
author
#3 lore raw

PATCH v2 3/4 selftests/kho: add LoongArch vmtest support

In reply to George Guo

From: George Guo <[email protected]>

Add loongarch.conf to configure QEMU's LoongArch virt machine with a la464 CPU, enable the 8250 serial console, and set the kernel image to vmlinux.efi. Extend vmtest.sh to recognize loongarch64 as a supported target and map it to the 'loongarch' kernel arch name.

QEMU's LoongArch virt machine provides no ACPI tables and relies on FDT to describe hardware. Without 'earlycon' on the kernel command line, the FDT is not scanned for a console UART, no output reaches the console, and vmtest.sh's console log stays empty causing the test to always fail. Add 'earlycon' to KERNEL_CMDLINE in loongarch.conf to fix this.

QEMU's LoongArch virt machine has no i8042 PS/2 controller. When PNP detection finds nothing, i8042_init() falls back to probing the ports directly. On LoongArch the I/O ports are memory-mapped, and the i8042 port addresses are not backed by any device on the virt machine, so i8042_flush() takes a page fault and the kernel panics:

i8042: PNP: No PS/2 controller found.
i8042: Probing ports directly.
CPU 0 Unable to handle kernel paging request at virtual address ffff800000008064
ERA: i8042_flush+0x50/0x198
RA: i8042_init+0x2a8/0x35c

  Kernel panic - not syncing: Attempted to kill init!

Disable SERIO_I8042 and its dependents (KEYBOARD_ATKBD, MOUSE_PS2) in the QEMU_KCONFIG fragment to prevent the driver from being built.

---
 tools/testing/selftests/kho/loongarch.conf | 10 ++++++++++
 tools/testing/selftests/kho/vmtest.sh      |  3 ++-
 2 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/kho/loongarch.conf
tools/testing/selftests/kho/loongarch.conf new file +10 -0
new file mode 100644
index 000000000000..0145cb49e5b2
@@ -0,0 +1,10 @@
+QEMU_CMD="qemu-system-loongarch64 -M virt -cpu la464"
+QEMU_KCONFIG="
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO_I8042 is not set
+"
+KERNEL_IMAGE="vmlinux.efi"
+KERNEL_CMDLINE="console=ttyS0 earlycon"
tools/testing/selftests/kho/vmtest.sh +2 -1
index 49fdac8e8b15..a6ae9ac09595 100755
@@ -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, loongarch64
 	-h)	display this help
 EOF
 }
@@ -123,6 +123,7 @@ function target_to_arch() {
 	case $target in
 	     aarch64) echo "arm64" ;;
 	     x86_64) echo "x86" ;;
+	     loongarch64) echo "loongarch" ;;
 	     *) skip "architecture $target is not supported"
 	esac
 }
Signature · 1 line
2.25.1
author
#4 lore raw

PATCH v2 4/4 selftests/kho: handle QEMU not exiting after kexec on LoongArch

In reply to George Guo

From: George Guo <[email protected]>

On LoongArch, QEMU provides only a minimal EFI stub with no runtime services and no ACPI tables, so machine_restart() falls through to its infinite idle loop and QEMU never exits after kexec. The test result is already printed to the serial console and vmtest.sh reports success, but the user must press Ctrl+C to get the prompt back.

Add QEMU_NEEDS_KILL=1 to loongarch.conf so the test completes unattended.

---
 tools/testing/selftests/kho/loongarch.conf |  3 ++
 tools/testing/selftests/kho/vmtest.sh      | 32 ++++++++++++++++++----
 2 files changed, 29 insertions(+), 6 deletions(-)
tools/testing/selftests/kho/loongarch.conf +3 -0
index 0145cb49e5b2..02a6add633f1 100644
@@ -8,3 +8,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
 "
 KERNEL_IMAGE="vmlinux.efi"
 KERNEL_CMDLINE="console=ttyS0 earlycon"
+# QEMU never exits after kexec on LoongArch (no EFI runtime services),
+# so vmtest.sh must kill it once the test verdict appears.
+QEMU_NEEDS_KILL=1
tools/testing/selftests/kho/vmtest.sh +26 -6
index a6ae9ac09595..821e13fa69a5 100755
@@ -107,12 +107,32 @@ function run_qemu() {
 
 	cmdline="$cmdline kho=on panic=-1"
 
-	$qemu_cmd -m 1G -smp 2 -no-reboot -nographic -nodefaults \
-		  -accel kvm -accel hvf -accel tcg  \
-		  -serial file:"$serial" \
-		  -append "$cmdline" \
-		  -kernel "$kernel" \
-		  -initrd "$initrd"
+	local qemu_args=(
+		-m 1G -smp 2 -no-reboot -nographic -nodefaults
+		-accel kvm -accel hvf -accel tcg
+		-serial file:"$serial"
+		-append "$cmdline"
+		-kernel "$kernel"
+		-initrd "$initrd"
+	)
+
+	# If the target does not exit QEMU after kexec (e.g. no EFI runtime
+	# services), the conf file sets QEMU_NEEDS_KILL=1.  Run QEMU in the
+	# background, poll for the test verdict, then kill it.
+	if [[ "${QEMU_NEEDS_KILL:-0}" == "1" ]]; then
+		$qemu_cmd "${qemu_args[@]}" &
+		local qemu_pid=$!
+		local remaining=100
+		while ((remaining-- > 0)); do
+			grep -q "KHO restore succeeded\|KHO restore failed" \
+				"$serial" 2>/dev/null && break
+			sleep 1
+		done
+		kill "$qemu_pid" 2>/dev/null
+		wait "$qemu_pid" 2>/dev/null || true
+	else
+		$qemu_cmd "${qemu_args[@]}"
+	fi
 
 	grep "KHO restore succeeded" "$serial" &> /dev/null || fail "KHO failed"
 }
Signature · 1 line
2.25.1
maintainer
#5 lore raw
In reply to George Guo

Hi,

Quoted 11 lines · George Guo

From: George Guo <[email protected]>

WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?) #26:
containing only /chosen with the two KHO properties. Since DEVICE_TREE_GUID

ERROR: Invalid commit separator - some tools may have problems applying this #34:
-------------------------------

total: 2 errors, 1 warnings, 0 lines checked

I believe something went wrong with sending the emails :)

Please include changes from revision to revision in the cover letter next time.

You also may want to consider using b4 prep/send for sending the patches.

Quoted 12 lines
Quoted 1 line

Date: Fri, 29 May 2026 21:54:01 +0800
Subject: [PATCH v2 0/4] LoongArch: add KHO support and selftests

This series adds Kexec Handover (KHO) support for LoongArch and extends the KHO selftest infrastructure to run on LoongArch under QEMU.

KHO passes metadata (the KHO state FDT and scratch area addresses) to the second kernel via the FDT /chosen node, using the linux,kho-fdt and linux,kho-scratch properties that drivers/of/kexec.c:kho_add_chosen() writes and drivers/of/fdt.c:early_init_dt_check_kho() reads.

Quoted 8 lines

Selftest support (patches 3-4):

Patch 3 adds loongarch.conf and extends vmtest.sh to recognise loongarch64 as a build target. The LoongArch virt machine is FDT-only (no ACPI), so 'earlycon' must appear on the kernel cmdline or the console UART is never discovered. PS/2 input devices are also disabled since QEMU's LoongArch virt machine has no i8042 controller; the fallback port probe hits a page fault and panics before reaching userspace.

Patch 3 should not introduce regressions

Quoted 5 lines

Patch 4 handles QEMU not exiting after kexec on LoongArch. QEMU provides no EFI runtime services, so machine_restart() falls through to an infinite idle loop. QEMU_NEEDS_KILL=1 in loongarch.conf signals vmtest.sh to run QEMU in the background, poll the serial output for the test verdict, and kill QEMU once it appears, so the test completes unattended.

And patch 4 should be folded into patch 3.
As I said during v1 review, the whole wait and kill loop can be replaced with 'timeout' command which does not need to be specific for LoongArch. The actual timeout value might, though.

Will wait for v3 for more detailed review.

Quoted 20 lines

George Guo (4):
LoongArch: kexec: add KHO support for FDT-based systems
LoongArch: kexec: add KHO support for ACPI-only systems selftests/kho: add LoongArch vmtest support selftests/kho: handle QEMU not exiting after kexec on LoongArch

 arch/loongarch/Kconfig                     |   3 +
 arch/loongarch/include/asm/kexec.h         |   7 +
 arch/loongarch/kernel/machine_kexec.c      |  38 +++
 arch/loongarch/kernel/machine_kexec_file.c | 256 +++++++++++++++++++++
 arch/loongarch/kernel/setup.c              |  21 +-
 tools/testing/selftests/kho/loongarch.conf |  13 ++
 tools/testing/selftests/kho/vmtest.sh      |  35 ++-
 7 files changed, 365 insertions(+), 8 deletions(-)
 create mode 100644 tools/testing/selftests/kho/loongarch.conf
Signature · 1 line
2.25.1
Signature · 2 lines
Sincerely yours,
Mike.