From nobody Tue Sep 29 13:19:12 2026 Received: from out-171.mta1.migadu.com (mta1.migadu.com [37.59.57.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA6AB42049B for ; Fri, 7 Aug 2026 10:38:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.59.57.117 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099094; cv=none; b=fPLXM2Hpdt1VOqM5v57GcyIEgHdRxnvJIN1hXtm/5MQTvkIPJ3y6CECuskmU6yZgkYbkfzlyDXdhDz23BGUv6Ir2D6yoNGiHXliqokwUcKhf0QFTKbdWB74jKFMbFNrgh1jQmJIirzxkizdjg9yxRzY7OrC1a30zXQm9y4VFlzw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099094; c=relaxed/simple; bh=M0AMxb+cVwP+atxrSkKPR5Z4+wp0xXh/yRjnQIRVMmw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qTb4iC93eKQvKJkDuFuE80/8qJiTLZO8JysMfEdsVGZnML16QaVbKuNNXnvUBxxS4hWKnvg91nXE2FE5yuTp3ztljpQM/4zdRYNAjaXM0LyHkNSK0jweRFvQm32ds/OEjq8QsT4d7+oGPyf8Fnlw0xlXthGoBnCh3EzISuHaaHs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=nUqGglQE; arc=none smtp.client-ip=37.59.57.117 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="nUqGglQE" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1786099088; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8MnGA2XpLaKtX7cmmtolKrMtU3s+BumW1DYNOt54uYU=; b=nUqGglQEFSiDP4w9XvLdasgzgUzCQg3EnaBt8s3qJmMZ9muZcSGKjRgCCxC6fluOTVKSvm ouR+zIBF+Rfk3GovmnF0OOku9DgEgMRJniWkjd5Hmv1wpvfO38bX97LZBO5HGVKAJB1uoZ i51ax670tcY7f0PpRSNY+JBndvEY7kY= From: George Guo To: chenhuacai@kernel.org, rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, shuah@kernel.org, ardb@kernel.org Cc: guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-efi@vger.kernel.org Subject: [PATCH v4 1/4] efi: add a KHO configuration table GUID Date: Fri, 7 Aug 2026 18:37:11 +0800 Message-ID: <20260807103714.33074-2-dongtai.guo@linux.dev> In-Reply-To: <20260807103714.33074-1-dongtai.guo@linux.dev> References: <20260807103714.33074-1-dongtai.guo@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: George Guo 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 --- 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, 0x48= 4c, 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, 0= x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) +#define LINUX_EFI_KHO_TABLE_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6, 0x= 9e, 0x50, 0xfc, 0xb3, 0xa8, 0x86, 0x8a, 0x17) =20 #define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec,= 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf) =20 @@ -1271,6 +1272,29 @@ struct linux_efi_memreserve { =20 void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size); =20 +/* + * 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 n= ext + * one: the addresses of the KHO state FDT and of the scratch area. + * + * This is the handover channel for architectures that boot through EFI wi= thout + * 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 cu= rrent + * 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 hand= over + * 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 --=20 2.53.0 From nobody Tue Sep 29 13:19:12 2026 Received: from out-185.mta1.migadu.com (out-185.mta1.migadu.com [95.215.58.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8F22377EC3 for ; Fri, 7 Aug 2026 10:38:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099133; cv=none; b=sdM7W+MghpAtoG2HrzRFF0IjNQWdxOylHxDUGOfZAHNnbJuF7Z5E4xXM0/yxAqT4bYiC3bTIZn5XMpRl/CLMtigdw+vvjLspBrftlIMQ4AFDBVUYbK8boK2n3dhNq2g6vD6aY0vUGF+dZziYOMz/Op6sNOtiTVobuvHe8W2bPNQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099133; c=relaxed/simple; bh=k+Fcen4MYcZyNNi1i9NYfUKJmyV3iEObVy5P5Juo1cQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OwMRa63rauQYClBuruPh9UYy/4j4VHA6bf6bRDYMOwoR0MSDd4kdFLuVi5DVbc1X5mljyJS/0PlsYSgMc2xWGF6hPrmV+2BeKZSQqcpFF7NYoYFdFqTslcBHSpxoVXwBHJbGt7s52nP/3pqGt8DJt6NzcaqJ12XqVOxpP2Njbdo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=XELU+/Ps; arc=none smtp.client-ip=95.215.58.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="XELU+/Ps" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1786099127; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2//MdYBzQ2M55gfAcjDDNKMmJ4XWZ+o7gw3/S2yli2o=; b=XELU+/Ps0KysLZGkSe2/XepKTlyG2/Iw6LTmp9rcJetE5z4NuL6subolc2tDA9kFIpeT7F vL6zJzuLfQPDvYJCb2VFS5QzbR//eU8xCa7E3itPrKDMJHv1TB6fwxQ9aJWT5VBF4L5YHu UmXCnkNRVzonuzpaD0bwJ+z0PwN+GgY= From: George Guo To: chenhuacai@kernel.org, rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, shuah@kernel.org, ardb@kernel.org Cc: guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-efi@vger.kernel.org, Kexin Liu Subject: [PATCH v4 2/4] LoongArch: kexec: add KHO support Date: Fri, 7 Aug 2026 18:37:12 +0800 Message-ID: <20260807103714.33074-3-dongtai.guo@linux.dev> In-Reply-To: <20260807103714.33074-1-dongtai.guo@linux.dev> References: <20260807103714.33074-1-dongtai.guo@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: George Guo 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 Signed-off-by: Kexin Liu Signed-off-by: George Guo --- 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 =20 +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/as= m/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 tabl= e */ +#endif }; =20 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 #include +#include #include #include #include @@ -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"); =20 +#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 =3D + (efi_system_table_t *)TO_CACHE(systable_ptr); + + st->tables =3D internal->efi_tables_mem; + st->nr_tables =3D internal->efi_tables_cnt; + } +#endif + /* Make reboot code buffer available to the boot CPU. */ flush_cache_all(); =20 diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/ke= rnel/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 @@ =20 #define pr_fmt(fmt) "kexec_file: " fmt =20 +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include =20 const struct kexec_file_ops * const kexec_file_loaders[] =3D { @@ -32,6 +34,13 @@ int arch_kimage_file_post_load_cleanup(struct kimage *im= age) image->elf_headers =3D NULL; image->elf_headers_sz =3D 0; =20 +#ifdef CONFIG_KEXEC_HANDOVER + kfree(image->arch.kho_data); + image->arch.kho_data =3D NULL; + kvfree(image->arch.efi_tables); + image->arch.efi_tables =3D NULL; +#endif + return kexec_image_post_load_cleanup_default(image); } =20 @@ -55,6 +64,121 @@ static void cmdline_add_initrd(struct kimage *image, un= signed long *cmdline_tmpl *cmdline_tmplen +=3D initrd_strlen; } =20 +#ifdef CONFIG_KEXEC_HANDOVER +/* + * Hand the KHO state to the next kernel through a dedicated EFI configura= tion + * 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 /cho= sen + * FDT path, build a small handover blob (struct linux_efi_kho_data) holdi= ng the + * KHO state FDT and scratch addresses, register it in the EFI configurati= on + * table under LINUX_EFI_KHO_TABLE_GUID, and let the next kernel read it a= nd + * 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 j= umping. + * + * 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 =3D { + .image =3D image, + .buf_min =3D 0, + .buf_max =3D ULONG_MAX, + .top_down =3D 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 =3D kzalloc(sizeof(*kho), GFP_KERNEL); + if (!kho) + return -ENOMEM; + + kho->fdt_addr =3D image->kho.fdt; + kho->fdt_size =3D PAGE_SIZE; + kho->scratch_addr =3D image->kho.scratch->mem; + kho->scratch_size =3D image->kho.scratch->memsz; + + kbuf.buffer =3D kho; + kbuf.bufsz =3D sizeof(*kho); + kbuf.memsz =3D sizeof(*kho); + kbuf.buf_align =3D sizeof(u64); + kbuf.mem =3D KEXEC_BUF_MEM_UNKNOWN; + + ret =3D kexec_add_buffer(&kbuf); + if (ret) { + kfree(kho); + return ret; + } + image->arch.kho_data =3D kho; + image->arch.kho_data_mem =3D kbuf.mem; + + kexec_dprintk("Loaded KHO handover blob at 0x%lx bufsz=3D0x%lx memsz=3D0x= %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 =3D (efi_system_table_t *)TO_CACHE(fw_arg2); + ct =3D (efi_config_table_t *)TO_CACHE((unsigned long)st->tables); + old_sz =3D st->nr_tables * sizeof(efi_config_table_t); + new_sz =3D old_sz + sizeof(efi_config_table_t); + + new_ct =3D kvmalloc(new_sz, GFP_KERNEL); + if (!new_ct) + return -ENOMEM; + + memcpy(new_ct, ct, old_sz); + new_ct[st->nr_tables].guid =3D LINUX_EFI_KHO_TABLE_GUID; + new_ct[st->nr_tables].table =3D (void *)image->arch.kho_data_mem; + + kbuf.buffer =3D new_ct; + kbuf.bufsz =3D new_sz; + kbuf.memsz =3D new_sz; + kbuf.buf_align =3D sizeof(void *); + kbuf.mem =3D KEXEC_BUF_MEM_UNKNOWN; + + ret =3D kexec_add_buffer(&kbuf); + if (ret) { + kvfree(new_ct); + return ret; + } + image->arch.efi_tables =3D new_ct; + image->arch.efi_tables_mem =3D kbuf.mem; + image->arch.efi_tables_cnt =3D st->nr_tables + 1; + + kexec_dprintk("Loaded EFI config table at 0x%lx bufsz=3D0x%lx memsz=3D0x%= lx nr_tables=3D%lu\n", + image->arch.efi_tables_mem, kbuf.bufsz, kbuf.memsz, + image->arch.efi_tables_cnt); + + return 0; +} +#endif + #ifdef CONFIG_CRASH_DUMP =20 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); } =20 +#ifdef CONFIG_KEXEC_HANDOVER + /* Load the KHO handover blob and the extended EFI configuration table */ + ret =3D 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 =3D -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 #include #include +#include #include #include #include @@ -280,6 +281,45 @@ static void __init arch_reserve_crashkernel(void) reserve_crashkernel_generic(crash_size, crash_base, low_size, high); } =20 +#ifdef CONFIG_KEXEC_HANDOVER +/* + * On a KHO kexec boot the previous kernel registered a handover blob in t= he EFI + * configuration table under LINUX_EFI_KHO_TABLE_GUID (see + * arch/loongarch/kernel/machine_kexec_file.c). Scan the configuration ta= ble + * 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 =3D (efi_system_table_t *)TO_CACHE(fw_arg2); + ct =3D (efi_config_table_t *)TO_CACHE((unsigned long)st->tables); + + for (i =3D 0; i < st->nr_tables; i++) { + if (efi_guidcmp(ct[i].guid, LINUX_EFI_KHO_TABLE_GUID)) + continue; + + kho =3D (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) =20 init_environ(); efi_init(); + kho_populate_from_efi(); fdt_setup(); memblock_init(); pagetable_init(); --=20 2.53.0 From nobody Tue Sep 29 13:19:12 2026 Received: from out-170.mta0.migadu.com (out-170.mta0.migadu.com [91.218.175.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3365C3F9F4C; Fri, 7 Aug 2026 10:39:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099152; cv=none; b=LmaSpw7YrFF4DU+x+NPGidIuzSDN2CLJvzoFUKGBZPgyVQCZiwxzFAJNLJ+Y69aw3IgeQEwme9WNAph419lUPSKMywwlCvBA0aA1zRUugwNvVDkKRIIeWRHqKBFaS+qKLTVAjPUkmqXVtCJd+q9qdMBbsBoxQLHDGqI3fhwLdgs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099152; c=relaxed/simple; bh=fqqsQaloq3X7EORELDdRzN6fv5y1opQI77hHeUsPE5o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hau3Lgzas/xhND6AmFsIQancWaUKK+nk5v82nXzv1r7dfgtObqEGpLtql727TaWoRK95gLYeHcMfFwSgr9FrRn7DC81qPKWuMM8MffnM48rqrqsUic1/7vCA0Ud6GB/J0W4/rSlfeN/J2FQ/Z0MtJKBst8XrateTFTJqT9x1aDw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=K/B1TZEE; arc=none smtp.client-ip=91.218.175.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="K/B1TZEE" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1786099136; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IhT9Nbnrmy1FCrntkD6IOlFelDNdobApjep1pMDJx7k=; b=K/B1TZEEloG3kmATLa01mpjHRXTcYT8OdEuMPA08x4VuWBrroYrXT6NA0bUekvtBpiPO5j d3a39YO2i1b2WEXhstvivoHKfRapFZFDDTQ68bYv28/okWZKG0ykMrfKDqI3vj1LeU5hwp VCQRU7Y6V/hVnlzk62RoS48vudn7TtY= From: George Guo To: chenhuacai@kernel.org, rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, shuah@kernel.org, ardb@kernel.org Cc: guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-efi@vger.kernel.org, Kexin Liu Subject: [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation Date: Fri, 7 Aug 2026 18:37:13 +0800 Message-ID: <20260807103714.33074-4-dongtai.guo@linux.dev> In-Reply-To: <20260807103714.33074-1-dongtai.guo@linux.dev> References: <20260807103714.33074-1-dongtai.guo@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: George Guo luo_session.c calls virt_to_phys() and phys_to_virt(). On LoongArch with CONFIG_KFENCE=3Dy, these macros (in arch/loongarch/include/asm/io.h) expand to offset_in_page() and page_address(), both declared in . Since luo_session.c only includes , the translation unit fails to build with CONFIG_KFENCE=3Dy: 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 Signed-off-by: Kexin Liu Signed-off-by: George Guo Acked-by: Mike Rapoport (Microsoft) Reviewed-by: Pratyush Yadav --- kernel/liveupdate/luo_session.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_sessio= n.c index f38b5b18f3f8..31490ac7b63d 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -94,6 +94,7 @@ #include #include #include +#include #include #include #include --=20 2.53.0 From nobody Tue Sep 29 13:19:12 2026 Received: from out-173.mta0.migadu.com (out-173.mta0.migadu.com [91.218.175.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D058042D75C for ; Fri, 7 Aug 2026 10:39:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099156; cv=none; b=FV5nvYgijnmEvGMb1v5rOBOb5v9BFKoxzGqGvYm0C33xrRqV4Xgt22AX0sl4XBb4zxrSQXnCjFkYAMydLl6GKlK57RTcOxc7SBQ6henrbOwXvNpG5cCm58UkbkJ1xYTvY94EGrI0SRaszGesZJG+++r7TCUEr5I8eup8I+BCK0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786099156; c=relaxed/simple; bh=AthgqfGh33oNASpFzQIJ8i2cw1Ud1tKoUiRNJueEqJQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bm+eU6pmPI0oWhKuB1PwAZkrnPhmRSW7heje4PQ3lynnydYLoJTHDvYwucF+n6rpnDijtzYrpSpVYjjmy5oRmH5Z5O2RqDFc1Cetmj1vj4RCQDTuJaOcHVKY8HqRR3aWBSIYaGC8bwVEiNv3Z2oRHj7xktDl905+yXMmO4O0oAs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=leFCf1q7; arc=none smtp.client-ip=91.218.175.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="leFCf1q7" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1786099147; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+cRL3uotexgsAYtLUosWyuQdevxVlf8Hhe38VeOp48k=; b=leFCf1q7bWexhIlRym5mgLf1EOisTxXGgyEu7WyO9nLs6AFFzBa5eAN4zwjxXwdcx9Zca0 omPlm5ULbkJc4DAoXhz5sJcehdTr4IdR3WIHmsRnRF4G7Y5VNtpBLF9EzxE+TcLqPLTWwa oHj3Bgs1ou/YKoTNmTnBdncag6GUT54= From: George Guo To: chenhuacai@kernel.org, rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, shuah@kernel.org, ardb@kernel.org Cc: guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-efi@vger.kernel.org, Kexin Liu Subject: [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support Date: Fri, 7 Aug 2026 18:37:14 +0800 Message-ID: <20260807103714.33074-5-dongtai.guo@linux.dev> In-Reply-To: <20260807103714.33074-1-dongtai.guo@linux.dev> References: <20260807103714.33074-1-dongtai.guo@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: George Guo 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 ffff80000= 0008064 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 Signed-off-by: Kexin Liu Signed-off-by: George Guo --- 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/sel= ftests/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=3D"qemu-system-loongarch64 -M virt -cpu la464" +QEMU_KCONFIG=3D" +CONFIG_SERIAL_8250=3Dy +CONFIG_SERIAL_8250_CONSOLE=3Dy +CONFIG_SPARSEMEM_MANUAL=3Dy +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO_I8042 is not set +" +KERNEL_IMAGE=3D"vmlinux.efi" +KERNEL_CMDLINE=3D"console=3DttyS0 earlycon kho_scratch=3D16M,16M,16M" diff --git a/tools/testing/selftests/kho/vmtest.sh b/tools/testing/selftest= s/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() { =20 cmdline=3D"$cmdline kho=3Don panic=3D-1" =20 - $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=3D( + -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=3D60 + timeout "$qemu_timeout" $qemu_cmd "${qemu_args[@]}" || true =20 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 } --=20 2.53.0