* [PATCH v4 0/4] LoongArch: add KHO support and selftests
@ 2026-08-07 10:37 George Guo
2026-08-07 10:37 ` [PATCH v4 1/4] efi: add a KHO configuration table GUID George Guo
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: George Guo @ 2026-08-07 10:37 UTC (permalink / raw)
To: chenhuacai, rppt, pasha.tatashin, pratyush, shuah, ardb
Cc: guodongtai, kernel, graf, loongarch, linux-kernel, kexec,
linux-mm, linux-kselftest, linux-efi
This series enables Kexec Handover (KHO) on LoongArch, making it the
third architecture (after x86 and arm64) to set
ARCH_SUPPORTS_KEXEC_HANDOVER. That is the only remaining gate for Live
Update (LUO) to run on LoongArch.
The hard part is the transport: how the first kernel hands the KHO state
(the KHO FDT and the scratch region) to the second kernel across kexec.
Why not the command line or an FDT
----------------------------------
LoongArch boots from EFI, but unlike arm64 and riscv its efistub does not
build a boot FDT. It passes the EFI system table and the command line
straight to the core kernel [1]. There is no /chosen node to carry the
blob, so the arm64 path (drivers/of/kexec.c:kho_add_chosen() writes
linux,kho-fdt and linux,kho-scratch; drivers/of/fdt.c:
early_init_dt_check_kho() reads them) does not apply.
Two earlier transports were tried and rejected:
* v1 put the handover addresses on the kernel command line. Pratyush
found that odd and asked for a DT-based alternative.
* v2/v3 synthesized an FDT and rewrote the DEVICE_TREE_GUID entry in the
EFI config table so the generic FDT reader would find it. Pratyush
called that "even more hacky" than the command line [2].
The v4 transport
----------------
v4 follows the x86 setup_data idea, in EFI terms. The first kernel packs
the KHO state into a small struct (linux_efi_kho_data: fdt addr/size and
scratch addr/size), appends a pointer to it under a dedicated
LINUX_EFI_KHO_TABLE_GUID entry in a new EFI config table, loads both as
kexec segments, and switches st->tables before jumping. The second kernel
scans the config table for that GUID in setup_arch() and calls
kho_populate() directly. This is the approach proposed in [3].
It addresses both objections: nothing is exposed on the command line, and
no FDT is synthesized. It also meets Huacai's constraint: it reuses the
EFI system table LoongArch already has, with no dependency on a boot FDT
the efistub never creates.
Patch layout
------------
Patches 1-2 implement the transport. Patch 1 adds the EFI config table
GUID and the handover struct to include/linux/efi.h. It is split out so
the EFI maintainers can review it on its own. Patch 2 wires up the
LoongArch side: ARCH_SUPPORTS_KEXEC_HANDOVER, the write side in
machine_kexec_file.c, the st->tables switch in machine_kexec(), and the
reader in setup_arch().
Patch 3 is a build fix for kernel/liveupdate/luo_session.c that the
series depends on under CONFIG_KFENCE=y on LoongArch. It was sent
standalone as v2 and acked by Mike. It is folded in here at his request
to send it along with this series [4].
Patch 4 adds LoongArch vmtest support to the KHO selftests and folds in
the two points Mike raised on v3 (use "VM" instead of the ad-hoc
"virt machine"; run every architecture under timeout(1), not only
LoongArch).
Patch 1 is aimed at the EFI tree. Patches 2-4 are aimed at the LoongArch
and KHO trees. I expect the whole series to go through the KHO tree with
Ard's and Huacai's acks.
Changes since v3
----------------
* Rework the transport: drop the synthesized FDT and the
DEVICE_TREE_GUID rewrite. Pass the KHO state through a dedicated EFI
configuration table GUID and call kho_populate() directly (patches
1, 2).
* Fold in the luo_session build fix (previously standalone v2, acked by
Mike) as patch 3, at his request.
* selftests: address Mike's v3 review (use "VM"; always run under
timeout(1)).
* Rebase onto v7.2-rc6.
[1] Huacai Chen: https://lore.kernel.org/r/CAAhV-H5B6Mj2-AffkstJ4f8EEmvvPOGXoDy2QNudKD2kSz2XkA@mail.gmail.com/
[2] Pratyush Yadav: https://lore.kernel.org/r/2vxzjyqzj8s2.fsf@kernel.org/
[3] https://lore.kernel.org/r/20260717071551.11904-1-dongtai.guo@linux.dev/
[4] Mike Rapoport: https://lore.kernel.org/r/ai5nYlbERQBXRHSp@kernel.org/
George Guo (4):
efi: add a KHO configuration table GUID
LoongArch: kexec: add KHO support
liveupdate: luo_session: include linux/mm.h for virt/phys translation
selftests/kho: add LoongArch vmtest support
arch/loongarch/Kconfig | 3 +
arch/loongarch/include/asm/kexec.h | 7 ++
arch/loongarch/kernel/machine_kexec.c | 16 +++
arch/loongarch/kernel/machine_kexec_file.c | 131 +++++++++++++++++++++
arch/loongarch/kernel/setup.c | 41 +++++++
include/linux/efi.h | 24 ++++
kernel/liveupdate/luo_session.c | 1 +
tools/testing/selftests/kho/loongarch.conf | 11 ++
tools/testing/selftests/kho/vmtest.sh | 22 ++--
9 files changed, 249 insertions(+), 7 deletions(-)
create mode 100644 tools/testing/selftests/kho/loongarch.conf
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 1/4] efi: add a KHO configuration table GUID
2026-08-07 10:37 [PATCH v4 0/4] LoongArch: add KHO support and selftests George Guo
@ 2026-08-07 10:37 ` George Guo
2026-08-07 10:37 ` [PATCH v4 2/4] LoongArch: kexec: add KHO support George Guo
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: George Guo @ 2026-08-07 10:37 UTC (permalink / raw)
To: chenhuacai, rppt, pasha.tatashin, pratyush, shuah, ardb
Cc: guodongtai, kernel, graf, loongarch, linux-kernel, kexec,
linux-mm, linux-kselftest, linux-efi
From: George Guo <guodongtai@kylinos.cn>
Kexec Handover (KHO) passes the address of its state FDT and of its
scratch area from the current kernel to the next one. On architectures
that boot with a device tree, the current kernel writes the
linux,kho-fdt and linux,kho-scratch properties into /chosen, and the next
kernel reads them back in early_init_dt_check_kho().
Architectures that boot through EFI without a device tree have no such
channel. LoongArch is one of them: its efistub passes the EFI system
table and the command line to the core kernel directly and never creates
an FDT. x86 has the same problem and carries the state out of band
instead, in a struct kho_data in the setup_data chain of its boot
protocol.
Add an out-of-band channel for EFI: a LINUX_EFI_KHO_TABLE_GUID
configuration table entry, under a randomly generated GUID, pointing at a
struct linux_efi_kho_data. The
current kernel loads the structure and an extended configuration table as
kexec segments, then switches the EFI system table to the new table
before jumping. The next kernel finds the entry by GUID and calls
kho_populate().
The structure carries no version field. An incompatible change to the
layout must use a new GUID, which is the usual rule for EFI configuration
tables. The handover payload itself is versioned separately, by the
compatible string of the KHO state FDT that kho_populate() checks.
This patch adds the definitions only. LoongArch is the first user; any
other EFI architecture without a boot FDT can use the same channel.
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
include/linux/efi.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/include/linux/efi.h b/include/linux/efi.h
index ccbc35479684..789ab9e4312a 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -422,6 +422,7 @@ void efi_native_runtime_setup(void);
#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)
#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
#define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31)
+#define LINUX_EFI_KHO_TABLE_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6, 0x9e, 0x50, 0xfc, 0xb3, 0xa8, 0x86, 0x8a, 0x17)
#define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf)
@@ -1271,6 +1272,29 @@ struct linux_efi_memreserve {
void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size);
+/*
+ * The LINUX_EFI_KHO_TABLE_GUID config table points to this structure. It
+ * carries the kexec handover (KHO) state from the current kernel to the next
+ * one: the addresses of the KHO state FDT and of the scratch area.
+ *
+ * This is the handover channel for architectures that boot through EFI without
+ * a device tree, where the /chosen linux,kho-fdt and linux,kho-scratch
+ * properties read by early_init_dt_check_kho() are not available. The current
+ * kernel loads the structure and an extended configuration table as kexec
+ * segments; the next kernel finds it by GUID and calls kho_populate().
+ *
+ * The layout is an ABI between the two kernels and is fixed. It carries no
+ * version field: an incompatible change must use a new GUID, and the handover
+ * payload itself is versioned separately by the compatible string of the KHO
+ * state FDT, which kho_populate() checks.
+ */
+struct linux_efi_kho_data {
+ u64 fdt_addr;
+ u64 fdt_size;
+ u64 scratch_addr;
+ u64 scratch_size;
+} __packed;
+
/*
* The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table can be provided
* to the kernel by an EFI boot loader. The table contains a packed
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 2/4] LoongArch: kexec: add KHO support
2026-08-07 10:37 [PATCH v4 0/4] LoongArch: add KHO support and selftests George Guo
2026-08-07 10:37 ` [PATCH v4 1/4] efi: add a KHO configuration table GUID George Guo
@ 2026-08-07 10:37 ` George Guo
2026-08-07 10:37 ` [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation George Guo
2026-08-07 10:37 ` [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support George Guo
3 siblings, 0 replies; 5+ messages in thread
From: George Guo @ 2026-08-07 10:37 UTC (permalink / raw)
To: chenhuacai, rppt, pasha.tatashin, pratyush, shuah, ardb
Cc: guodongtai, kernel, graf, loongarch, linux-kernel, kexec,
linux-mm, linux-kselftest, linux-efi, Kexin Liu
From: George Guo <guodongtai@kylinos.cn>
Enable Kexec Handover (KHO) on LoongArch64.
LoongArch has no boot FDT: the efistub passes the EFI system table and
the command line to the core kernel directly, so the arm64 /chosen path
(append linux,kho-fdt / linux,kho-scratch and let
early_init_dt_check_kho() read them) does not apply. Follow the x86
model instead, which has no boot FDT either: carry the KHO pointer out of
band and call kho_populate() directly. The channel is the EFI
configuration table entry added by the previous patch.
- Kconfig: ARCH_SUPPORTS_KEXEC_HANDOVER is def_bool 64BIT.
- machine_kexec_file.c: kho_load_data() builds a small handover blob
(struct linux_efi_kho_data) holding the KHO state FDT and scratch
addresses, and a new EFI configuration table with a
LINUX_EFI_KHO_TABLE_GUID entry pointing to it; both are loaded as kexec
segments.
- machine_kexec.c: before jumping to the next kernel, switch the EFI
system table to the extended configuration table.
- setup.c: kho_populate_from_efi() scans the configuration table for
LINUX_EFI_KHO_TABLE_GUID and calls kho_populate() from setup_arch(),
after efi_init() and before memblock_init().
Handover is set up by the kexec_file_load() syscall only. kho_load_data()
runs from load_other_segments(), which the older kexec_load() syscall does
not reach. This matches x86, where KHO lives in the bzImage64 loader.
Tested on a LoongArch machine booting through ACPI/UEFI. After the kexec,
the second kernel reports
KHO: found kexec handover data.
and the two-stage test passes: luo_kexec_simple --stage 1, kexec into the
second kernel, then luo_kexec_simple --stage 2.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
arch/loongarch/Kconfig | 3 +
arch/loongarch/include/asm/kexec.h | 7 ++
arch/loongarch/kernel/machine_kexec.c | 16 +++
arch/loongarch/kernel/machine_kexec_file.c | 131 +++++++++++++++++++++
arch/loongarch/kernel/setup.c | 41 +++++++
5 files changed, 198 insertions(+)
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index d8d252325017..698828ef70f0 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -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
diff --git a/arch/loongarch/include/asm/kexec.h b/arch/loongarch/include/asm/kexec.h
index 6be136e9f0a0..2bcc8bc0d3cc 100644
--- a/arch/loongarch/include/asm/kexec.h
+++ b/arch/loongarch/include/asm/kexec.h
@@ -39,6 +39,13 @@ struct kimage_arch {
unsigned long efi_boot;
unsigned long cmdline_ptr;
unsigned long systable_ptr;
+#ifdef CONFIG_KEXEC_HANDOVER
+ void *kho_data; /* KHO handover blob buffer (virtual) */
+ unsigned long kho_data_mem; /* physical address of the KHO handover blob */
+ 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
};
struct kimage;
diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
index 1883cae93bc3..c98a5607684d 100644
--- a/arch/loongarch/kernel/machine_kexec.c
+++ b/arch/loongarch/kernel/machine_kexec.c
@@ -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>
@@ -287,6 +288,21 @@ 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
+ /*
+ * KHO: switch the EFI system table to the extended configuration table
+ * built in kho_load_data(), which carries the LINUX_EFI_KHO_TABLE_GUID
+ * entry the next kernel reads to find the KHO handover blob.
+ */
+ if (internal->efi_tables_mem) {
+ 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
+
/* Make reboot code buffer available to the boot CPU. */
flush_cache_all();
diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
index 5584b798ba46..d4c2243b6cb0 100644
--- a/arch/loongarch/kernel/machine_kexec_file.c
+++ b/arch/loongarch/kernel/machine_kexec_file.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) "kexec_file: " fmt
+#include <linux/efi.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/kexec.h>
@@ -18,6 +19,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
+#include <asm/addrspace.h>
#include <asm/bootinfo.h>
const struct kexec_file_ops * const kexec_file_loaders[] = {
@@ -32,6 +34,13 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
image->elf_headers = NULL;
image->elf_headers_sz = 0;
+#ifdef CONFIG_KEXEC_HANDOVER
+ kfree(image->arch.kho_data);
+ image->arch.kho_data = NULL;
+ kvfree(image->arch.efi_tables);
+ image->arch.efi_tables = NULL;
+#endif
+
return kexec_image_post_load_cleanup_default(image);
}
@@ -55,6 +64,121 @@ static void cmdline_add_initrd(struct kimage *image, unsigned long *cmdline_tmpl
*cmdline_tmplen += initrd_strlen;
}
+#ifdef CONFIG_KEXEC_HANDOVER
+/*
+ * Hand the KHO state to the next kernel through a dedicated EFI configuration
+ * table entry.
+ *
+ * LoongArch has no boot FDT: the efistub passes the EFI system table and the
+ * command line to the core kernel directly. So instead of the arm64 /chosen
+ * FDT path, build a small handover blob (struct linux_efi_kho_data) holding the
+ * KHO state FDT and scratch addresses, register it in the EFI configuration
+ * table under LINUX_EFI_KHO_TABLE_GUID, and let the next kernel read it and
+ * call kho_populate() directly.
+ *
+ * Both the blob and the extended configuration table are loaded as kexec
+ * segments; machine_kexec() switches st->tables to the new table before jumping.
+ *
+ * image->kho.fdt and image->kho.scratch are filled in by kho_fill_kimage()
+ * before the arch loader runs, so they are valid here.
+ */
+static int kho_load_data(struct kimage *image)
+{
+ struct linux_efi_kho_data *kho;
+ efi_system_table_t *st;
+ efi_config_table_t *ct, *new_ct;
+ size_t old_sz, new_sz;
+ struct kexec_buf kbuf = {
+ .image = image,
+ .buf_min = 0,
+ .buf_max = ULONG_MAX,
+ .top_down = true,
+ };
+ int ret;
+
+ if (!image->kho.fdt || !image->kho.scratch)
+ return 0;
+
+ if (!fw_arg2) {
+ pr_err("KHO requires an EFI boot, no EFI system table found\n");
+ return -EINVAL;
+ }
+
+ /* Build the handover blob and load it as a kexec segment. */
+ kho = kzalloc(sizeof(*kho), GFP_KERNEL);
+ if (!kho)
+ return -ENOMEM;
+
+ kho->fdt_addr = image->kho.fdt;
+ kho->fdt_size = PAGE_SIZE;
+ kho->scratch_addr = image->kho.scratch->mem;
+ kho->scratch_size = image->kho.scratch->memsz;
+
+ kbuf.buffer = kho;
+ kbuf.bufsz = sizeof(*kho);
+ kbuf.memsz = sizeof(*kho);
+ kbuf.buf_align = sizeof(u64);
+ kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+
+ ret = kexec_add_buffer(&kbuf);
+ if (ret) {
+ kfree(kho);
+ return ret;
+ }
+ image->arch.kho_data = kho;
+ image->arch.kho_data_mem = kbuf.mem;
+
+ kexec_dprintk("Loaded KHO handover blob at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ image->arch.kho_data_mem, kbuf.bufsz, kbuf.memsz);
+ kexec_dprintk("KHO fdt at 0x%llx, scratch at 0x%llx size 0x%llx\n",
+ kho->fdt_addr, kho->scratch_addr, kho->scratch_size);
+
+ /*
+ * Build a new EFI configuration table with a LINUX_EFI_KHO_TABLE_GUID
+ * entry appended, pointing at the handover blob, and load it as a kexec
+ * segment. machine_kexec() updates st->tables / st->nr_tables to point
+ * to it before jumping.
+ *
+ * fw_arg2 is the EFI system table physical address passed by the
+ * firmware/bootloader. Use it directly because image->arch.systable_ptr
+ * is set later in machine_kexec_prepare(), which runs after this.
+ */
+ st = (efi_system_table_t *)TO_CACHE(fw_arg2);
+ ct = (efi_config_table_t *)TO_CACHE((unsigned long)st->tables);
+ old_sz = st->nr_tables * sizeof(efi_config_table_t);
+ new_sz = old_sz + sizeof(efi_config_table_t);
+
+ new_ct = kvmalloc(new_sz, GFP_KERNEL);
+ if (!new_ct)
+ return -ENOMEM;
+
+ memcpy(new_ct, ct, old_sz);
+ new_ct[st->nr_tables].guid = LINUX_EFI_KHO_TABLE_GUID;
+ new_ct[st->nr_tables].table = (void *)image->arch.kho_data_mem;
+
+ kbuf.buffer = new_ct;
+ kbuf.bufsz = new_sz;
+ kbuf.memsz = new_sz;
+ kbuf.buf_align = sizeof(void *);
+ kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+
+ ret = kexec_add_buffer(&kbuf);
+ if (ret) {
+ kvfree(new_ct);
+ return ret;
+ }
+ image->arch.efi_tables = new_ct;
+ image->arch.efi_tables_mem = kbuf.mem;
+ image->arch.efi_tables_cnt = st->nr_tables + 1;
+
+ kexec_dprintk("Loaded EFI config table at 0x%lx bufsz=0x%lx memsz=0x%lx nr_tables=%lu\n",
+ image->arch.efi_tables_mem, kbuf.bufsz, kbuf.memsz,
+ image->arch.efi_tables_cnt);
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_CRASH_DUMP
static int prepare_elf_headers(void **addr, unsigned long *sz)
@@ -220,6 +344,13 @@ int load_other_segments(struct kimage *image,
cmdline_add_initrd(image, &cmdline_tmplen, modified_cmdline, initrd_load_addr);
}
+#ifdef CONFIG_KEXEC_HANDOVER
+ /* Load the KHO handover blob and the extended EFI configuration table */
+ ret = kho_load_data(image);
+ if (ret)
+ goto out_err;
+#endif
+
if (cmdline_len + cmdline_tmplen > COMMAND_LINE_SIZE) {
pr_err("Appending command line exceeds COMMAND_LINE_SIZE\n");
ret = -EINVAL;
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index 6fa4a22a58fd..1e2fbf37aecf 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -20,6 +20,7 @@
#include <linux/initrd.h>
#include <linux/ioport.h>
#include <linux/kexec.h>
+#include <linux/kexec_handover.h>
#include <linux/crash_dump.h>
#include <linux/root_dev.h>
#include <linux/console.h>
@@ -280,6 +281,45 @@ static void __init arch_reserve_crashkernel(void)
reserve_crashkernel_generic(crash_size, crash_base, low_size, high);
}
+#ifdef CONFIG_KEXEC_HANDOVER
+/*
+ * On a KHO kexec boot the previous kernel registered a handover blob in the EFI
+ * configuration table under LINUX_EFI_KHO_TABLE_GUID (see
+ * arch/loongarch/kernel/machine_kexec_file.c). Scan the configuration table
+ * for it, read the KHO state FDT and scratch addresses, and hand them to the
+ * KHO core. fw_arg2 is the EFI system table physical address.
+ *
+ * This runs from setup_arch(), after efi_init() and before memblock_init(),
+ * which is where the generic reader early_init_dt_check_kho() would call
+ * kho_populate().
+ */
+static void __init kho_populate_from_efi(void)
+{
+ efi_system_table_t *st;
+ efi_config_table_t *ct;
+ struct linux_efi_kho_data *kho;
+ unsigned long i;
+
+ if (!fw_arg2)
+ return;
+
+ st = (efi_system_table_t *)TO_CACHE(fw_arg2);
+ ct = (efi_config_table_t *)TO_CACHE((unsigned long)st->tables);
+
+ for (i = 0; i < st->nr_tables; i++) {
+ if (efi_guidcmp(ct[i].guid, LINUX_EFI_KHO_TABLE_GUID))
+ continue;
+
+ kho = (struct linux_efi_kho_data *)TO_CACHE((unsigned long)ct[i].table);
+ kho_populate(kho->fdt_addr, kho->fdt_size,
+ kho->scratch_addr, kho->scratch_size);
+ break;
+ }
+}
+#else
+static void __init kho_populate_from_efi(void) { }
+#endif
+
static void __init fdt_setup(void)
{
#ifdef CONFIG_OF_EARLY_FLATTREE
@@ -599,6 +639,7 @@ void __init setup_arch(char **cmdline_p)
init_environ();
efi_init();
+ kho_populate_from_efi();
fdt_setup();
memblock_init();
pagetable_init();
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation
2026-08-07 10:37 [PATCH v4 0/4] LoongArch: add KHO support and selftests George Guo
2026-08-07 10:37 ` [PATCH v4 1/4] efi: add a KHO configuration table GUID George Guo
2026-08-07 10:37 ` [PATCH v4 2/4] LoongArch: kexec: add KHO support George Guo
@ 2026-08-07 10:37 ` George Guo
2026-08-07 10:37 ` [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support George Guo
3 siblings, 0 replies; 5+ messages in thread
From: George Guo @ 2026-08-07 10:37 UTC (permalink / raw)
To: chenhuacai, rppt, pasha.tatashin, pratyush, shuah, ardb
Cc: guodongtai, kernel, graf, loongarch, linux-kernel, kexec,
linux-mm, linux-kselftest, linux-efi, Kexin Liu
From: George Guo <guodongtai@kylinos.cn>
luo_session.c calls virt_to_phys() and phys_to_virt(). On LoongArch with
CONFIG_KFENCE=y, these macros (in arch/loongarch/include/asm/io.h) expand
to offset_in_page() and page_address(), both declared in <linux/mm.h>.
Since luo_session.c only includes <linux/io.h>, the translation unit fails
to build with CONFIG_KFENCE=y:
asm/io.h: error: implicit declaration of function 'offset_in_page'
asm/io.h: error: implicit declaration of function 'page_address'
Add the missing include to fix these build errors.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
kernel/liveupdate/luo_session.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
index f38b5b18f3f8..31490ac7b63d 100644
--- a/kernel/liveupdate/luo_session.c
+++ b/kernel/liveupdate/luo_session.c
@@ -94,6 +94,7 @@
#include <linux/kho/abi/luo.h>
#include <linux/list.h>
#include <linux/liveupdate.h>
+#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support
2026-08-07 10:37 [PATCH v4 0/4] LoongArch: add KHO support and selftests George Guo
` (2 preceding siblings ...)
2026-08-07 10:37 ` [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation George Guo
@ 2026-08-07 10:37 ` George Guo
3 siblings, 0 replies; 5+ messages in thread
From: George Guo @ 2026-08-07 10:37 UTC (permalink / raw)
To: chenhuacai, rppt, pasha.tatashin, pratyush, shuah, ardb
Cc: guodongtai, kernel, graf, loongarch, linux-kernel, kexec,
linux-mm, linux-kselftest, linux-efi, Kexin Liu
From: George Guo <guodongtai@kylinos.cn>
Add loongarch.conf to configure QEMU's LoongArch virtual machine (VM)
with a la464 CPU, enable the 8250 serial console, and set the kernel
image to vmlinux.efi. Extend vmtest.sh to recognise loongarch64 as a
supported target and map it to the 'loongarch' kernel arch name.
QEMU's LoongArch VM 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.
QEMU's LoongArch VM 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 VM, 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.
All three options are scoped to loongarch.conf; no other architecture
is affected.
Wrap the QEMU invocation in run_qemu() with timeout(1) using a local
time limit so the test always terminates, even when QEMU does not exit
on its own. This is useful for every architecture; on LoongArch, for
example, QEMU provides no EFI runtime services and machine_restart()
falls through to an idle loop after kexec, so QEMU would never exit
otherwise.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
tools/testing/selftests/kho/loongarch.conf | 11 +++++++++++
tools/testing/selftests/kho/vmtest.sh | 22 +++++++++++++++-------
2 files changed, 26 insertions(+), 7 deletions(-)
create mode 100644 tools/testing/selftests/kho/loongarch.conf
diff --git a/tools/testing/selftests/kho/loongarch.conf b/tools/testing/selftests/kho/loongarch.conf
new file mode 100644
index 000000000000..e45fe1014cf3
--- /dev/null
+++ b/tools/testing/selftests/kho/loongarch.conf
@@ -0,0 +1,11 @@
+QEMU_CMD="qemu-system-loongarch64 -M virt -cpu la464"
+QEMU_KCONFIG="
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SPARSEMEM_MANUAL=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 kho_scratch=16M,16M,16M"
diff --git a/tools/testing/selftests/kho/vmtest.sh b/tools/testing/selftests/kho/vmtest.sh
index 0014bd76e88d..de6aa59cf5a0 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, loongarch64
-h) display this help
EOF
}
@@ -111,12 +111,19 @@ 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"
+ )
+
+ # Bound the QEMU run so the test always terminates, even when QEMU
+ # does not exit on its own (e.g. no EFI runtime services after kexec).
+ local qemu_timeout=60
+ timeout "$qemu_timeout" $qemu_cmd "${qemu_args[@]}" || true
grep "KHO restore succeeded" "$serial" &> /dev/null || fail "KHO failed"
}
@@ -127,6 +134,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
}
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-07 10:39 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-07 10:37 [PATCH v4 0/4] LoongArch: add KHO support and selftests George Guo
2026-08-07 10:37 ` [PATCH v4 1/4] efi: add a KHO configuration table GUID George Guo
2026-08-07 10:37 ` [PATCH v4 2/4] LoongArch: kexec: add KHO support George Guo
2026-08-07 10:37 ` [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation George Guo
2026-08-07 10:37 ` [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support George Guo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox