From nobody Mon Feb 9 14:03:22 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (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 6AC6D72631 for ; Fri, 9 Jan 2026 00:11:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767917500; cv=none; b=NVOaou8SoU0hi+eYqmSD38mz6BaSOU3JfL8rVsy62tJWHLLnec4ATGPxL8rnX4+lwWGyY6KQU1FdTwE5O+N1oAiW6KADJwvZkFhvYYEdcBN4EXWYNhu3NP4EuY0+W23yPi+Ja3GerS1wSxFsh1EuiOO1mzF7kJiMKyZpg/9pm0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767917500; c=relaxed/simple; bh=Xzvwz6V0XrEg3MANF5PBsjfm1JJj+PwE3Kxmw6I2OiY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=J+cHLRbSOO1CJ7QrKgi1Q9cITKvDMyJEtlh2fm9Plmqy3K/HY9VOTE1rJIWS2FCpTjToUaGEjFXIj3FEKNXEV0zu6zi8oXmFft3DaD+RYrOMgmOC1doPGNLgSJFd2350v9DuptGACaupOBfq4bx6Now6jmyh6amjU6uZlZL/tvA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jasonmiu.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=BBod5SNN; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jasonmiu.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BBod5SNN" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-11b7dbce216so4793586c88.1 for ; Thu, 08 Jan 2026 16:11:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767917495; x=1768522295; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=EKgMKBT5OFHokoCGrW4c5BW1nZH0a8FU1Tg2IfU9qt0=; b=BBod5SNNGP4t+QB08upCLN5L3dC0QUiak2cMZJ2jOneY27AC5jF0YibYv6y1gwcXyg LoIlybxjslenMXapzG34+vrSbql/Ng4Fhidyo5Hju9n3tkHB6kdKnzJUEzfWJToppg5g mRxVcM/sCrZT6hAAiSvYtreR3L2sCaHHQ1AdfMNauETyIDdjJPOJjZasmzKD55P77bX3 53Jr9Upp3pXZcxXw/p0iF64PD88AZkws6h5/4V8QNOZuEutBRLsv/zkAKWwrVonzE/4A cuJyzKKP7Q6VQySIK4xwHjewR96yrVg4+JzZOM0OfQSOSAei1js5hPIxTafysqpEVFPt lmyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767917495; x=1768522295; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EKgMKBT5OFHokoCGrW4c5BW1nZH0a8FU1Tg2IfU9qt0=; b=TiXd3xvjTvuUFBt9x3VhMlaL6Oh7xtYD+zbRPWMnj4ViGQkSrisgpYKGFifNJE7MG1 Y3VrweBDSSfnUrVNr9kDFDzX6eC2bvvA+xbFaSVQ6oI6CqC+x3bkqQVTqDQoPENzkcc5 hrxAHFT/RAUK+tg8gY/L2s5pWRmsMuJjX8w48AwCmrtUtyB6BLHocPI/e6TmNsP129Y/ GWShzv9PHqNRyfGnF8UbhmbO5Fjr5qK1DpBwSas/aTFelC1l8zflDQJhbKbn/4+gt7g1 Dz+AuAJ3I10XO3/Gw2ZQjvUJan8TP0vPHLFfUk7qcK3u5pvOziVZisLe7Bz/jKFRCymr XZ2A== X-Forwarded-Encrypted: i=1; AJvYcCWKXBVobTbPvFI2WEm8Dfw13K3cZDXMgcaxliBJy0xYs54xtckeTOoUaxp4VGz78u2BPyYp2gwQAc4bKUg=@vger.kernel.org X-Gm-Message-State: AOJu0Yx6TpyPUGK1P1vV/+JWrcKgPRBFaVHW0Uh6KBTKP8uYsVfrhvxC +ajHIOa33Tmc5hlmP5I2YwQpqwAv32u6DYUWfwyR60tmEqhIbRDRN4XW3fPvrVe8jekqILF1Fqw r7yqdUuT0qQ61Yw== X-Google-Smtp-Source: AGHT+IEFOtcW4jk0aXhAffgAIqkI0UKGPAV2Ujq35QNsvPluSbvTyZRl2dRJINPWfimpz9fDoX9MuIGSXj0PtA== X-Received: from dlbdx12.prod.google.com ([2002:a05:7022:e0c:b0:11d:cc5a:2cd0]) (user=jasonmiu job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:985:b0:11b:99a2:9082 with SMTP id a92af1059eb24-121f8adcfe2mr5422835c88.15.1767917495328; Thu, 08 Jan 2026 16:11:35 -0800 (PST) Date: Thu, 8 Jan 2026 16:11:27 -0800 In-Reply-To: <20260109001127.2596222-1-jasonmiu@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260109001127.2596222-1-jasonmiu@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109001127.2596222-3-jasonmiu@google.com> Subject: [PATCH v4 2/2] kho: Remove finalize state and clients From: Jason Miu To: Alexander Graf , Andrew Morton , Baoquan He , Changyuan Lyu , David Matlack , David Rientjes , Jason Gunthorpe , Jason Miu , Mike Rapoport , Pasha Tatashin , Pratyush Yadav , kexec@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Eliminate the `kho_finalize()` function and its associated state from the KHO subsystem. The transition to a radix tree for memory tracking makes the explicit "finalize" state and its serialization step obsolete. Remove the `kho_finalize()` and `kho_finalized()` APIs and their stub implementations. Update KHO client code and the debugfs interface to no longer call or depend on the `kho_finalize()` mechanism. Complete the move towards a stateless KHO, simplifying the overall design by removing unnecessary state management. Signed-off-by: Jason Miu --- Documentation/admin-guide/mm/kho.rst | 52 ++++----------------- Documentation/core-api/kho/index.rst | 17 ++----- kernel/liveupdate/kexec_handover.c | 21 +-------- kernel/liveupdate/kexec_handover_debugfs.c | 23 --------- kernel/liveupdate/kexec_handover_internal.h | 3 -- kernel/liveupdate/luo_core.c | 12 +---- kernel/liveupdate/luo_flb.c | 2 +- tools/testing/selftests/kho/init.c | 20 -------- 8 files changed, 16 insertions(+), 134 deletions(-) diff --git a/Documentation/admin-guide/mm/kho.rst b/Documentation/admin-gui= de/mm/kho.rst index 6dc18ed4b886..57d5690dce77 100644 --- a/Documentation/admin-guide/mm/kho.rst +++ b/Documentation/admin-guide/mm/kho.rst @@ -28,20 +28,10 @@ per NUMA node scratch regions on boot. Perform a KHO kexec =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -First, before you perform a KHO kexec, you need to move the system into -the :ref:`KHO finalization phase ` :: - - $ echo 1 > /sys/kernel/debug/kho/out/finalize - -After this command, the KHO FDT is available in -``/sys/kernel/debug/kho/out/fdt``. Other subsystems may also register -their own preserved sub FDTs under -``/sys/kernel/debug/kho/out/sub_fdts/``. - -Next, load the target payload and kexec into it. It is important that you -use the ``-s`` parameter to use the in-kernel kexec file loader, as user -space kexec tooling currently has no support for KHO with the user space -based file loader :: +To perform a KHO kexec, load the target payload and kexec into it. It +is important that you use the ``-s`` parameter to use the in-kernel +kexec file loader, as user space kexec tooling currently has no +support for KHO with the user space based file loader :: =20 # kexec -l /path/to/bzImage --initrd /path/to/initrd -s # kexec -e @@ -52,40 +42,19 @@ For example, if you used ``reserve_mem`` command line p= arameter to create an early memory reservation, the new kernel will have that memory at the same physical address as the old kernel. =20 -Abort a KHO exec -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -You can move the system out of KHO finalization phase again by calling :: - - $ echo 0 > /sys/kernel/debug/kho/out/active - -After this command, the KHO FDT is no longer available in -``/sys/kernel/debug/kho/out/fdt``. - debugfs Interfaces =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 +These debugfs interfaces are available when the kernel is compiled with +``CONFIG_KEXEC_HANDOVER_DEBUGFS`` set to y. + Currently KHO creates the following debugfs interfaces. Notice that these interfaces may change in the future. They will be moved to sysfs once KHO = is stabilized. =20 -``/sys/kernel/debug/kho/out/finalize`` - Kexec HandOver (KHO) allows Linux to transition the state of - compatible drivers into the next kexec'ed kernel. To do so, - device drivers will instruct KHO to preserve memory regions, - which could contain serialized kernel state. - While the state is serialized, they are unable to perform - any modifications to state that was serialized, such as - handed over memory allocations. - - When this file contains "1", the system is in the transition - state. When contains "0", it is not. To switch between the - two states, echo the respective number into this file. - ``/sys/kernel/debug/kho/out/fdt`` - When KHO state tree is finalized, the kernel exposes the - flattened device tree blob that carries its current KHO - state in this file. Kexec user space tooling can use this + The kernel exposes the flattened device tree blob that carries its + current KHO state in this file. Kexec user space tooling can use this as input file for the KHO payload image. =20 ``/sys/kernel/debug/kho/out/scratch_len`` @@ -100,8 +69,7 @@ stabilized. it should place its payload images. =20 ``/sys/kernel/debug/kho/out/sub_fdts/`` - In the KHO finalization phase, KHO producers register their own - FDT blob under this directory. + KHO producers can register their own FDT blob under this directory. =20 ``/sys/kernel/debug/kho/in/fdt`` When the kernel was booted with Kexec HandOver (KHO), diff --git a/Documentation/core-api/kho/index.rst b/Documentation/core-api/= kho/index.rst index 7ddc4d3ecac5..286a6d0b9956 100644 --- a/Documentation/core-api/kho/index.rst +++ b/Documentation/core-api/kho/index.rst @@ -9,8 +9,9 @@ Kexec Handover Subsystem Overview =3D=3D=3D=3D=3D=3D=3D=3D =20 -Kexec HandOver (KHO) is a mechanism that allows Linux to preserve memory -regions, which could contain serialized system states, across kexec. +Kexec HandOver (KHO) is a mechanism that allows Linux to preserve +memory regions, containing kernel data structures in their live, +in-memory format, across kexec. =20 KHO uses :ref:`flattened device tree (FDT) ` to pass information = about the preserved state from pre-exec kernel to post-kexec kernel and :ref:`sc= ratch @@ -71,18 +72,6 @@ for boot memory allocations and as target memory for kex= ec blobs, some parts of that memory region may be reserved. These reservations are irrelevant f= or the next KHO, because kexec can overwrite even the original kernel. =20 -KHO finalization phase -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -.. _kho-finalization-phase: - -To enable user space based kexec file loader, the kernel needs to be able = to -provide the FDT that describes the current kernel's state before -performing the actual kexec. The process of generating that FDT is -called serialization. When the FDT is generated, some properties -of the system may become immutable because they are already written down -in the FDT. That state is called the KHO finalization phase. - Kexec Handover Radix Tree =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D =20 diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_h= andover.c index 440f6de65eb2..8d9cf939790c 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -69,8 +69,7 @@ early_param("kho", kho_parse_enable); =20 struct kho_out { void *fdt; - bool finalized; - struct mutex lock; /* protects KHO FDT finalization */ + struct mutex lock; /* protects KHO FDT */ =20 struct kho_radix_tree radix_tree; struct kho_debugfs dbg; @@ -81,7 +80,6 @@ static struct kho_out kho_out =3D { .radix_tree =3D { .lock =3D __MUTEX_INITIALIZER(kho_out.radix_tree.lock), }, - .finalized =3D false, }; =20 /** @@ -1191,23 +1189,6 @@ void kho_restore_free(void *mem) } EXPORT_SYMBOL_GPL(kho_restore_free); =20 -int kho_finalize(void) -{ - if (!kho_enable) - return -EOPNOTSUPP; - - guard(mutex)(&kho_out.lock); - kho_out.finalized =3D true; - - return 0; -} - -bool kho_finalized(void) -{ - guard(mutex)(&kho_out.lock); - return kho_out.finalized; -} - struct kho_in { phys_addr_t fdt_phys; phys_addr_t scratch_phys; diff --git a/kernel/liveupdate/kexec_handover_debugfs.c b/kernel/liveupdate= /kexec_handover_debugfs.c index 2abbf62ba942..430c9521d59c 100644 --- a/kernel/liveupdate/kexec_handover_debugfs.c +++ b/kernel/liveupdate/kexec_handover_debugfs.c @@ -75,24 +75,6 @@ void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, voi= d *fdt) } } =20 -static int kho_out_finalize_get(void *data, u64 *val) -{ - *val =3D kho_finalized(); - - return 0; -} - -static int kho_out_finalize_set(void *data, u64 val) -{ - if (val) - return kho_finalize(); - else - return -EINVAL; -} - -DEFINE_DEBUGFS_ATTRIBUTE(kho_out_finalize_fops, kho_out_finalize_get, - kho_out_finalize_set, "%llu\n"); - static int scratch_phys_show(struct seq_file *m, void *v) { for (int i =3D 0; i < kho_scratch_cnt; i++) @@ -198,11 +180,6 @@ __init int kho_out_debugfs_init(struct kho_debugfs *db= g) if (IS_ERR(f)) goto err_rmdir; =20 - f =3D debugfs_create_file("finalize", 0600, dir, NULL, - &kho_out_finalize_fops); - if (IS_ERR(f)) - goto err_rmdir; - dbg->dir =3D dir; dbg->sub_fdt_dir =3D sub_fdt_dir; return 0; diff --git a/kernel/liveupdate/kexec_handover_internal.h b/kernel/liveupdat= e/kexec_handover_internal.h index 0202c85ad14f..9a832a35254c 100644 --- a/kernel/liveupdate/kexec_handover_internal.h +++ b/kernel/liveupdate/kexec_handover_internal.h @@ -22,9 +22,6 @@ struct kho_debugfs {}; extern struct kho_scratch *kho_scratch; extern unsigned int kho_scratch_cnt; =20 -bool kho_finalized(void); -int kho_finalize(void); - #ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS int kho_debugfs_init(void); void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt); diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c index 7a9ef16b37d8..2df798e07668 100644 --- a/kernel/liveupdate/luo_core.c +++ b/kernel/liveupdate/luo_core.c @@ -231,17 +231,7 @@ int liveupdate_reboot(void) =20 luo_flb_serialize(); =20 - err =3D kho_finalize(); - if (err) { - pr_err("kho_finalize failed %d\n", err); - /* - * kho_finalize() may return libfdt errors, to aboid passing to - * userspace unknown errors, change this to EAGAIN. - */ - err =3D -EAGAIN; - } - - return err; + return 0; } =20 /** diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index 4c437de5c0b0..ddc9110a2b45 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -630,7 +630,7 @@ int __init luo_flb_setup_incoming(void *fdt_in) * data handle, and the final reference count. This allows the new kernel = to * find the appropriate handler and reconstruct the FLB's state. * - * Context: Called from liveupdate_reboot() just before kho_finalize(). + * Context: Called from liveupdate_reboot() just before return. */ void luo_flb_serialize(void) { diff --git a/tools/testing/selftests/kho/init.c b/tools/testing/selftests/k= ho/init.c index 6d9e91d55d68..88a41b6eba95 100644 --- a/tools/testing/selftests/kho/init.c +++ b/tools/testing/selftests/kho/init.c @@ -11,7 +11,6 @@ /* from arch/x86/include/asm/setup.h */ #define COMMAND_LINE_SIZE 2048 =20 -#define KHO_FINALIZE "/debugfs/kho/out/finalize" #define KERNEL_IMAGE "/kernel" =20 static int mount_filesystems(void) @@ -22,22 +21,6 @@ static int mount_filesystems(void) return mount("proc", "/proc", "proc", 0, NULL); } =20 -static int kho_enable(void) -{ - const char enable[] =3D "1"; - int fd; - - fd =3D open(KHO_FINALIZE, O_RDWR); - if (fd < 0) - return -1; - - if (write(fd, enable, sizeof(enable)) !=3D sizeof(enable)) - return 1; - - close(fd); - return 0; -} - static long kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char *cmdline, unsigned long flags) @@ -78,9 +61,6 @@ int main(int argc, char *argv[]) if (mount_filesystems()) goto err_reboot; =20 - if (kho_enable()) - goto err_reboot; - if (kexec_load()) goto err_reboot; =20 --=20 2.52.0.457.g6b5491de43-goog