From: George Guo <dongtai.guo@linux.dev>
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 v6 2/8] kho: Write KHO state to the EFI table at kexec time
Date: Fri, 30 Oct 2026 02:29:49 +0900 [thread overview]
Message-ID: <20261029172956.20791-3-dongtai.guo@linux.dev> (raw)
In-Reply-To: <20261029172956.20791-1-dongtai.guo@linux.dev>
From: George Guo <guodongtai@kylinos.cn>
On arm64 and riscv, KHO addresses and sizes are passed through /chosen
properties in the boot FDT prepared for each kexec image. On x86, they
are passed through a SETUP_KEXEC_KHO record linked from the image's boot
parameters. These records are per-image, unlike the shared EFI table.
The EFI table is shared. A KHO-enabled normal image and a crash image
can both be loaded, but need different contents: the normal image needs
the KHO addresses, while the crash image needs an empty table. Updating
the table at load time cannot satisfy both.
Write the table in kernel_kexec() and __crash_kexec(), once the image
that will run is known. kho_update_efi_table() fills the table from that
image, or zeroes it if the image has no KHO state, including images
loaded with kexec_load().
Clear the table even with CONFIG_KEXEC_HANDOVER disabled, since the
kernel may have inherited a populated table. This prevents a later
kernel from trying to revive obsolete KHO state.
The table stores the size of the bootmem area list (bufsz), not of its
page-aligned segment, as the FDT and x86 code do. If updating or clearing
the table fails, kernel_kexec() returns before liveupdate_reboot(), so
LUO does not save state that the next kernel would not find.
__crash_kexec() ignores the error so the crash boot can still proceed.
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
kernel/crash_core.c | 6 ++++++
kernel/kexec_core.c | 5 +++++
kernel/kexec_internal.h | 8 ++++++++
kernel/liveupdate/kexec_handover.c | 26 ++++++++++++++++++++++++++
4 files changed, 45 insertions(+)
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 2b36aa9fade0..0f77adc0928b 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -138,6 +138,12 @@ void __noclone __crash_kexec(struct pt_regs *regs)
if (kexec_crash_image) {
struct pt_regs fixed_regs;
+ /*
+ * A crash image has no KHO state. Zero the EFI
+ * table so the crash kernel has no inherited KHO state.
+ */
+ (void)kho_update_efi_table(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..37597091770a 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1146,6 +1146,11 @@ int kernel_kexec(void)
goto Unlock;
}
+ /* Write this image's KHO state into the EFI table. */
+ error = kho_update_efi_table(kexec_image);
+ if (error)
+ goto Unlock;
+
if (!kexec_image->preserve_context) {
error = liveupdate_reboot();
if (error)
diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h
index 228bb88c018b..cfdd0b158f72 100644
--- a/kernel/kexec_internal.h
+++ b/kernel/kexec_internal.h
@@ -2,6 +2,7 @@
#ifndef LINUX_KEXEC_INTERNAL_H
#define LINUX_KEXEC_INTERNAL_H
+#include <linux/efi.h>
#include <linux/kexec.h>
struct kexec_segment;
@@ -46,6 +47,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_update_efi_table(struct kimage *image);
#else
static inline int kho_locate_mem_hole(struct kexec_buf *kbuf,
int (*func)(struct resource *, void *))
@@ -54,5 +56,11 @@ static inline int kho_locate_mem_hole(struct kexec_buf *kbuf,
}
static inline int kho_fill_kimage(struct kimage *image) { return 0; }
+
+static inline int kho_update_efi_table(struct kimage *image)
+{
+ /* The previous kernel may have left KHO state in the EFI table. */
+ return efi_kho_update(0, 0, 0, 0);
+}
#endif /* CONFIG_KEXEC_HANDOVER */
#endif /* LINUX_KEXEC_INTERNAL_H */
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 9a53d7750367..74c4633f5afc 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -15,6 +15,7 @@
#include <linux/crash_dump.h>
#include <linux/kmemleak.h>
#include <linux/count_zeros.h>
+#include <linux/efi.h>
#include <linux/kasan.h>
#include <linux/kexec.h>
#include <linux/kexec_handover.h>
@@ -2094,6 +2095,31 @@ int kho_fill_kimage(struct kimage *image)
return 0;
}
+/*
+ * Write the KHO state of @image into the EFI table, or zero the table if
+ * @image has none.
+ *
+ * There is one table, but the normal and the crash image can both be loaded,
+ * so the table is written just before @image runs rather than at load time.
+ * Crash images, images loaded with kexec_load() and images loaded with KHO
+ * disabled have no KHO state. Zeroing the table for them makes the next
+ * kernel boot without inherited KHO state instead of reading stale addresses.
+ */
+int kho_update_efi_table(struct kimage *image)
+{
+ int err;
+
+ if (!image->kho.fdt || !image->kho.bootmem)
+ return efi_kho_update(0, 0, 0, 0);
+
+ err = efi_kho_update(image->kho.fdt, PAGE_SIZE,
+ image->kho.bootmem->mem, image->kho.bootmem->bufsz);
+ if (err)
+ pr_warn("failed to update EFI config table: %pe\n", ERR_PTR(err));
+
+ return err;
+}
+
static int kho_walk_bootmem(struct kexec_buf *kbuf,
int (*func)(struct resource *, void *))
{
--
2.53.0
next prev parent reply other threads:[~2026-10-29 17:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 17:29 [PATCH v6 0/8] LoongArch: Add KHO support and selftests George Guo
2026-10-29 17:29 ` [PATCH v6 1/8] efi: Pass KHO state to the next kernel in a configuration table George Guo
2026-10-29 17:47 ` sashiko-bot
2026-10-29 19:28 ` Ard Biesheuvel
2026-10-29 19:42 ` Pratyush Yadav
2026-10-29 17:29 ` George Guo [this message]
2026-10-29 17:47 ` [PATCH v6 2/8] kho: Write KHO state to the EFI table at kexec time sashiko-bot
2026-10-29 17:29 ` [PATCH v6 3/8] kho: Include linux/mm.h in kho_block.c George Guo
2026-10-29 17:47 ` sashiko-bot
2026-10-29 17:29 ` [PATCH v6 4/8] kho: Add kho_disable() George Guo
2026-10-29 17:47 ` sashiko-bot
2026-10-29 17:29 ` [PATCH v6 5/8] LoongArch: Allow memblock arrays to resize George Guo
2026-10-29 17:47 ` sashiko-bot
2026-10-29 17:29 ` [PATCH v6 6/8] LoongArch: Enable kexec handover (KHO) George Guo
2026-10-29 17:47 ` sashiko-bot
2026-10-29 17:29 ` [PATCH v6 7/8] selftests/kho: Add LoongArch vmtest support George Guo
2026-10-29 17:47 ` sashiko-bot
2026-10-29 17:29 ` [PATCH v6 8/8] selftests/liveupdate: " George Guo
2026-10-29 17:47 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261029172956.20791-3-dongtai.guo@linux.dev \
--to=dongtai.guo@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=ardb@kernel.org \
--cc=baoquan.he@linux.dev \
--cc=chenhuacai@kernel.org \
--cc=graf@amazon.com \
--cc=guodongtai@kylinos.cn \
--cc=ilias.apalodimas@linaro.org \
--cc=kernel@xen0n.name \
--cc=kexec@lists.infradead.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=liukexin@kylinos.cn \
--cc=loongarch@lists.linux.dev \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=rppt@kernel.org \
--cc=ruirui.yang@linux.dev \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.