From nobody Sat Sep 26 05:27:45 2026 Received: from mta0.migadu.com (out-102.mta0.migadu.com [91.218.175.102]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BAB945560D for ; Fri, 4 Sep 2026 10:10:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.102 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516635; cv=none; b=jFuT0zpvFAFzaoEWPTm7++uf6mi8cXq6DEPGmn6u+qKKVwvE/qkn48RWV2+8piOAR7jW/tZHybPoCiJ+f9H+pyS4hY0wn39dMXYB0yfU4RUDqCpPY4zyAS+Tdwhsk6rDB60jGWZGauBA9TROW6MVbjWtiXWRIYyOD8qUAXPH5nM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516635; c=relaxed/simple; bh=HvzAFA3PwYD95faWowDYT060CwppIvNZX691N3gouBk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eBb0T3xVYDP3Ty3HZGj81abK7Rcqp+xAP6CpAQvJG8ch0i56Fw3PHanVKfKbBk4CDuOscrn8Dm/ry3bxsazyDMb4IJLZmGrOuJkbDuisC9o5k1FwMynEoGTn+PK9qeyYVOWU7GgooMV5WxK5zrYm8RnjuSmTe77OT1Koj2/pJKk= 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=tTP7V36q; arc=none smtp.client-ip=91.218.175.102 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="tTP7V36q" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=HvzAFA3PwYD95faWowDYT060CwppIvNZX691N3gouBk=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788516625; v=1; x=1789121425; b=tTP7V36qCtvcLHfmzhjNqHtSqxqOmJqcixopkpczVmPo8uTKgEslGAb8UiRAXkGaCqPAAQ5G 7Ydd+0l3x3tLFy0X9Atn6vzhvDObPOHwvJpcpSOxjfKpSw2EEFxr4EgThwoaJ/GJVfvFpncDKQO 0oF2DCKx7QDnLSwXjeh7r1kk= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 9df508514e3edb12; Fri, 04 Sep 2026 10:10:24 +0000 X-Mizu-Trace-ID: 9df508514e3edb12 X-Migadu-Flow: FLOW_OUT From: George Guo To: rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, chenhuacai@kernel.org, ardb@kernel.org, shuah@kernel.org Cc: ilias.apalodimas@linaro.org, akpm@linux-foundation.org, baoquan.he@linux.dev, ruirui.yang@linux.dev, guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, liukexin@kylinos.cn, 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 v5 1/5] efi: add a KHO configuration table channel Date: Fri, 4 Sep 2026 18:08:48 +0800 Message-ID: <20260904100852.26006-2-dongtai.guo@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260904100852.26006-1-dongtai.guo@linux.dev> References: <20260904100852.26006-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 Content-Type: text/plain; charset="utf-8" From: George Guo Add an architecture-agnostic EFI configuration table channel for kexec handover (KHO): a LINUX_EFI_KEXEC_HANDOVER_GUID table entry pointing at a struct linux_efi_kho_data that carries the KHO state FDT and scratch area addresses from one kernel to the next. This is the channel for architectures that boot through EFI without a device tree (e.g. LoongArch), where the /chosen linux,kho-fdt and linux,kho-scratch properties read by early_init_dt_check_kho() are not available. Architectures with a boot FDT (arm64, riscv) keep using the FDT path and do not select this. The design mirrors the LINUX_EFI_MEMRESERVE_TABLE_GUID channel: - The EFI stub allocates and installs the table once at boot (install_kho_table(), next to install_memreserve_table()), so the config table entry is inherited across kexec for free. - The reader is a common_tables[] entry in efi_config_parse_tables(). It reserves the stub-allocated table with memblock_reserve(), the same way the memreserve entries are reserved there, so the table is neither handed out by the buddy allocator nor placed on by kexec segments. It then maps the table and calls kho_populate(). No arch-specific setup.c hook is needed. - efi_kho_update() rewrites the table contents in place before a kexec; the config table array is never rebuilt and st->tables is never switched, unlike the per-arch approach it replaces. The table stays persistently mapped from an early_initcall, the same way the memreserve root is, so the update also works on the crash kexec path. Gated behind CONFIG_EFI_KHO, selected by architectures that use this channel. Signed-off-by: George Guo --- drivers/firmware/efi/Kconfig | 12 ++++ drivers/firmware/efi/efi.c | 78 +++++++++++++++++++++++++ drivers/firmware/efi/libstub/efi-stub.c | 25 ++++++++ include/linux/efi.h | 36 ++++++++++++ 4 files changed, 151 insertions(+) diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 29e0729299f5..d6c1372484b4 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -314,6 +314,18 @@ config EFI_SBAT_FILE =20 If unsure, leave blank. =20 +config EFI_KHO + bool + depends on EFI_STUB && EFI_GENERIC_STUB && KEXEC_HANDOVER + help + Carry the KHO state (the KHO state FDT and the scratch area) from + one kernel to the next across kexec via an EFI configuration table + entry under LINUX_EFI_KEXEC_HANDOVER_GUID, for architectures that + boot through EFI without a device tree (e.g. LoongArch). + + Architectures with a boot FDT (arm64, riscv) use the /chosen FDT + path instead and do not select this. + endmenu =20 config UEFI_CPER diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 0327a39d31fa..6380cfab1493 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,9 @@ unsigned long __ro_after_init efi_rng_seed =3D EFI_INVALI= D_TABLE_ADDR; static unsigned long __initdata mem_reserve =3D EFI_INVALID_TABLE_ADDR; static unsigned long __initdata rt_prop =3D EFI_INVALID_TABLE_ADDR; static unsigned long __initdata initrd =3D EFI_INVALID_TABLE_ADDR; +#ifdef CONFIG_EFI_KHO +static unsigned long __ro_after_init efi_kho_table_phys =3D EFI_INVALID_TA= BLE_ADDR; +#endif =20 extern unsigned long primary_display_table; =20 @@ -629,6 +633,9 @@ static const efi_config_table_type_t common_tables[] __= initconst =3D { {EFI_TCG2_FINAL_EVENTS_TABLE_GUID, &efi.tpm_final_log, "TPMFinalLog" }, {EFI_CC_FINAL_EVENTS_TABLE_GUID, &efi.tpm_final_log, "CCFinalLog" }, {LINUX_EFI_MEMRESERVE_TABLE_GUID, &mem_reserve, "MEMRESERVE" }, +#ifdef CONFIG_EFI_KHO + {LINUX_EFI_KEXEC_HANDOVER_GUID, &efi_kho_table_phys, "KHO" }, +#endif {LINUX_EFI_INITRD_MEDIA_GUID, &initrd, "INITRD" }, {EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" }, #ifdef CONFIG_OVMF_DEBUG_LOG @@ -806,6 +813,31 @@ int __init efi_config_parse_tables(const efi_config_ta= ble_t *config_tables, } } =20 +#ifdef CONFIG_EFI_KHO + if (efi_kho_table_phys !=3D EFI_INVALID_TABLE_ADDR) { + struct linux_efi_kho_data *kho; + + /* + * Reserve the stub-allocated table so it is neither handed + * out by the buddy allocator nor placed on by kexec + * segments, mirroring the memreserve handling above. This + * runs on every boot, so it also protects the table in the + * next kernel until it reads it. + */ + memblock_reserve(efi_kho_table_phys, sizeof(*kho)); + + kho =3D early_memremap(efi_kho_table_phys, sizeof(*kho)); + if (kho) { + if (kho->fdt_addr) + kho_populate((phys_addr_t)kho->fdt_addr, + kho->fdt_size, + (phys_addr_t)kho->scratch_addr, + kho->scratch_size); + early_memunmap(kho, sizeof(*kho)); + } + } +#endif + if (rt_prop !=3D EFI_INVALID_TABLE_ADDR) { efi_rt_properties_table_t *tbl; =20 @@ -1171,6 +1203,52 @@ static int __init efi_memreserve_root_init(void) } early_initcall(efi_memreserve_root_init); =20 +#ifdef CONFIG_EFI_KHO +static struct linux_efi_kho_data *efi_kho_table __ro_after_init; + +static int __init efi_kho_table_init(void) +{ + if (efi_kho_table_phys =3D=3D EFI_INVALID_TABLE_ADDR) + return 0; + + /* + * Keep a persistent mapping of the table, the same way + * efi_memreserve_root_init() keeps the memreserve root mapped: + * efi_kho_update() is also called on the crash kexec path, where + * memremap() is no longer an option. + */ + efi_kho_table =3D memremap(efi_kho_table_phys, sizeof(*efi_kho_table), + MEMREMAP_WB); + WARN_ON_ONCE(!efi_kho_table); + + return 0; +} +early_initcall(efi_kho_table_init); + +/* + * Update the KHO config table in place before a kexec, so the next kernel + * finds the current handover state. Mirrors efi_mem_reserve_persistent(): + * the config table entry was installed once by the EFI stub and is inheri= ted + * across kexec, so only the table contents are rewritten here -- the conf= ig + * table array is never rebuilt and st->tables is never switched. + */ +int efi_kho_update(phys_addr_t fdt_addr, u64 fdt_size, + phys_addr_t scratch_addr, u64 scratch_size) +{ + struct linux_efi_kho_data *kho =3D efi_kho_table; + + if (!kho) + return -ENODEV; + + kho->fdt_addr =3D fdt_addr; + kho->fdt_size =3D fdt_size; + kho->scratch_addr =3D scratch_addr; + kho->scratch_size =3D scratch_size; + + return 0; +} +#endif + #ifdef CONFIG_KEXEC static int update_efi_random_seed(struct notifier_block *nb, unsigned long code, void *unused) diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi= /libstub/efi-stub.c index 42d6073bcd06..751f46280433 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -100,6 +100,29 @@ static void install_memreserve_table(void) efi_err("Failed to install memreserve config table!\n"); } =20 +static void install_kho_table(void) +{ +#ifdef CONFIG_EFI_KHO + struct linux_efi_kho_data *kho; + efi_guid_t kho_table_guid =3D LINUX_EFI_KEXEC_HANDOVER_GUID; + efi_status_t status; + + status =3D efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*kho), + (void **)&kho); + if (status !=3D EFI_SUCCESS) { + efi_err("Failed to allocate KHO config table!\n"); + return; + } + + *kho =3D (struct linux_efi_kho_data){}; + + status =3D efi_bs_call(install_configuration_table, &kho_table_guid, + kho); + if (status !=3D EFI_SUCCESS) + efi_err("Failed to install KHO config table!\n"); +#endif +} + static u32 get_supported_rt_services(void) { const efi_rt_properties_table_t *rt_prop_table; @@ -180,6 +203,8 @@ efi_status_t efi_stub_common(efi_handle_t handle, =20 install_memreserve_table(); =20 + install_kho_table(); + status =3D efi_boot_kernel(handle, image, image_addr, cmdline_ptr); =20 free_primary_display(dpy); diff --git a/include/linux/efi.h b/include/linux/efi.h index aa15ff88539b..564b3cbd5ccb 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_KEXEC_HANDOVER_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6= , 0x9e, 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 @@ -1273,6 +1274,41 @@ struct linux_efi_memreserve { =20 void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size); =20 +#ifdef CONFIG_EFI_KHO +/* + * The LINUX_EFI_KEXEC_HANDOVER_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 (e.g. LoongArch), where the /chosen linux,kho-fdt + * and linux,kho-scratch properties read by early_init_dt_check_kho() are = not + * available. The EFI stub allocates and installs the table once at boot; + * the current kernel updates its contents before a kexec, and the next + * kernel reads it back and calls kho_populate(). + * + * The layout is an ABI between the two kernels and carries no version + * field: an incompatible change must use a new GUID. 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; + +int efi_kho_update(phys_addr_t fdt_addr, u64 fdt_size, + phys_addr_t scratch_addr, u64 scratch_size); +#else +static inline int efi_kho_update(phys_addr_t fdt_addr, u64 fdt_size, + phys_addr_t scratch_addr, u64 scratch_size) +{ + return 0; +} +#endif + /* * 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 Sat Sep 26 05:27:45 2026 Received: from mta0.migadu.com (out-110.mta0.migadu.com [91.218.175.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E2E3B455176 for ; Fri, 4 Sep 2026 10:10:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.110 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516641; cv=none; b=rqlup/6WaeAzVMT3YXC8wEokvE+sd+vEb8+NvfRjZQvFyWyZjEApy/DCpxSBYRtmArX/KULvoeGzqdoyOl/hfY3oNBf3OlrJFHhP0IpVepz82W+TA1sGgvOdztV8azG1ijXClzpu5MxgEXZC/AIYDiHa2cTEVxHhXsae6OlDeAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516641; c=relaxed/simple; bh=PHW2ypkolV+36MeBrIflBY2kZtvuYhFSqnZa7Us0mSc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l2hbkk6ZG5iTXe2qno2RYp3le07YgLIQN1XoaZptNfo6EYOXNGHWM9HbA9QMHP+z2X0BrykHPpxiSILjCNIGnUu8FTGHvuXhFgkc4x9/yPAHulV7XRlOTt8eLR/YWIfCcrJD0jlqukw5O8zZ1eTiI10hB3WVRSPIvKS+qqpMemc= 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=PXOgys01; arc=none smtp.client-ip=91.218.175.110 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="PXOgys01" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=PHW2ypkolV+36MeBrIflBY2kZtvuYhFSqnZa7Us0mSc=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788516627; v=1; x=1789121427; b=PXOgys016DDQhBb/QNKwSkffh+43zc78rYU4UKbXwE6RWxIzonFp+epRA1onkLuvSzHVdEL+ VNsS5zGIUqkzkGmkoqh91TGfrg5FhVDnPYpbgM595l95zXwS+ioLRT2IssUtaRA8U+rJAL9eGUb AG038oagG6EWQpo4yMmgyNv4= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id b181acf3ff0b524f; Fri, 04 Sep 2026 10:10:27 +0000 X-Mizu-Trace-ID: b181acf3ff0b524f X-Migadu-Flow: FLOW_OUT From: George Guo To: rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, chenhuacai@kernel.org, ardb@kernel.org, shuah@kernel.org Cc: ilias.apalodimas@linaro.org, akpm@linux-foundation.org, baoquan.he@linux.dev, ruirui.yang@linux.dev, guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, liukexin@kylinos.cn, 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 v5 2/5] liveupdate: synchronize EFI KHO channel at execution Date: Fri, 4 Sep 2026 18:08:49 +0800 Message-ID: <20260904100852.26006-3-dongtai.guo@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260904100852.26006-1-dongtai.guo@linux.dev> References: <20260904100852.26006-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 Content-Type: text/plain; charset="utf-8" From: George Guo The EFI KHO configuration table is a global channel. Updating it while a candidate kexec image is still being loaded can leave the channel pointing at the failed candidate even though the previous image remains installed. Synchronize it instead from the image selected for execution. Use the actual scratch payload size rather than its page-aligned segment size, and propagate update failures before live-update serialization. Keep clearing the channel for cold and crash images best-effort. Signed-off-by: George Guo --- kernel/crash_core.c | 7 +++++++ kernel/kexec_core.c | 5 +++++ kernel/kexec_internal.h | 3 +++ kernel/liveupdate/kexec_handover.c | 33 ++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 2b36aa9fade0..6166ce4203d3 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -138,6 +138,13 @@ void __noclone __crash_kexec(struct pt_regs *regs) if (kexec_crash_image) { struct pt_regs fixed_regs; =20 + /* + * A crash image carries no KHO state: clear the + * transport so the crash kernel boots cold instead + * of reviving from stale state. + */ + (void)kho_sync_channel(kexec_crash_image); + crash_setup_regs(&fixed_regs, regs); crash_save_vmcoreinfo(); machine_crash_shutdown(&fixed_regs); diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index dc770b9a6d05..147f5b5b23d4 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1146,6 +1146,11 @@ int kernel_kexec(void) goto Unlock; } =20 + /* Synchronize the handover transport with the image being executed. */ + error =3D kho_sync_channel(kexec_image); + if (error) + goto Unlock; + if (!kexec_image->preserve_context) { error =3D liveupdate_reboot(); if (error) diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h index 228bb88c018b..4d4c2290e85c 100644 --- a/kernel/kexec_internal.h +++ b/kernel/kexec_internal.h @@ -46,6 +46,7 @@ struct kexec_buf; int kho_locate_mem_hole(struct kexec_buf *kbuf, int (*func)(struct resource *, void *)); int kho_fill_kimage(struct kimage *image); +int kho_sync_channel(struct kimage *image); #else static inline int kho_locate_mem_hole(struct kexec_buf *kbuf, int (*func)(struct resource *, void *)) @@ -54,5 +55,7 @@ static inline int kho_locate_mem_hole(struct kexec_buf *k= buf, } =20 static inline int kho_fill_kimage(struct kimage *image) { return 0; } + +static inline int kho_sync_channel(struct kimage *image) { return 0; } #endif /* CONFIG_KEXEC_HANDOVER */ #endif /* LINUX_KEXEC_INTERNAL_H */ diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_h= andover.c index 39f489a258d9..3aa5c66dfc6d 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -2074,6 +2075,38 @@ int kho_fill_kimage(struct kimage *image) return 0; } =20 +/* + * Synchronize the handover transport with the image that is about to be + * executed. The EFI config table channel is global, while kexec keeps + * separate images for a normal reboot and for crash. Write the state of = the + * selected image immediately before it is executed, rather than while a + * candidate image is being loaded, so a failed replacement cannot leave t= he + * channel pointing at that failed image. + * + * An image loaded through the legacy kexec_load() syscall, a crash image,= or + * an image loaded while KHO is disabled carries no handover state. Clear= the + * channel for those images so the next kernel boots cold instead of reviv= ing + * from stale state. Clearing is best-effort because an absent channel ca= nnot + * affect a cold boot. + */ +int kho_sync_channel(struct kimage *image) +{ + int err; + + if (!image->kho.fdt || !image->kho.scratch) { + efi_kho_update(0, 0, 0, 0); + return 0; + } + + err =3D efi_kho_update(image->kho.fdt, PAGE_SIZE, + image->kho.scratch->mem, + image->kho.scratch->bufsz); + if (err) + pr_warn("failed to update EFI config table: %d\n", err); + + return err; +} + static int kho_walk_scratch(struct kexec_buf *kbuf, int (*func)(struct resource *, void *)) { --=20 2.53.0 From nobody Sat Sep 26 05:27:45 2026 Received: from mta1.migadu.com (out-108.mta1.migadu.com [95.215.58.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 954AB4562AF for ; Fri, 4 Sep 2026 10:10:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516643; cv=none; b=XRc5DaWpQM3w1PCF07j1s9RLfnkIAUh6J2zfcxx1Dima18AGxdS9YTZRRQGhU3duP1HfcGIyUT9BGbu1ZRGxwdG29aYPaOvMzsq517uDtuYVJhiMgM67FEJI1wzyKG58WgTWlzL3WnXY2uZtAc0SvTvarmRfz0IfzBsu+B/innU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516643; c=relaxed/simple; bh=9aOZu5joPDLJyi4gz7dO0f9aMIY13LvVV/UJCIG+uIA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YLUfFnCgBxKj5JgpYxecANz3uU2EOxxQUqShDtHntP5R+o3SSn5lU5tZQXpipo0826dzoOZ4yXYehUCkCOytJpUqkYlkhhNtqiXcKQXOvsEyXZr6PnVRKAF/IMARHmnvZ7V3d/S6EQ+Dy5jkH4/Fck42ugIEIbVew1k+FQVu6JY= 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=OMDA5LLr; arc=none smtp.client-ip=95.215.58.108 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="OMDA5LLr" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=9aOZu5joPDLJyi4gz7dO0f9aMIY13LvVV/UJCIG+uIA=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788516633; v=1; x=1789121433; b=OMDA5LLrG8KDrfPVcchlsXbhmMDk865MrwFysRUs9ECTzubH+1uug4zwb1SxLQgRgJp9sDPU pfj7iDyCFWimdOIUFY3t2hkpZQ+W6CkKvuoIsdKvaRe8pZJdifYCaEboSCRwYEXnZxlVV+TDQUq IZXhR/Swxia4qtJDty0ZJ7oE= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 94f18b2629cbbf22; Fri, 04 Sep 2026 10:10:33 +0000 X-Mizu-Trace-ID: 94f18b2629cbbf22 X-Migadu-Flow: FLOW_OUT From: George Guo To: rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, chenhuacai@kernel.org, ardb@kernel.org, shuah@kernel.org Cc: ilias.apalodimas@linaro.org, akpm@linux-foundation.org, baoquan.he@linux.dev, ruirui.yang@linux.dev, guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, liukexin@kylinos.cn, 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 v5 3/5] liveupdate: kho_block: include linux/mm.h for virt/phys translation Date: Fri, 4 Sep 2026 18:08:50 +0800 Message-ID: <20260904100852.26006-4-dongtai.guo@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260904100852.26006-1-dongtai.guo@linux.dev> References: <20260904100852.26006-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 Content-Type: text/plain; charset="utf-8" From: George Guo kho_block.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 kho_block.c does not include , 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. This is the same root cause as the luo_session.c build fix previously acked by Mike Rapoport [1]; the virt_to_phys()/phys_to_virt() calls have since been refactored from luo_session.c into kho_block.c, so the fix moves with it. [1] https://lore.kernel.org/r/ai5nYlbERQBXRHSp@kernel.org/ Co-developed-by: Kexin Liu Signed-off-by: Kexin Liu Signed-off-by: George Guo --- kernel/liveupdate/kho_block.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/liveupdate/kho_block.c b/kernel/liveupdate/kho_block.c index 0d2a342ef422..0d56891b2f4c 100644 --- a/kernel/liveupdate/kho_block.c +++ b/kernel/liveupdate/kho_block.c @@ -25,6 +25,7 @@ #include #include #include +#include =20 /* * Safeguard limit for the number of serialization blocks. This is used to --=20 2.53.0 From nobody Sat Sep 26 05:27:45 2026 Received: from mta0.migadu.com (out-124.mta0.migadu.com [91.218.175.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0557E45562E for ; Fri, 4 Sep 2026 10:10:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516645; cv=none; b=MBXmnVmyE1xaE6P4rBK5EldyYxUrubyw4ggJEPIFHa+PzOvx9TkSH5FQnhxD8v3ABiMHfDJ/IHFbEn5eh3S9BrEwgoQxkehBpLFKqoB4o94qUmXfixHqZoI8F0n8EhjAVsNYJay+gt1gbObWi0LR5R7VMFQlM/sVWYCNhNEU8RI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516645; c=relaxed/simple; bh=3cPgANBsAN0TCTPt7lj+YGACHJ2FHFsC3fuQuOraQMA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=syV0n6zHGPRQSmOlgPxOLmsg8WuKJ/sZlgHqaHGi6BHHWBxTckImYHly8OJ8vJtW/BPwkCg08m2wXU/MSFupC1yz0qP12ySCvEWE6NrkNy/cWQl2dxEGCo1NbdHNtDNooNvUGLxOqRy4yDAGo51XZscm9JQSBGnQhIqvFOkXtJc= 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=jOYuemRc; arc=none smtp.client-ip=91.218.175.124 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="jOYuemRc" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=3cPgANBsAN0TCTPt7lj+YGACHJ2FHFsC3fuQuOraQMA=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788516636; v=1; x=1789121436; b=jOYuemRcWo5KL+QgZmCOv9MMIDTecQV4sy4qKJZoKBEmf5d3iNXBGG9bnLcIf1/rcI4GcegT fTUoHhog/yvL5xoVRmK1vLBPfhssLCgKuA5gqPNvAsN6NJaLVLdygn8180W+R8x0Ym3nDkEmxor QWjA6/7/PTIMc6MQxWL3/CAY= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 031a72623a973772; Fri, 04 Sep 2026 10:10:35 +0000 X-Mizu-Trace-ID: 031a72623a973772 X-Migadu-Flow: FLOW_OUT From: George Guo To: rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, chenhuacai@kernel.org, ardb@kernel.org, shuah@kernel.org Cc: ilias.apalodimas@linaro.org, akpm@linux-foundation.org, baoquan.he@linux.dev, ruirui.yang@linux.dev, guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, liukexin@kylinos.cn, 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 v5 4/5] LoongArch: enable kexec handover (KHO) Date: Fri, 4 Sep 2026 18:08:51 +0800 Message-ID: <20260904100852.26006-5-dongtai.guo@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260904100852.26006-1-dongtai.guo@linux.dev> References: <20260904100852.26006-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 Content-Type: text/plain; charset="utf-8" From: George Guo Enable ARCH_SUPPORTS_KEXEC_HANDOVER for 64-bit LoongArch. It selects EFI_KHO whenever KEXEC_HANDOVER is enabled, so LoongArch uses the architecture-agnostic EFI configuration table channel (LINUX_EFI_KEXEC_HANDOVER_GUID) introduced by this series to carry the KHO state across kexec. LoongArch boots through EFI without a device tree, so it cannot use the /chosen FDT path that arm64 and riscv use; the EFI configuration table channel is its handover transport. No arch-specific setup.c reader or machine_kexec_file.c writer is needed -- both live in the generic EFI code. Co-developed-by: Kexin Liu Signed-off-by: Kexin Liu Signed-off-by: George Guo --- arch/loongarch/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index a21f51e5815e..5eaa65578d58 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -685,6 +685,10 @@ config ARCH_SUPPORTS_KEXEC config ARCH_SUPPORTS_KEXEC_FILE def_bool 64BIT =20 +config ARCH_SUPPORTS_KEXEC_HANDOVER + def_bool 64BIT && EFI_STUB + select EFI_KHO if KEXEC_HANDOVER + config ARCH_SELECTS_KEXEC_FILE def_bool 64BIT depends on KEXEC_FILE --=20 2.53.0 From nobody Sat Sep 26 05:27:45 2026 Received: from mta0.migadu.com (out-130.mta0.migadu.com [91.218.175.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 056014582E6 for ; Fri, 4 Sep 2026 10:10:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516650; cv=none; b=WT92XfxsLNmi9CCLwfj3HGEVNhG5/179TNNazi+JV2iR5z/D0qm31gNPfETCD6VvTJWo0YBpe5C+c0NvNRq25xNir7jR1xM2j0EcSGHzRfobAsuuwR9c0BQ6/wf1PdxNsB8Sb/sj0nxu/tsEmL++N+AazM+pKJV2juMf0H/+s68= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788516650; c=relaxed/simple; bh=/oiDxHrVDKa7VGrXp6hL5mHL7wu/IJpMsp5HWkvasdU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=idn+NXLq8hZpZlaDtPPJ42Z04UH6ZWoiDbi4Q4mU3as17yErq37UdETae/1T3G4C0/mXHi0Nl2tzrttsgtjOA7IM+AKOkmv3Yj5JCOrTQamjJ0cuWIiRmi2q3qsX2/I6mtgSamf3FJ9Xy0sTWmXhph47r4sWcTujfCV6XhnrUQE= 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=dg/D2y03; arc=none smtp.client-ip=91.218.175.130 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="dg/D2y03" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=/oiDxHrVDKa7VGrXp6hL5mHL7wu/IJpMsp5HWkvasdU=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788516638; v=1; x=1789121438; b=dg/D2y03QKFwv7tqBdzyogXQtKWJ6QyG1AcV3TJ7bsMddVZASTcVwj62I/0/wfZEFineU+UJ CnMSS7E65A4K0nrZe9VxlTxW2cOeDVyg0D8ncWkhy27GLqaMZuMNHGYTvO2pwJF8dwi1WXA3wLh UgCdLH577lFDOfuakyd6prj0= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 6e5c0a65e25e0cdf; Fri, 04 Sep 2026 10:10:37 +0000 X-Mizu-Trace-ID: 6e5c0a65e25e0cdf X-Migadu-Flow: FLOW_OUT From: George Guo To: rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, chenhuacai@kernel.org, ardb@kernel.org, shuah@kernel.org Cc: ilias.apalodimas@linaro.org, akpm@linux-foundation.org, baoquan.he@linux.dev, ruirui.yang@linux.dev, guodongtai@kylinos.cn, kernel@xen0n.name, graf@amazon.com, liukexin@kylinos.cn, 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 v5 5/5] selftests/kho: add LoongArch vmtest support Date: Fri, 4 Sep 2026 18:08:52 +0800 Message-ID: <20260904100852.26006-6-dongtai.guo@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260904100852.26006-1-dongtai.guo@linux.dev> References: <20260904100852.26006-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 Content-Type: text/plain; charset="utf-8" From: George Guo Add loongarch.conf to configure QEMU's LoongArch virtual machine with a la464 CPU, an 8250 serial console, and the generic PCI host controller. Extend vmtest.sh to recognize loongarch64 as a supported target and map it to the loongarch kernel architecture name. Boot vmlinux.efi through EFI firmware. The KHO configuration table channel is installed by the EFI stub during the initial boot, so direct kernel boot bypasses the path that this test needs to exercise. QEMU_EFI defaults to the firmware shipped under /usr/share/edk2/loongarch64/ and can be overridden for distributions that install it under a different path, such as Debian's qemu-efi-loongarch64 package. QEMU's LoongArch virt machine has no i8042 controller. Enable the generic PCI host so its I/O space is mapped before the i8042 fallback probe accesses the legacy ports. This avoids disabling the i8042 options and allows the same kernel configuration to remain usable on physical hosts. Enable ACPI_SPCR_TABLE so the bare earlycon parameter can obtain the UART type, MMIO address and baud rate from the SPCR table installed by EDK2. Unlike on x86, ACPI_SPCR_TABLE does not default to enabled on LoongArch. Without it, no early console is registered for the EFI firmware boot path, and vmtest cannot observe the early kernel output in its serial log. The KHO vmtest requires CONFIG_DEFERRED_STRUCT_PAGE_INIT=3Dy, which depends on SPARSEMEM. Select CONFIG_SPARSEMEM_MANUAL=3Dy to satisfy the dependency on LoongArch. 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 | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) 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..36153b03c4ef --- /dev/null +++ b/tools/testing/selftests/kho/loongarch.conf @@ -0,0 +1,11 @@ +QEMU_EFI=3D"${QEMU_EFI:-/usr/share/edk2/loongarch64/QEMU_EFI.fd}" +QEMU_CMD=3D"qemu-system-loongarch64 -M virt -cpu la464 -bios $QEMU_EFI" +QEMU_KCONFIG=3D" +CONFIG_ACPI_SPCR_TABLE=3Dy +CONFIG_PCI_HOST_GENERIC=3Dy +CONFIG_SERIAL_8250=3Dy +CONFIG_SERIAL_8250_CONSOLE=3Dy +CONFIG_SPARSEMEM_MANUAL=3Dy +" +KERNEL_IMAGE=3D"vmlinux.efi" +KERNEL_CMDLINE=3D"console=3DttyS0 earlycon" diff --git a/tools/testing/selftests/kho/vmtest.sh b/tools/testing/selftest= s/kho/vmtest.sh index 0014bd76e88d..d05ba0734b25 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, loongarch64, x86_64 -h) display this help EOF } @@ -126,6 +126,7 @@ function target_to_arch() { =20 case $target in aarch64) echo "arm64" ;; + loongarch64) echo "loongarch" ;; x86_64) echo "x86" ;; *) skip "architecture $target is not supported" esac --=20 2.53.0