Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
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 v5 2/5] liveupdate: synchronize EFI KHO channel at execution
Date: Fri,  4 Sep 2026 18:08:49 +0800	[thread overview]
Message-ID: <20260904100852.26006-3-dongtai.guo@linux.dev> (raw)
In-Reply-To: <20260904100852.26006-1-dongtai.guo@linux.dev>

From: George Guo <guodongtai@kylinos.cn>

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 <guodongtai@kylinos.cn>
---
 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;
 
+			/*
+			 * 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;
 	}
 
+	/* Synchronize the handover transport with the image being executed. */
+	error = kho_sync_channel(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..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 *kbuf,
 }
 
 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_handover.c
index 39f489a258d9..3aa5c66dfc6d 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -14,6 +14,7 @@
 #include <linux/cma.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>
@@ -2074,6 +2075,38 @@ int kho_fill_kimage(struct kimage *image)
 	return 0;
 }
 
+/*
+ * 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 the
+ * 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 reviving
+ * from stale state.  Clearing is best-effort because an absent channel cannot
+ * 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 = 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 *))
 {
-- 
2.53.0



  parent reply	other threads:[~2026-09-04 10:10 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-04 10:08 [PATCH v5 0/5] LoongArch: add KHO support and selftests George Guo
2026-09-04 10:08 ` [PATCH v5 1/5] efi: add a KHO configuration table channel George Guo
2026-09-04 10:08 ` George Guo [this message]
2026-09-04 10:08 ` [PATCH v5 3/5] liveupdate: kho_block: include linux/mm.h for virt/phys translation George Guo
2026-09-04 10:08 ` [PATCH v5 4/5] LoongArch: enable kexec handover (KHO) George Guo
2026-09-04 10:08 ` [PATCH v5 5/5] selftests/kho: add LoongArch vmtest support George Guo

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=20260904100852.26006-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox