From nobody Wed Dec 17 21:30:17 2025 Received: from mail-ua1-f44.google.com (mail-ua1-f44.google.com [209.85.222.44]) (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 416C72F39D0 for ; Sat, 1 Nov 2025 14:23:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007016; cv=none; b=aWKkPDA4ghULCdC1UMqKvysSNCDAkD8PFQkw0EM10pEHmduPBEywwN/91ouHvoCSjwwDqnP19X5xqCJNbupif/pHpoStk4K9AWv4JUq9z0qgQgemsThJnjf66rJHA5z0OwiJhtlFZ7WTlTiMZrLqNzUw4ulcrMydfnHckDWMk+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007016; c=relaxed/simple; bh=vTIRXTtMPnIKnSywgCkbj/+Q6QBlEM9kgGZvr2ZMUm0=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PGQZEXEHbpTqZVWRzzthOCz6+9cn7VmTWq9Dbb7613JPXiWWARgcFVli3xSi2PvwxWp6p/75BiJfkFHnrQWalW7fbeFZ/qTrjVB8hEWt9N7jktxrigTRAY5KH+mNyj7wDWRz0nMCll5geB3y8d30gZU3ThPp5fq3xo4+61ajSjg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=hv9C3mY9; arc=none smtp.client-ip=209.85.222.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="hv9C3mY9" Received: by mail-ua1-f44.google.com with SMTP id a1e0cc1a2514c-89019079fbeso1459836241.2 for ; Sat, 01 Nov 2025 07:23:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007013; x=1762611813; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=plOa1OL0gZsScg9TiwwvNHv6SGSDOjKmUNm5LtJnuWY=; b=hv9C3mY9gDPxKEiZGWt4arPIw7FIl+5FrkmE/jR1IBqpcaL9+orRmu81fjcjBHtNEj WNM9cwhTdOZdT1R9INdqecJBDoa4n5Lo7psvNDNI0awAZ/q+O+DAPLxaV/F0iYtNBIz8 Qs0iCc9ZWCgVvqCJtMDW0KwPWqK+arcV8l0dkPB+Aw1QbFS2wFKXOy7OajmakTF51E2E lWKBjUWScjlD5aE6Y2rKjcFruGuehBDMiVOt1ri2gs65d0qmZN+CXHdeMTAhai4Ocx1I 4COgNS8TkT96xPqeY13//8xljbWlkCTagvWsiM4nFVoMUOXKB+IvIx4Jc95FG50VTCOf qCfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007013; x=1762611813; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=plOa1OL0gZsScg9TiwwvNHv6SGSDOjKmUNm5LtJnuWY=; b=cVkS+iXJ/fEKm/9A1O74kURWRz7qUCbR/PoHQGtbf8/uaSUoFj3eB09zEcaco6lopY khk2LCyXBbPr45YlCbxpm0HnRRfDh8kyzOT5KuJ91DGEQjJywtF5gdJKym2kd6QnVSBf 1+0pBClqRBc8+ixZJu4ECE+JDuiD9R7YR857CfkEul17gW3HbRpALY5+DHuTfchIVkAg kbbgWJNDOvzCEYO7gWFiu05lHlabU0D7snEPO4uZrsvA+fUtqzbr2yrjPIGE1j87uyxG lz0gxemaQxBzl3UTMEhjnJCIjGuJmt2fQlOTkxs9u2XGPXWBGze4XPPo/5pcB9uNHt+o +V/g== X-Forwarded-Encrypted: i=1; AJvYcCV7Y0mL5+k+qJ0HO8INTT+cQfFDJew9WTagZ3Gn7lCykZJPZ8yodkwMjk9DPmWN71S3QZYy733zBiXea18=@vger.kernel.org X-Gm-Message-State: AOJu0YztPuiXprxp5Iyfjy3V1kxIVrjEu2P4Lt3ZWZqAaaXxPJRu/Y8a aBx/VrVccgONSeGgSOcfHW1fYxkb5L1OTMxNbwNGfxd1nD7V8kIK9IZ88uJ06M4UlHQ= X-Gm-Gg: ASbGncutWuTVXmkoPeDzpQHhbJo/c6putdQgwrYelZQ7+cLjF9gQ8VjZQZLfwfDwAvO 0+B+u7DrYrvmMKdrUmWU2IhgZB8bXiU5Rti5mWTk9iFl6UB9ESkOGzCBFr+9AAA1IvYzJdH7Ana 8AtfTC24iPlLHb9QIcK6gzC1yi9QSiYiXGOCz1oQM1KTgEOMsW5BXr6bTujsbmTAKrrUDCbWtGm el+ry+5pOnq/6eU8tFTvwmUu7GHQZwZJJXhPk9kH5H/QxLClBjoXhSspxRtua/aSZ/hPt0GJAvA qzullwB1+UZQnVATwncmc6FU8z+rI7VNRTu3tQLuWikL1QnPANdzXMAwRGSjDIaJyBBQmbU/0st 90kIEtfRlWGaQ5+g9p3EgZpB1tjyihNbYHAIH2jYOiNBVCPAZuvK8haSZDqaWcTmTNwYzDBS/Ri E7irQRvtrzu05edk2sv7WsfQDT/t53tfDOSrTneuEgU6SlEk2heJCo1dqztu/n X-Google-Smtp-Source: AGHT+IEXHIbTFAWI7hQOxYyfZm0I3KA43OaSBxKIz4wfRB0hVmanX6lgmn1m2e3fK+RpbyWde6iXNg== X-Received: by 2002:a05:6102:e0f:b0:5db:417d:923d with SMTP id ada2fe7eead31-5dbb12ef1cdmr1982595137.22.1762007013002; Sat, 01 Nov 2025 07:23:33 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:31 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 1/9] kho: make debugfs interface optional Date: Sat, 1 Nov 2025 10:23:17 -0400 Message-ID: <20251101142325.1326536-2-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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" Currently, KHO is controlled via debugfs interface, but once LUO is introduced, it can control KHO, and the debug interface becomes optional. Add a separate config CONFIG_KEXEC_HANDOVER_DEBUGFS that enables the debugfs interface, and allows to inspect the tree. Move all debugfs related code to a new file to keep the .c files clear of ifdefs. Co-developed-by: Mike Rapoport (Microsoft) Signed-off-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav --- MAINTAINERS | 2 +- kernel/Kconfig.kexec | 12 +- kernel/Makefile | 1 + kernel/kexec_handover.c | 273 +++++--------------------- kernel/kexec_handover_debugfs.c | 216 ++++++++++++++++++++ kernel/kexec_handover_internal.h | 39 ++++ tools/testing/selftests/kho/vmtest.sh | 1 + 7 files changed, 320 insertions(+), 224 deletions(-) create mode 100644 kernel/kexec_handover_debugfs.c diff --git a/MAINTAINERS b/MAINTAINERS index 2628431dcdfe..bdd0a1260421 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13795,7 +13795,7 @@ S: Maintained F: Documentation/admin-guide/mm/kho.rst F: Documentation/core-api/kho/* F: include/linux/kexec_handover.h -F: kernel/kexec_handover.c +F: kernel/kexec_handover* F: tools/testing/selftests/kho/ =20 KEYS-ENCRYPTED diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec index 54e581072617..cc6743137946 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -100,7 +100,6 @@ config KEXEC_HANDOVER depends on !DEFERRED_STRUCT_PAGE_INIT select MEMBLOCK_KHO_SCRATCH select KEXEC_FILE - select DEBUG_FS select LIBFDT select CMA help @@ -118,6 +117,17 @@ config KEXEC_HANDOVER_DEBUG scenarios and the extra code might be adding overhead it is only optionally enabled. =20 +config KEXEC_HANDOVER_DEBUGFS + bool "kexec handover debugfs interface" + default KEXEC_HANDOVER + depends on KEXEC_HANDOVER + select DEBUG_FS + help + Allow to control kexec handover device tree via debugfs + interface, i.e. finalize the state or aborting the finalization. + Also, enables inspecting the KHO fdt trees with the debugfs binary + blobs. + config CRASH_DUMP bool "kernel crash dumps" default ARCH_DEFAULT_CRASH_DUMP diff --git a/kernel/Makefile b/kernel/Makefile index 9fe722305c9b..2cf7909a74e5 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_KEXEC_FILE) +=3D kexec_file.o obj-$(CONFIG_KEXEC_ELF) +=3D kexec_elf.o obj-$(CONFIG_KEXEC_HANDOVER) +=3D kexec_handover.o obj-$(CONFIG_KEXEC_HANDOVER_DEBUG) +=3D kexec_handover_debug.o +obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS) +=3D kexec_handover_debugfs.o obj-$(CONFIG_BACKTRACE_SELF_TEST) +=3D backtracetest.o obj-$(CONFIG_COMPAT) +=3D compat.o obj-$(CONFIG_CGROUPS) +=3D cgroup/ diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index de4466b47455..da071277d85e 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -30,6 +29,7 @@ */ #include "../mm/internal.h" #include "kexec_internal.h" +#include "kexec_handover_internal.h" =20 #define KHO_FDT_COMPATIBLE "kho-v1" #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map" @@ -105,8 +105,6 @@ struct khoser_mem_chunk; =20 struct kho_serialization { struct page *fdt; - struct list_head fdt_list; - struct dentry *sub_fdt_dir; struct kho_mem_track track; /* First chunk of serialized preserved memory map */ struct khoser_mem_chunk *preserved_mem_map; @@ -114,20 +112,16 @@ struct kho_serialization { =20 struct kho_out { struct blocking_notifier_head chain_head; - - struct dentry *dir; - struct mutex lock; /* protects KHO FDT finalization */ - struct kho_serialization ser; bool finalized; + struct kho_debugfs dbg; }; =20 static struct kho_out kho_out =3D { .chain_head =3D BLOCKING_NOTIFIER_INIT(kho_out.chain_head), .lock =3D __MUTEX_INITIALIZER(kho_out.lock), .ser =3D { - .fdt_list =3D LIST_HEAD_INIT(kho_out.ser.fdt_list), .track =3D { .orders =3D XARRAY_INIT(kho_out.ser.track.orders, 0), }, @@ -477,8 +471,8 @@ static void __init kho_mem_deserialize(const void *fdt) * area for early allocations that happen before page allocator is * initialized. */ -static struct kho_scratch *kho_scratch; -static unsigned int kho_scratch_cnt; +struct kho_scratch *kho_scratch; +unsigned int kho_scratch_cnt; =20 /* * The scratch areas are scaled by default as percent of memory allocated = from @@ -674,37 +668,6 @@ static void __init kho_reserve_scratch(void) kho_enable =3D false; } =20 -struct fdt_debugfs { - struct list_head list; - struct debugfs_blob_wrapper wrapper; - struct dentry *file; -}; - -static int kho_debugfs_fdt_add(struct list_head *list, struct dentry *dir, - const char *name, const void *fdt) -{ - struct fdt_debugfs *f; - struct dentry *file; - - f =3D kmalloc(sizeof(*f), GFP_KERNEL); - if (!f) - return -ENOMEM; - - f->wrapper.data =3D (void *)fdt; - f->wrapper.size =3D fdt_totalsize(fdt); - - file =3D debugfs_create_blob(name, 0400, dir, &f->wrapper); - if (IS_ERR(file)) { - kfree(f); - return PTR_ERR(file); - } - - f->file =3D file; - list_add(&f->list, list); - - return 0; -} - /** * kho_add_subtree - record the physical address of a sub FDT in KHO root = tree. * @ser: serialization control object passed by KHO notifiers. @@ -716,7 +679,8 @@ static int kho_debugfs_fdt_add(struct list_head *list, = struct dentry *dir, * by KHO for the new kernel to retrieve it after kexec. * * A debugfs blob entry is also created at - * ``/sys/kernel/debug/kho/out/sub_fdts/@name``. + * ``/sys/kernel/debug/kho/out/sub_fdts/@name`` when kernel is configured = with + * CONFIG_KEXEC_HANDOVER_DEBUGFS * * Return: 0 on success, error code on failure */ @@ -733,7 +697,7 @@ int kho_add_subtree(struct kho_serialization *ser, cons= t char *name, void *fdt) if (err) return err; =20 - return kho_debugfs_fdt_add(&ser->fdt_list, ser->sub_fdt_dir, name, fdt); + return kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false); } EXPORT_SYMBOL_GPL(kho_add_subtree); =20 @@ -1064,30 +1028,7 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *= preservation) } EXPORT_SYMBOL_GPL(kho_restore_vmalloc); =20 -/* Handling for debug/kho/out */ - -static struct dentry *debugfs_root; - -static int kho_out_update_debugfs_fdt(void) -{ - int err =3D 0; - struct fdt_debugfs *ff, *tmp; - - if (kho_out.finalized) { - err =3D kho_debugfs_fdt_add(&kho_out.ser.fdt_list, kho_out.dir, - "fdt", page_to_virt(kho_out.ser.fdt)); - } else { - list_for_each_entry_safe(ff, tmp, &kho_out.ser.fdt_list, list) { - debugfs_remove(ff->file); - list_del(&ff->list); - kfree(ff); - } - } - - return err; -} - -static int kho_abort(void) +static int __kho_abort(void) { int err; unsigned long order; @@ -1120,7 +1061,28 @@ static int kho_abort(void) return err; } =20 -static int kho_finalize(void) +int kho_abort(void) +{ + int ret =3D 0; + + if (!kho_enable) + return -EOPNOTSUPP; + + guard(mutex)(&kho_out.lock); + if (!kho_out.finalized) + return -ENOENT; + + ret =3D __kho_abort(); + if (ret) + return ret; + + kho_out.finalized =3D false; + kho_debugfs_cleanup(&kho_out.dbg); + + return 0; +} + +static int __kho_finalize(void) { int err =3D 0; u64 *preserved_mem_map; @@ -1163,118 +1125,46 @@ static int kho_finalize(void) abort: if (err) { pr_err("Failed to convert KHO state tree: %d\n", err); - kho_abort(); + __kho_abort(); } =20 return err; } =20 -static int kho_out_finalize_get(void *data, u64 *val) +int kho_finalize(void) { - mutex_lock(&kho_out.lock); - *val =3D kho_out.finalized; - mutex_unlock(&kho_out.lock); - - return 0; -} - -static int kho_out_finalize_set(void *data, u64 _val) -{ - int ret =3D 0; - bool val =3D !!_val; - - mutex_lock(&kho_out.lock); + int ret; =20 - if (val =3D=3D kho_out.finalized) { - if (kho_out.finalized) - ret =3D -EEXIST; - else - ret =3D -ENOENT; - goto unlock; - } + if (!kho_enable) + return -EOPNOTSUPP; =20 - if (val) - ret =3D kho_finalize(); - else - ret =3D kho_abort(); + guard(mutex)(&kho_out.lock); + if (kho_out.finalized) + return -EEXIST; =20 + ret =3D __kho_finalize(); if (ret) - goto unlock; - - kho_out.finalized =3D val; - ret =3D kho_out_update_debugfs_fdt(); - -unlock: - mutex_unlock(&kho_out.lock); - return ret; -} - -DEFINE_DEBUGFS_ATTRIBUTE(fops_kho_out_finalize, 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++) - seq_printf(m, "0x%llx\n", kho_scratch[i].addr); - - return 0; -} -DEFINE_SHOW_ATTRIBUTE(scratch_phys); + return ret; =20 -static int scratch_len_show(struct seq_file *m, void *v) -{ - for (int i =3D 0; i < kho_scratch_cnt; i++) - seq_printf(m, "0x%llx\n", kho_scratch[i].size); + kho_out.finalized =3D true; =20 - return 0; + return kho_debugfs_fdt_add(&kho_out.dbg, "fdt", + page_to_virt(kho_out.ser.fdt), true); } -DEFINE_SHOW_ATTRIBUTE(scratch_len); =20 -static __init int kho_out_debugfs_init(void) +bool kho_finalized(void) { - struct dentry *dir, *f, *sub_fdt_dir; - - dir =3D debugfs_create_dir("out", debugfs_root); - if (IS_ERR(dir)) - return -ENOMEM; - - sub_fdt_dir =3D debugfs_create_dir("sub_fdts", dir); - if (IS_ERR(sub_fdt_dir)) - goto err_rmdir; - - f =3D debugfs_create_file("scratch_phys", 0400, dir, NULL, - &scratch_phys_fops); - if (IS_ERR(f)) - goto err_rmdir; - - f =3D debugfs_create_file("scratch_len", 0400, dir, NULL, - &scratch_len_fops); - if (IS_ERR(f)) - goto err_rmdir; - - f =3D debugfs_create_file("finalize", 0600, dir, NULL, - &fops_kho_out_finalize); - if (IS_ERR(f)) - goto err_rmdir; - - kho_out.dir =3D dir; - kho_out.ser.sub_fdt_dir =3D sub_fdt_dir; - return 0; - -err_rmdir: - debugfs_remove_recursive(dir); - return -ENOENT; + guard(mutex)(&kho_out.lock); + return kho_out.finalized; } =20 struct kho_in { - struct dentry *dir; phys_addr_t fdt_phys; phys_addr_t scratch_phys; - struct list_head fdt_list; + struct kho_debugfs dbg; }; =20 static struct kho_in kho_in =3D { - .fdt_list =3D LIST_HEAD_INIT(kho_in.fdt_list), }; =20 static const void *kho_get_fdt(void) @@ -1338,56 +1228,6 @@ int kho_retrieve_subtree(const char *name, phys_addr= _t *phys) } EXPORT_SYMBOL_GPL(kho_retrieve_subtree); =20 -/* Handling for debugfs/kho/in */ - -static __init int kho_in_debugfs_init(const void *fdt) -{ - struct dentry *sub_fdt_dir; - int err, child; - - kho_in.dir =3D debugfs_create_dir("in", debugfs_root); - if (IS_ERR(kho_in.dir)) - return PTR_ERR(kho_in.dir); - - sub_fdt_dir =3D debugfs_create_dir("sub_fdts", kho_in.dir); - if (IS_ERR(sub_fdt_dir)) { - err =3D PTR_ERR(sub_fdt_dir); - goto err_rmdir; - } - - err =3D kho_debugfs_fdt_add(&kho_in.fdt_list, kho_in.dir, "fdt", fdt); - if (err) - goto err_rmdir; - - fdt_for_each_subnode(child, fdt, 0) { - int len =3D 0; - const char *name =3D fdt_get_name(fdt, child, NULL); - const u64 *fdt_phys; - - fdt_phys =3D fdt_getprop(fdt, child, "fdt", &len); - if (!fdt_phys) - continue; - if (len !=3D sizeof(*fdt_phys)) { - pr_warn("node `%s`'s prop `fdt` has invalid length: %d\n", - name, len); - continue; - } - err =3D kho_debugfs_fdt_add(&kho_in.fdt_list, sub_fdt_dir, name, - phys_to_virt(*fdt_phys)); - if (err) { - pr_warn("failed to add fdt `%s` to debugfs: %d\n", name, - err); - continue; - } - } - - return 0; - -err_rmdir: - debugfs_remove_recursive(kho_in.dir); - return err; -} - static __init int kho_init(void) { int err =3D 0; @@ -1402,27 +1242,16 @@ static __init int kho_init(void) goto err_free_scratch; } =20 - debugfs_root =3D debugfs_create_dir("kho", NULL); - if (IS_ERR(debugfs_root)) { - err =3D -ENOENT; + err =3D kho_debugfs_init(); + if (err) goto err_free_fdt; - } =20 - err =3D kho_out_debugfs_init(); + err =3D kho_out_debugfs_init(&kho_out.dbg); if (err) goto err_free_fdt; =20 if (fdt) { - err =3D kho_in_debugfs_init(fdt); - /* - * Failure to create /sys/kernel/debug/kho/in does not prevent - * reviving state from KHO and setting up KHO for the next - * kexec. - */ - if (err) - pr_err("failed exposing handover FDT in debugfs: %d\n", - err); - + kho_in_debugfs_init(&kho_in.dbg, fdt); return 0; } =20 diff --git a/kernel/kexec_handover_debugfs.c b/kernel/kexec_handover_debugf= s.c new file mode 100644 index 000000000000..a91b279f1b23 --- /dev/null +++ b/kernel/kexec_handover_debugfs.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * kexec_handover_debugfs.c - kexec handover debugfs interfaces + * Copyright (C) 2023 Alexander Graf + * Copyright (C) 2025 Microsoft Corporation, Mike Rapoport + * Copyright (C) 2025 Google LLC, Changyuan Lyu + * Copyright (C) 2025 Google LLC, Pasha Tatashin + */ + +#define pr_fmt(fmt) "KHO: " fmt + +#include +#include +#include +#include +#include "kexec_handover_internal.h" + +static struct dentry *debugfs_root; + +struct fdt_debugfs { + struct list_head list; + struct debugfs_blob_wrapper wrapper; + struct dentry *file; +}; + +static int __kho_debugfs_fdt_add(struct list_head *list, struct dentry *di= r, + const char *name, const void *fdt) +{ + struct fdt_debugfs *f; + struct dentry *file; + + f =3D kmalloc(sizeof(*f), GFP_KERNEL); + if (!f) + return -ENOMEM; + + f->wrapper.data =3D (void *)fdt; + f->wrapper.size =3D fdt_totalsize(fdt); + + file =3D debugfs_create_blob(name, 0400, dir, &f->wrapper); + if (IS_ERR(file)) { + kfree(f); + return PTR_ERR(file); + } + + f->file =3D file; + list_add(&f->list, list); + + return 0; +} + +int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name, + const void *fdt, bool root) +{ + struct dentry *dir; + + if (root) + dir =3D dbg->dir; + else + dir =3D dbg->sub_fdt_dir; + + return __kho_debugfs_fdt_add(&dbg->fdt_list, dir, name, fdt); +} + +void kho_debugfs_cleanup(struct kho_debugfs *dbg) +{ + struct fdt_debugfs *ff, *tmp; + + list_for_each_entry_safe(ff, tmp, &dbg->fdt_list, list) { + debugfs_remove(ff->file); + list_del(&ff->list); + kfree(ff); + } +} + +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 kho_abort(); +} + +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++) + seq_printf(m, "0x%llx\n", kho_scratch[i].addr); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(scratch_phys); + +static int scratch_len_show(struct seq_file *m, void *v) +{ + for (int i =3D 0; i < kho_scratch_cnt; i++) + seq_printf(m, "0x%llx\n", kho_scratch[i].size); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(scratch_len); + +__init void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt) +{ + struct dentry *dir, *sub_fdt_dir; + int err, child; + + INIT_LIST_HEAD(&dbg->fdt_list); + + dir =3D debugfs_create_dir("in", debugfs_root); + if (IS_ERR(dir)) { + err =3D PTR_ERR(dir); + goto err_out; + } + + sub_fdt_dir =3D debugfs_create_dir("sub_fdts", dir); + if (IS_ERR(sub_fdt_dir)) { + err =3D PTR_ERR(sub_fdt_dir); + goto err_rmdir; + } + + err =3D __kho_debugfs_fdt_add(&dbg->fdt_list, dir, "fdt", fdt); + if (err) + goto err_rmdir; + + fdt_for_each_subnode(child, fdt, 0) { + int len =3D 0; + const char *name =3D fdt_get_name(fdt, child, NULL); + const u64 *fdt_phys; + + fdt_phys =3D fdt_getprop(fdt, child, "fdt", &len); + if (!fdt_phys) + continue; + if (len !=3D sizeof(*fdt_phys)) { + pr_warn("node %s prop fdt has invalid length: %d\n", + name, len); + continue; + } + err =3D __kho_debugfs_fdt_add(&dbg->fdt_list, sub_fdt_dir, name, + phys_to_virt(*fdt_phys)); + if (err) { + pr_warn("failed to add fdt %s to debugfs: %d\n", name, + err); + continue; + } + } + + dbg->dir =3D dir; + dbg->sub_fdt_dir =3D sub_fdt_dir; + + return; +err_rmdir: + debugfs_remove_recursive(dir); +err_out: + /* + * Failure to create /sys/kernel/debug/kho/in does not prevent + * reviving state from KHO and setting up KHO for the next + * kexec. + */ + if (err) + pr_err("failed exposing handover FDT in debugfs: %d\n", err); +} + +__init int kho_out_debugfs_init(struct kho_debugfs *dbg) +{ + struct dentry *dir, *f, *sub_fdt_dir; + + INIT_LIST_HEAD(&dbg->fdt_list); + + dir =3D debugfs_create_dir("out", debugfs_root); + if (IS_ERR(dir)) + return -ENOMEM; + + sub_fdt_dir =3D debugfs_create_dir("sub_fdts", dir); + if (IS_ERR(sub_fdt_dir)) + goto err_rmdir; + + f =3D debugfs_create_file("scratch_phys", 0400, dir, NULL, + &scratch_phys_fops); + if (IS_ERR(f)) + goto err_rmdir; + + f =3D debugfs_create_file("scratch_len", 0400, dir, NULL, + &scratch_len_fops); + if (IS_ERR(f)) + goto err_rmdir; + + 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; + +err_rmdir: + debugfs_remove_recursive(dir); + return -ENOENT; +} + +__init int kho_debugfs_init(void) +{ + debugfs_root =3D debugfs_create_dir("kho", NULL); + if (IS_ERR(debugfs_root)) + return -ENOENT; + return 0; +} diff --git a/kernel/kexec_handover_internal.h b/kernel/kexec_handover_inter= nal.h index 05e9720ba7b9..217b8b25a542 100644 --- a/kernel/kexec_handover_internal.h +++ b/kernel/kexec_handover_internal.h @@ -2,8 +2,47 @@ #ifndef LINUX_KEXEC_HANDOVER_INTERNAL_H #define LINUX_KEXEC_HANDOVER_INTERNAL_H =20 +#include +#include #include =20 +#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS +#include + +struct kho_debugfs { + struct dentry *dir; + struct dentry *sub_fdt_dir; + struct list_head fdt_list; +}; + +#else +struct kho_debugfs {}; +#endif + +extern struct kho_scratch *kho_scratch; +extern unsigned int kho_scratch_cnt; + +bool kho_finalized(void); +int kho_finalize(void); +int kho_abort(void); + +#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS +int kho_debugfs_init(void); +void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt); +int kho_out_debugfs_init(struct kho_debugfs *dbg); +int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name, + const void *fdt, bool root); +void kho_debugfs_cleanup(struct kho_debugfs *dbg); +#else +static inline int kho_debugfs_init(void) { return 0; } +static inline void kho_in_debugfs_init(struct kho_debugfs *dbg, + const void *fdt) { } +static inline int kho_out_debugfs_init(struct kho_debugfs *dbg) { return 0= ; } +static inline int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char = *name, + const void *fdt, bool root) { return 0; } +static inline void kho_debugfs_cleanup(struct kho_debugfs *dbg) {} +#endif /* CONFIG_KEXEC_HANDOVER_DEBUGFS */ + #ifdef CONFIG_KEXEC_HANDOVER_DEBUG bool kho_scratch_overlap(phys_addr_t phys, size_t size); #else diff --git a/tools/testing/selftests/kho/vmtest.sh b/tools/testing/selftest= s/kho/vmtest.sh index 3f6c17166846..49fdac8e8b15 100755 --- a/tools/testing/selftests/kho/vmtest.sh +++ b/tools/testing/selftests/kho/vmtest.sh @@ -59,6 +59,7 @@ function build_kernel() { tee "$kconfig" > "$kho_config" <; Sat, 1 Nov 2025 14:23:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007018; cv=none; b=qCJ0f41uZaVcgkJJ28T0T6pWMWfKMPwPgGRCoXgTqmQljZpvE37MdGgQkC3LgBEZMnJ8CP9d9t56hz3WHWD1jFZPok5Mqi8DlT0jcsJO7jZxh+b7jdknKQmu9OwfsTXtU+eCi3liMV0BIiWFevIsnPVPqGQAcU+zxusEcip8PRY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007018; c=relaxed/simple; bh=qTKDkER9kB/1QOvwce4NNa+65Z/v7JDN8dt5jqZEKhA=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=opVE8CkInsvB9Zw3gOpRW/Mex4zKCB7r41PL/M12qZc33YsmQJFuj9pw0XJc5i3r4BTnjnwrUqBoaXXpdlg5eQiUT2QJUJd6o5Jgku4/dWlakyC7JGExXaY9HeOx0PnU5KjEwbS2NgUjE2caeNnuF3JF/QEsD49lkPacvKwOGgM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=cG2+Fuec; arc=none smtp.client-ip=209.85.221.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="cG2+Fuec" Received: by mail-vk1-f173.google.com with SMTP id 71dfb90a1353d-557c5109d90so2290172e0c.0 for ; Sat, 01 Nov 2025 07:23:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007015; x=1762611815; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=gHmXVaTw3+GhHsgA6m5g0ajWi+g0HpuNbJcxgt5WdAQ=; b=cG2+FuecA5Kfr3gesTflswvFGc+z48TQzJUjSnCGats5/C5ItFS1tqe5GBV64YedHS 1LqwuCBMSFY5SRFV4giDu2qmQxKtSoJllEXRGhhfwr3ot6x3BJcBPOgYDTgWZDBx7y7p ojSNXznZHSbvZEG6IweZslxKGucLMO6/n9pR5jKWgCcvM8HN+IC35GtLOmO8EKYlCXOX Alt3fqZUkY2nF0qxmA3gWe9acPHGu13AxjNzwYgI865VU+KMbTAb76bK1yd2IOX3A4Yb lFl1cz670lDv4EppV1b8VQOp5lCNHQKtgYdDRxJHRZCs94eV5v18+X0V0KPLyWef529s JCPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007015; x=1762611815; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gHmXVaTw3+GhHsgA6m5g0ajWi+g0HpuNbJcxgt5WdAQ=; b=guuBmPSbwIiRgJouwk+EvEmZ6NXSlS6BDVgUS9TtIDeZS2Omt8vPDrbFCXvPdXtbPl DHwpR5sqw3pjbXg5bSlEIUiMsgt/81JQgt21aAxo2rrKA4H+7h+FYyBLCqxmykqXB0Pk kiCYH9jV1wbnHcqC/KgSvNOHY2g9fkv5jjLijcRBkTlTjd+FxgkDG8ACSJe4iWmpHMfZ 5Xc5ZuCLTUilx5lbQKmy74CVZQnxyHz+Q2tOljB7nZFh/h1VKqQ6t+T4fJQ2opCPZB07 RB2zuB+626/Pv+ZlA59d3eMiZm7GjQs8sBFm7g3OxJ0lgdl179KSeoewuPNPWT8U3SBl POhw== X-Forwarded-Encrypted: i=1; AJvYcCVGzrs8EbJbpZTZxHdUdAU5ZR+2pTTB9HIfOeDxScwuqe9c3Aaina2OdqEaDvn0Wj/rVnp1I32hY2hCFwc=@vger.kernel.org X-Gm-Message-State: AOJu0Yz1ONLPbr7adg1M/bf8zlAWA5ORPvCBmK1nXFbcTO/EhPTcl2fw nQWPVrBvhrpjxaoPK5OJnNicUPfLJM7g8JamzQ4PD0UGxoAa469l0czn7IA8aGAlAug= X-Gm-Gg: ASbGnctnLQsQCcIClUe5t9dTni3hbY5UjRtUCtKw8exFnDuLPm/zUFLyvyGRP4N0dmN j5QX+i2I9sOu52QTAbJULU31iwePQ3wEmdXNNii8qrl6bXS2Vuyu+2hA2ah7EWD0UKagVTAO+8r e1MvSeEQfvC3V/nanhmo3eiSdKgOEnLtPFIE/EiU7+zRXOmwaBirZyIGqQG4Ng6CovYmYsxrTak BDNyo7B2cs0+I/OWOTLEe+32R2P48559XAJR3sMdE8w9kBTch6NGaWMyO0gHJ9sBbjjUoIof03b pewWqnoYSYC9+uwlFHeBISps+tjGLThAJYMWjm7jA1sBTflKkSbDLFzRmWk6842an3PZUcFT4C0 habR2YyKHRL4KEwzfvT6OJ1TBSYn05XiV9Oj584NUTxKMlKkSEK0S1XJGIaxfhYDbU/mahssI1e ze8C9zI1szS4+OXbJBppXjjrs2P3GbFy2PsVqOWZ52oXv7atP0KBnM4sjaJRONDN4XzXnoNEk= X-Google-Smtp-Source: AGHT+IG+jHUlmJU3ah4e9d9PL0VI3kvkYYEth54bO69x8ug2ZcNH/fpmRNUgVQ/FWLQqqMm7iew6cQ== X-Received: by 2002:a05:6122:62f1:b0:556:e951:b554 with SMTP id 71dfb90a1353d-5593e3f77aemr2725706e0c.10.1762007014629; Sat, 01 Nov 2025 07:23:34 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:34 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 2/9] kho: drop notifiers Date: Sat, 1 Nov 2025 10:23:18 -0400 Message-ID: <20251101142325.1326536-3-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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: "Mike Rapoport (Microsoft)" The KHO framework uses a notifier chain as the mechanism for clients to participate in the finalization process. While this works for a single, central state machine, it is too restrictive for kernel-internal components like pstore/reserve_mem or IMA. These components need a simpler, direct way to register their state for preservation (e.g., during their initcall) without being part of a complex, shutdown-time notifier sequence. The notifier model forces all participants into a single finalization flow and makes direct preservation from an arbitrary context difficult. This patch refactors the client participation model by removing the notifier chain and introducing a direct API for managing FDT subtrees. The core kho_finalize() and kho_abort() state machine remains, but clients now register their data with KHO beforehand. Signed-off-by: Mike Rapoport (Microsoft) Co-developed-by: Pasha Tatashin Signed-off-by: Pasha Tatashin --- include/linux/kexec_handover.h | 28 +----- kernel/kexec_handover.c | 166 +++++++++++++++++-------------- kernel/kexec_handover_debugfs.c | 17 ++-- kernel/kexec_handover_internal.h | 5 +- lib/test_kho.c | 35 +------ mm/memblock.c | 62 +++--------- 6 files changed, 125 insertions(+), 188 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 25042c1d8d54..0d860d793b66 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -10,14 +10,7 @@ struct kho_scratch { phys_addr_t size; }; =20 -/* KHO Notifier index */ -enum kho_event { - KEXEC_KHO_FINALIZE =3D 0, - KEXEC_KHO_ABORT =3D 1, -}; - struct folio; -struct notifier_block; struct page; =20 #define DECLARE_KHOSER_PTR(name, type) \ @@ -37,8 +30,6 @@ struct page; (typeof((s).ptr))((s).phys ? phys_to_virt((s).phys) : NULL); \ }) =20 -struct kho_serialization; - struct kho_vmalloc_chunk; struct kho_vmalloc { DECLARE_KHOSER_PTR(first, struct kho_vmalloc_chunk *); @@ -57,12 +48,10 @@ int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc = *preservation); struct folio *kho_restore_folio(phys_addr_t phys); struct page *kho_restore_pages(phys_addr_t phys, unsigned int nr_pages); void *kho_restore_vmalloc(const struct kho_vmalloc *preservation); -int kho_add_subtree(struct kho_serialization *ser, const char *name, void = *fdt); +int kho_add_subtree(const char *name, void *fdt); +void kho_remove_subtree(void *fdt); int kho_retrieve_subtree(const char *name, phys_addr_t *phys); =20 -int register_kho_notifier(struct notifier_block *nb); -int unregister_kho_notifier(struct notifier_block *nb); - void kho_memory_init(void); =20 void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_p= hys, @@ -110,23 +99,16 @@ static inline void *kho_restore_vmalloc(const struct k= ho_vmalloc *preservation) return NULL; } =20 -static inline int kho_add_subtree(struct kho_serialization *ser, - const char *name, void *fdt) +static inline int kho_add_subtree(const char *name, void *fdt) { return -EOPNOTSUPP; } =20 -static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys) +static inline void kho_remove_subtree(void *fdt) { - return -EOPNOTSUPP; } =20 -static inline int register_kho_notifier(struct notifier_block *nb) -{ - return -EOPNOTSUPP; -} - -static inline int unregister_kho_notifier(struct notifier_block *nb) +static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys) { return -EOPNOTSUPP; } diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index da071277d85e..82137eba1474 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include =20 @@ -103,29 +102,34 @@ struct kho_mem_track { =20 struct khoser_mem_chunk; =20 -struct kho_serialization { - struct page *fdt; - struct kho_mem_track track; - /* First chunk of serialized preserved memory map */ - struct khoser_mem_chunk *preserved_mem_map; +struct kho_sub_fdt { + struct list_head l; + const char *name; + void *fdt; }; =20 struct kho_out { - struct blocking_notifier_head chain_head; - struct mutex lock; /* protects KHO FDT finalization */ - struct kho_serialization ser; + void *fdt; bool finalized; + struct mutex lock; /* protects KHO FDT finalization */ + + struct list_head sub_fdts; + struct mutex fdts_lock; + + struct kho_mem_track track; + /* First chunk of serialized preserved memory map */ + struct khoser_mem_chunk *preserved_mem_map; + struct kho_debugfs dbg; }; =20 static struct kho_out kho_out =3D { - .chain_head =3D BLOCKING_NOTIFIER_INIT(kho_out.chain_head), .lock =3D __MUTEX_INITIALIZER(kho_out.lock), - .ser =3D { - .track =3D { - .orders =3D XARRAY_INIT(kho_out.ser.track.orders, 0), - }, + .track =3D { + .orders =3D XARRAY_INIT(kho_out.track.orders, 0), }, + .sub_fdts =3D LIST_HEAD_INIT(kho_out.sub_fdts), + .fdts_lock =3D __MUTEX_INITIALIZER(kho_out.fdts_lock), .finalized =3D false, }; =20 @@ -369,7 +373,7 @@ static void kho_mem_ser_free(struct khoser_mem_chunk *f= irst_chunk) } } =20 -static int kho_mem_serialize(struct kho_serialization *ser) +static int kho_mem_serialize(struct kho_out *kho_out) { struct khoser_mem_chunk *first_chunk =3D NULL; struct khoser_mem_chunk *chunk =3D NULL; @@ -377,7 +381,7 @@ static int kho_mem_serialize(struct kho_serialization *= ser) unsigned long order; int err =3D -ENOMEM; =20 - xa_for_each(&ser->track.orders, order, physxa) { + xa_for_each(&kho_out->track.orders, order, physxa) { struct kho_mem_phys_bits *bits; unsigned long phys; =20 @@ -409,7 +413,7 @@ static int kho_mem_serialize(struct kho_serialization *= ser) } } =20 - ser->preserved_mem_map =3D first_chunk; + kho_out->preserved_mem_map =3D first_chunk; =20 return 0; =20 @@ -670,7 +674,6 @@ static void __init kho_reserve_scratch(void) =20 /** * kho_add_subtree - record the physical address of a sub FDT in KHO root = tree. - * @ser: serialization control object passed by KHO notifiers. * @name: name of the sub tree. * @fdt: the sub tree blob. * @@ -684,34 +687,41 @@ static void __init kho_reserve_scratch(void) * * Return: 0 on success, error code on failure */ -int kho_add_subtree(struct kho_serialization *ser, const char *name, void = *fdt) +int kho_add_subtree(const char *name, void *fdt) { - int err =3D 0; - u64 phys =3D (u64)virt_to_phys(fdt); - void *root =3D page_to_virt(ser->fdt); + struct kho_sub_fdt *sub_fdt; =20 - err |=3D fdt_begin_node(root, name); - err |=3D fdt_property(root, PROP_SUB_FDT, &phys, sizeof(phys)); - err |=3D fdt_end_node(root); + sub_fdt =3D kmalloc(sizeof(*sub_fdt), GFP_KERNEL); + if (!sub_fdt) + return -ENOMEM; =20 - if (err) - return err; + INIT_LIST_HEAD(&sub_fdt->l); + sub_fdt->name =3D name; + sub_fdt->fdt =3D fdt; =20 - return kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false); -} -EXPORT_SYMBOL_GPL(kho_add_subtree); + guard(mutex)(&kho_out.fdts_lock); + list_add_tail(&sub_fdt->l, &kho_out.sub_fdts); + WARN_ON_ONCE(kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false)); =20 -int register_kho_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&kho_out.chain_head, nb); + return 0; } -EXPORT_SYMBOL_GPL(register_kho_notifier); +EXPORT_SYMBOL_GPL(kho_add_subtree); =20 -int unregister_kho_notifier(struct notifier_block *nb) +void kho_remove_subtree(void *fdt) { - return blocking_notifier_chain_unregister(&kho_out.chain_head, nb); + struct kho_sub_fdt *sub_fdt; + + guard(mutex)(&kho_out.fdts_lock); + list_for_each_entry(sub_fdt, &kho_out.sub_fdts, l) { + if (sub_fdt->fdt =3D=3D fdt) { + list_del(&sub_fdt->l); + kfree(sub_fdt); + kho_debugfs_fdt_remove(&kho_out.dbg, fdt); + break; + } + } } -EXPORT_SYMBOL_GPL(unregister_kho_notifier); +EXPORT_SYMBOL_GPL(kho_remove_subtree); =20 /** * kho_preserve_folio - preserve a folio across kexec. @@ -726,7 +736,7 @@ int kho_preserve_folio(struct folio *folio) { const unsigned long pfn =3D folio_pfn(folio); const unsigned int order =3D folio_order(folio); - struct kho_mem_track *track =3D &kho_out.ser.track; + struct kho_mem_track *track =3D &kho_out.track; =20 if (WARN_ON(kho_scratch_overlap(pfn << PAGE_SHIFT, PAGE_SIZE << order))) return -EINVAL; @@ -747,7 +757,7 @@ EXPORT_SYMBOL_GPL(kho_preserve_folio); */ int kho_preserve_pages(struct page *page, unsigned int nr_pages) { - struct kho_mem_track *track =3D &kho_out.ser.track; + struct kho_mem_track *track =3D &kho_out.track; const unsigned long start_pfn =3D page_to_pfn(page); const unsigned long end_pfn =3D start_pfn + nr_pages; unsigned long pfn =3D start_pfn; @@ -848,7 +858,7 @@ static struct kho_vmalloc_chunk *new_vmalloc_chunk(stru= ct kho_vmalloc_chunk *cur =20 static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk) { - struct kho_mem_track *track =3D &kho_out.ser.track; + struct kho_mem_track *track =3D &kho_out.track; unsigned long pfn =3D PHYS_PFN(virt_to_phys(chunk)); =20 __kho_unpreserve(track, pfn, pfn + 1); @@ -1030,11 +1040,11 @@ EXPORT_SYMBOL_GPL(kho_restore_vmalloc); =20 static int __kho_abort(void) { - int err; + int err =3D 0; unsigned long order; struct kho_mem_phys *physxa; =20 - xa_for_each(&kho_out.ser.track.orders, order, physxa) { + xa_for_each(&kho_out.track.orders, order, physxa) { struct kho_mem_phys_bits *bits; unsigned long phys; =20 @@ -1044,17 +1054,13 @@ static int __kho_abort(void) xa_destroy(&physxa->phys_bits); kfree(physxa); } - xa_destroy(&kho_out.ser.track.orders); + xa_destroy(&kho_out.track.orders); =20 - if (kho_out.ser.preserved_mem_map) { - kho_mem_ser_free(kho_out.ser.preserved_mem_map); - kho_out.ser.preserved_mem_map =3D NULL; + if (kho_out.preserved_mem_map) { + kho_mem_ser_free(kho_out.preserved_mem_map); + kho_out.preserved_mem_map =3D NULL; } =20 - err =3D blocking_notifier_call_chain(&kho_out.chain_head, KEXEC_KHO_ABORT, - NULL); - err =3D notifier_to_errno(err); - if (err) pr_err("Failed to abort KHO finalization: %d\n", err); =20 @@ -1077,7 +1083,8 @@ int kho_abort(void) return ret; =20 kho_out.finalized =3D false; - kho_debugfs_cleanup(&kho_out.dbg); + + kho_debugfs_fdt_remove(&kho_out.dbg, kho_out.fdt); =20 return 0; } @@ -1086,41 +1093,46 @@ static int __kho_finalize(void) { int err =3D 0; u64 *preserved_mem_map; - void *fdt =3D page_to_virt(kho_out.ser.fdt); + void *root =3D kho_out.fdt; + struct kho_sub_fdt *fdt; =20 - err |=3D fdt_create(fdt, PAGE_SIZE); - err |=3D fdt_finish_reservemap(fdt); - err |=3D fdt_begin_node(fdt, ""); - err |=3D fdt_property_string(fdt, "compatible", KHO_FDT_COMPATIBLE); + err |=3D fdt_create(root, PAGE_SIZE); + err |=3D fdt_finish_reservemap(root); + err |=3D fdt_begin_node(root, ""); + err |=3D fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); /** * Reserve the preserved-memory-map property in the root FDT, so * that all property definitions will precede subnodes created by * KHO callers. */ - err |=3D fdt_property_placeholder(fdt, PROP_PRESERVED_MEMORY_MAP, + err |=3D fdt_property_placeholder(root, PROP_PRESERVED_MEMORY_MAP, sizeof(*preserved_mem_map), (void **)&preserved_mem_map); if (err) goto abort; =20 - err =3D kho_preserve_folio(page_folio(kho_out.ser.fdt)); + err =3D kho_preserve_folio(virt_to_folio(kho_out.fdt)); if (err) goto abort; =20 - err =3D blocking_notifier_call_chain(&kho_out.chain_head, - KEXEC_KHO_FINALIZE, &kho_out.ser); - err =3D notifier_to_errno(err); + err =3D kho_mem_serialize(&kho_out); if (err) goto abort; =20 - err =3D kho_mem_serialize(&kho_out.ser); - if (err) - goto abort; + *preserved_mem_map =3D (u64)virt_to_phys(kho_out.preserved_mem_map); + + mutex_lock(&kho_out.fdts_lock); + list_for_each_entry(fdt, &kho_out.sub_fdts, l) { + phys_addr_t phys =3D virt_to_phys(fdt->fdt); =20 - *preserved_mem_map =3D (u64)virt_to_phys(kho_out.ser.preserved_mem_map); + err |=3D fdt_begin_node(root, fdt->name); + err |=3D fdt_property(root, PROP_SUB_FDT, &phys, sizeof(phys)); + err |=3D fdt_end_node(root); + } + mutex_unlock(&kho_out.fdts_lock); =20 - err |=3D fdt_end_node(fdt); - err |=3D fdt_finish(fdt); + err |=3D fdt_end_node(root); + err |=3D fdt_finish(root); =20 abort: if (err) { @@ -1148,8 +1160,10 @@ int kho_finalize(void) =20 kho_out.finalized =3D true; =20 - return kho_debugfs_fdt_add(&kho_out.dbg, "fdt", - page_to_virt(kho_out.ser.fdt), true); + WARN_ON_ONCE(kho_debugfs_fdt_add(&kho_out.dbg, "fdt", + kho_out.fdt, true)); + + return 0; } =20 bool kho_finalized(void) @@ -1232,15 +1246,17 @@ static __init int kho_init(void) { int err =3D 0; const void *fdt =3D kho_get_fdt(); + struct page *fdt_page; =20 if (!kho_enable) return 0; =20 - kho_out.ser.fdt =3D alloc_page(GFP_KERNEL); - if (!kho_out.ser.fdt) { + fdt_page =3D alloc_page(GFP_KERNEL); + if (!fdt_page) { err =3D -ENOMEM; goto err_free_scratch; } + kho_out.fdt =3D page_to_virt(fdt_page); =20 err =3D kho_debugfs_init(); if (err) @@ -1268,8 +1284,8 @@ static __init int kho_init(void) return 0; =20 err_free_fdt: - put_page(kho_out.ser.fdt); - kho_out.ser.fdt =3D NULL; + put_page(fdt_page); + kho_out.fdt =3D NULL; err_free_scratch: for (int i =3D 0; i < kho_scratch_cnt; i++) { void *start =3D __va(kho_scratch[i].addr); @@ -1280,7 +1296,7 @@ static __init int kho_init(void) kho_enable =3D false; return err; } -late_initcall(kho_init); +fs_initcall(kho_init); =20 static void __init kho_release_scratch(void) { @@ -1416,7 +1432,7 @@ int kho_fill_kimage(struct kimage *image) if (!kho_out.finalized) return 0; =20 - image->kho.fdt =3D page_to_phys(kho_out.ser.fdt); + image->kho.fdt =3D virt_to_phys(kho_out.fdt); =20 scratch_size =3D sizeof(*kho_scratch) * kho_scratch_cnt; scratch =3D (struct kexec_buf){ diff --git a/kernel/kexec_handover_debugfs.c b/kernel/kexec_handover_debugf= s.c index a91b279f1b23..46e9e6c0791f 100644 --- a/kernel/kexec_handover_debugfs.c +++ b/kernel/kexec_handover_debugfs.c @@ -61,14 +61,17 @@ int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const = char *name, return __kho_debugfs_fdt_add(&dbg->fdt_list, dir, name, fdt); } =20 -void kho_debugfs_cleanup(struct kho_debugfs *dbg) +void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, void *fdt) { - struct fdt_debugfs *ff, *tmp; - - list_for_each_entry_safe(ff, tmp, &dbg->fdt_list, list) { - debugfs_remove(ff->file); - list_del(&ff->list); - kfree(ff); + struct fdt_debugfs *ff; + + list_for_each_entry(ff, &dbg->fdt_list, list) { + if (ff->wrapper.data =3D=3D fdt) { + debugfs_remove(ff->file); + list_del(&ff->list); + kfree(ff); + break; + } } } =20 diff --git a/kernel/kexec_handover_internal.h b/kernel/kexec_handover_inter= nal.h index 217b8b25a542..52ed73659fe6 100644 --- a/kernel/kexec_handover_internal.h +++ b/kernel/kexec_handover_internal.h @@ -32,7 +32,7 @@ void kho_in_debugfs_init(struct kho_debugfs *dbg, const v= oid *fdt); int kho_out_debugfs_init(struct kho_debugfs *dbg); int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name, const void *fdt, bool root); -void kho_debugfs_cleanup(struct kho_debugfs *dbg); +void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, void *fdt); #else static inline int kho_debugfs_init(void) { return 0; } static inline void kho_in_debugfs_init(struct kho_debugfs *dbg, @@ -40,7 +40,8 @@ static inline void kho_in_debugfs_init(struct kho_debugfs= *dbg, static inline int kho_out_debugfs_init(struct kho_debugfs *dbg) { return 0= ; } static inline int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char = *name, const void *fdt, bool root) { return 0; } -static inline void kho_debugfs_cleanup(struct kho_debugfs *dbg) {} +static inline void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, + void *fdt) { } #endif /* CONFIG_KEXEC_HANDOVER_DEBUGFS */ =20 #ifdef CONFIG_KEXEC_HANDOVER_DEBUG diff --git a/lib/test_kho.c b/lib/test_kho.c index 60cd899ea745..9f7cfa6ac855 100644 --- a/lib/test_kho.c +++ b/lib/test_kho.c @@ -39,33 +39,6 @@ struct kho_test_state { =20 static struct kho_test_state kho_test_state; =20 -static int kho_test_notifier(struct notifier_block *self, unsigned long cm= d, - void *v) -{ - struct kho_test_state *state =3D &kho_test_state; - struct kho_serialization *ser =3D v; - int err =3D 0; - - switch (cmd) { - case KEXEC_KHO_ABORT: - return NOTIFY_DONE; - case KEXEC_KHO_FINALIZE: - /* Handled below */ - break; - default: - return NOTIFY_BAD; - } - - err |=3D kho_preserve_folio(state->fdt); - err |=3D kho_add_subtree(ser, KHO_TEST_FDT, folio_address(state->fdt)); - - return err ? NOTIFY_BAD : NOTIFY_DONE; -} - -static struct notifier_block kho_test_nb =3D { - .notifier_call =3D kho_test_notifier, -}; - static int kho_test_save_data(struct kho_test_state *state, void *fdt) { phys_addr_t *folios_info __free(kvfree) =3D NULL; @@ -120,6 +93,7 @@ static int kho_test_prepare_fdt(struct kho_test_state *s= tate) =20 fdt =3D folio_address(state->fdt); =20 + err |=3D kho_preserve_folio(state->fdt); err |=3D fdt_create(fdt, fdt_size); err |=3D fdt_finish_reservemap(fdt); =20 @@ -131,6 +105,7 @@ static int kho_test_prepare_fdt(struct kho_test_state *= state) =20 err |=3D fdt_finish(fdt); =20 + err =3D kho_add_subtree(KHO_TEST_FDT, folio_address(state->fdt)); if (err) folio_put(state->fdt); =20 @@ -203,10 +178,6 @@ static int kho_test_save(void) if (err) goto err_free_folios; =20 - err =3D register_kho_notifier(&kho_test_nb); - if (err) - goto err_free_fdt; - return 0; =20 err_free_fdt: @@ -326,7 +297,7 @@ static void kho_test_cleanup(void) =20 static void __exit kho_test_exit(void) { - unregister_kho_notifier(&kho_test_nb); + kho_remove_subtree(folio_address(kho_test_state.fdt)); kho_test_cleanup(); } module_exit(kho_test_exit); diff --git a/mm/memblock.c b/mm/memblock.c index e23e16618e9b..e3bef9b35d63 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -2444,53 +2444,18 @@ int reserve_mem_release_by_name(const char *name) #define MEMBLOCK_KHO_FDT "memblock" #define MEMBLOCK_KHO_NODE_COMPATIBLE "memblock-v1" #define RESERVE_MEM_KHO_NODE_COMPATIBLE "reserve-mem-v1" -static struct page *kho_fdt; - -static int reserve_mem_kho_finalize(struct kho_serialization *ser) -{ - int err =3D 0, i; - - for (i =3D 0; i < reserved_mem_count; i++) { - struct reserve_mem_table *map =3D &reserved_mem_table[i]; - struct page *page =3D phys_to_page(map->start); - unsigned int nr_pages =3D map->size >> PAGE_SHIFT; - - err |=3D kho_preserve_pages(page, nr_pages); - } - - err |=3D kho_preserve_folio(page_folio(kho_fdt)); - err |=3D kho_add_subtree(ser, MEMBLOCK_KHO_FDT, page_to_virt(kho_fdt)); - - return notifier_from_errno(err); -} - -static int reserve_mem_kho_notifier(struct notifier_block *self, - unsigned long cmd, void *v) -{ - switch (cmd) { - case KEXEC_KHO_FINALIZE: - return reserve_mem_kho_finalize((struct kho_serialization *)v); - case KEXEC_KHO_ABORT: - return NOTIFY_DONE; - default: - return NOTIFY_BAD; - } -} - -static struct notifier_block reserve_mem_kho_nb =3D { - .notifier_call =3D reserve_mem_kho_notifier, -}; =20 static int __init prepare_kho_fdt(void) { int err =3D 0, i; + struct page *fdt_page; void *fdt; =20 - kho_fdt =3D alloc_page(GFP_KERNEL); - if (!kho_fdt) + fdt_page =3D alloc_page(GFP_KERNEL); + if (!fdt_page) return -ENOMEM; =20 - fdt =3D page_to_virt(kho_fdt); + fdt =3D page_to_virt(fdt_page); =20 err |=3D fdt_create(fdt, PAGE_SIZE); err |=3D fdt_finish_reservemap(fdt); @@ -2499,7 +2464,10 @@ static int __init prepare_kho_fdt(void) err |=3D fdt_property_string(fdt, "compatible", MEMBLOCK_KHO_NODE_COMPATI= BLE); for (i =3D 0; i < reserved_mem_count; i++) { struct reserve_mem_table *map =3D &reserved_mem_table[i]; + struct page *page =3D phys_to_page(map->start); + unsigned int nr_pages =3D map->size >> PAGE_SHIFT; =20 + err |=3D kho_preserve_pages(page, nr_pages); err |=3D fdt_begin_node(fdt, map->name); err |=3D fdt_property_string(fdt, "compatible", RESERVE_MEM_KHO_NODE_COM= PATIBLE); err |=3D fdt_property(fdt, "start", &map->start, sizeof(map->start)); @@ -2507,13 +2475,16 @@ static int __init prepare_kho_fdt(void) err |=3D fdt_end_node(fdt); } err |=3D fdt_end_node(fdt); - err |=3D fdt_finish(fdt); =20 + err |=3D kho_preserve_folio(page_folio(fdt_page)); + + if (!err) + err =3D kho_add_subtree(MEMBLOCK_KHO_FDT, fdt); + if (err) { pr_err("failed to prepare memblock FDT for KHO: %d\n", err); - put_page(kho_fdt); - kho_fdt =3D NULL; + put_page(fdt_page); } =20 return err; @@ -2529,13 +2500,6 @@ static int __init reserve_mem_init(void) err =3D prepare_kho_fdt(); if (err) return err; - - err =3D register_kho_notifier(&reserve_mem_kho_nb); - if (err) { - put_page(kho_fdt); - kho_fdt =3D NULL; - } - return err; } late_initcall(reserve_mem_init); --=20 2.51.1.930.gacf6e81ea2-goog From nobody Wed Dec 17 21:30:17 2025 Received: from mail-vk1-f180.google.com (mail-vk1-f180.google.com [209.85.221.180]) (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 1BF0F214A9B for ; Sat, 1 Nov 2025 14:23:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007019; cv=none; b=fBGf9FLGJvXJOsSYGKGwlNkRcMpjVPxld18jYM9r58RnK4p9sfkaUL7hPF1NEh/NMayNtyZtscrpCEC+agJ4yvdmI6LxaeX09MmHtPYmWXr3jMohVmJIYua4DtCUz5YM4BDHK2PgXHamFILUuPRSgcupEiulpldKX6P4Vu9RBC4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007019; c=relaxed/simple; bh=QII1LaRqcceKkOy011EbkwamvpGeFjwigCsLK8szwCk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cG0y0nmp/nqBznp9yawwwKJsZZPBXkDdxB5pRgIGz1tS17fraIjAYanYb3BP32eA4+F3MB8/YE4qUFKkhYF8l/BM755kIO1Jy9CI1ygwbLrqV0FijNYRsg8TUtzlHoJecQ8noqnptWVrN3OmRtzoPA90VvADA+R9Sv8Xx/0xdwI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=Vn2y9h4m; arc=none smtp.client-ip=209.85.221.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="Vn2y9h4m" Received: by mail-vk1-f180.google.com with SMTP id 71dfb90a1353d-556a4651cfcso1149793e0c.1 for ; Sat, 01 Nov 2025 07:23:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007017; x=1762611817; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=rpi1Z/2DyRVkKnxEHwYxahLzSNsmpU8z1Poo2lMWpYA=; b=Vn2y9h4mSl7FT0REVdf5xAOC+m1+BLUlz3PgfWB48dtEzjfw0pS8goROfXDrIfKiP/ ynXAjyj4D3KJE1blU3GWAndhPUQ8bKvR/O+KurHHuiQIHXmjZgvPs8Sv0NJLlIfHfDkR HW92lXr0t5tqcuXB9EuL+blXIni3tNW38viWVqgQFdwyWwncXV6SjGhGmqN0ZB0myjKJ vCPcVr9MpFaj9bf9KtiDWOxqkf7h8KQeromsQDzbA22R8ZmSDn5KB4zX9TNqHSNSRrDP 5CvARIrvGHgaXQ+yKsoBM/fEhUHTfH9wqhgJOWFc3RXPYOwd2QS/vTKYi+Si8zbFsTv4 IihA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007017; x=1762611817; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rpi1Z/2DyRVkKnxEHwYxahLzSNsmpU8z1Poo2lMWpYA=; b=sEQwjr7+ftRB9OYSXyV+yLxvi0UE/vQnU9O/lxEhEazlqnZemvcysk5/cdngD8Qnrw 0/trQ6Q/kxgKJ+4/9mk1JHK4Fnegpt+5TDT02G/54y25z+ljX/lIuwVx/DQJDfudiw7t YhtdpuaTjSQHvAAQgSTq688slYu2CFi5IqGZDc9rDewIiHRkr+HrUyU+0SwUIa1aTOek 2Tj/8QdVgq4pYUuHwBLG37RAPwnx3oIbmlxdCqKlZa+17oxOIPOhb6z2VXJuMoyXF+fn NTwjx8oiPh8cO/FF/PYm3BzvxxM/RLG46YJGAAVpoGHMFtycxMq8dU5EmQkc8CzA8Cqc 2c9Q== X-Forwarded-Encrypted: i=1; AJvYcCWbsC2ZJCZQmpHblY5onzTIj3edKJ4JXTWYbmjptSYU7afRz+1EautpRvIK8u8XSNXFi0zzsf1iV4mX0e4=@vger.kernel.org X-Gm-Message-State: AOJu0YzEEf4AuaQFPVg+B23675ee+EK/1CvryFQuZINaTt5i1wnDlxii lUJ794XFetp5WAQg19GssTJrgmBVRZgSzwTIBe4A2kcVA+UQPUb9qaXLi7ZJSQApixU= X-Gm-Gg: ASbGnculHjv06EGuNEDDlNBl6VEnqUnwKf8AE1cvBNeCUy7Wg+/o1eSQ4XVjq4+C1UH vFc2q/LNML3VA8DLvVfE9nbUVAtpufunl6RzxaQZU4dcT50ihbuYw5MymPATvj1dePZtmz+4xEB NVVuyzyaxI4MeHFBfFXe5KksajHXR8H3uMW76lCyJlNJrqRpJYvnGIJ5w0f/PzLPqegKLgrNCTu AZjaMid6NFhuL/BCUZfftp/x+KVFf6YhlEFRn3KaPvnihf3MHjXgV7KPHa+/Vfr6gNLeh9jgQ4x znIbG0hYOxFqkv1U1EhDrQ6aNxFOfd5Cdy6DqatS9dDbTedw2z4qYiDHGGT5yLO3KLfZlmL9LlW HTfq3Cqrne5qkDsgdGX556ci3n4KTb1ppUmAOA59hvK7bT+lumgWMKeqKx2KbSOzocIqlAD5mnI L0gums1n8IqzjJRnzMgwdZVsmOhwLjmy8+iZ+P4o8kfrkNie6/Rz70f1xl9fsjxUma9kPaUGs= X-Google-Smtp-Source: AGHT+IEMu4ntr1ofdj6Iu9NM0kSW7ODJm45DTBvuQgzydqOGurQZxTtybUZHECZqoshEfoiQa/oT9Q== X-Received: by 2002:a05:6122:4591:b0:558:251:f0e8 with SMTP id 71dfb90a1353d-5593e4ef501mr2376540e0c.11.1762007016891; Sat, 01 Nov 2025 07:23:36 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:35 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 3/9] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Date: Sat, 1 Nov 2025 10:23:19 -0400 Message-ID: <20251101142325.1326536-4-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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" Allow users of KHO to cancel the previous preservation by adding the necessary interfaces to unpreserve folio, pages, and vmallocs. Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav Reviewed-by: Mike Rapoport (Microsoft) --- include/linux/kexec_handover.h | 18 ++++++ kernel/kexec_handover.c | 104 ++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 13 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 0d860d793b66..80ece4232617 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -43,8 +43,11 @@ bool kho_is_enabled(void); bool is_kho_boot(void); =20 int kho_preserve_folio(struct folio *folio); +int kho_unpreserve_folio(struct folio *folio); int kho_preserve_pages(struct page *page, unsigned int nr_pages); +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages); int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation); +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation); struct folio *kho_restore_folio(phys_addr_t phys); struct page *kho_restore_pages(phys_addr_t phys, unsigned int nr_pages); void *kho_restore_vmalloc(const struct kho_vmalloc *preservation); @@ -72,17 +75,32 @@ static inline int kho_preserve_folio(struct folio *foli= o) return -EOPNOTSUPP; } =20 +static inline int kho_unpreserve_folio(struct folio *folio) +{ + return -EOPNOTSUPP; +} + static inline int kho_preserve_pages(struct page *page, unsigned int nr_pa= ges) { return -EOPNOTSUPP; } =20 +static inline int kho_unpreserve_pages(struct page *page, unsigned int nr_= pages) +{ + return -EOPNOTSUPP; +} + static inline int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation) { return -EOPNOTSUPP; } =20 +static inline int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) +{ + return -EOPNOTSUPP; +} + static inline struct folio *kho_restore_folio(phys_addr_t phys) { return NULL; diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index 82137eba1474..c514b300ebe6 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -157,26 +157,33 @@ static void *xa_load_or_alloc(struct xarray *xa, unsi= gned long index) return no_free_ptr(elm); } =20 -static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pf= n, - unsigned long end_pfn) +static void __kho_unpreserve_order(struct kho_mem_track *track, unsigned l= ong pfn, + unsigned int order) { struct kho_mem_phys_bits *bits; struct kho_mem_phys *physxa; + const unsigned long pfn_high =3D pfn >> order; =20 - while (pfn < end_pfn) { - const unsigned int order =3D - min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); - const unsigned long pfn_high =3D pfn >> order; + physxa =3D xa_load(&track->orders, order); + if (!physxa) + return; =20 - physxa =3D xa_load(&track->orders, order); - if (!physxa) - continue; + bits =3D xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); + if (!bits) + return; =20 - bits =3D xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); - if (!bits) - continue; + clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); +} + +static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pf= n, + unsigned long end_pfn) +{ + unsigned int order; + + while (pfn < end_pfn) { + order =3D min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); =20 - clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); + __kho_unpreserve_order(track, pfn, order); =20 pfn +=3D 1 << order; } @@ -745,6 +752,30 @@ int kho_preserve_folio(struct folio *folio) } EXPORT_SYMBOL_GPL(kho_preserve_folio); =20 +/** + * kho_unpreserve_folio - unpreserve a folio. + * @folio: folio to unpreserve. + * + * Instructs KHO to unpreserve a folio that was preserved by + * kho_preserve_folio() before. The provided @folio (pfn and order) + * must exactly match a previously preserved folio. + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_folio(struct folio *folio) +{ + const unsigned long pfn =3D folio_pfn(folio); + const unsigned int order =3D folio_order(folio); + struct kho_mem_track *track =3D &kho_out.track; + + if (kho_out.finalized) + return -EBUSY; + + __kho_unpreserve_order(track, pfn, order); + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_folio); + /** * kho_preserve_pages - preserve contiguous pages across kexec * @page: first page in the list. @@ -789,6 +820,33 @@ int kho_preserve_pages(struct page *page, unsigned int= nr_pages) } EXPORT_SYMBOL_GPL(kho_preserve_pages); =20 +/** + * kho_unpreserve_pages - unpreserve contiguous pages. + * @page: first page in the list. + * @nr_pages: number of pages. + * + * Instructs KHO to unpreserve @nr_pages contiguous pages starting from @p= age. + * This must be called with the same @page and @nr_pages as the correspond= ing + * kho_preserve_pages() call. Unpreserving arbitrary sub-ranges of larger + * preserved blocks is not supported. + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) +{ + struct kho_mem_track *track =3D &kho_out.track; + const unsigned long start_pfn =3D page_to_pfn(page); + const unsigned long end_pfn =3D start_pfn + nr_pages; + + if (kho_out.finalized) + return -EBUSY; + + __kho_unpreserve(track, start_pfn, end_pfn); + + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_pages); + struct kho_vmalloc_hdr { DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *); }; @@ -949,6 +1007,26 @@ int kho_preserve_vmalloc(void *ptr, struct kho_vmallo= c *preservation) } EXPORT_SYMBOL_GPL(kho_preserve_vmalloc); =20 +/** + * kho_unpreserve_vmalloc - unpreserve memory allocated with vmalloc() + * @preservation: preservation metadata returned by kho_preserve_vmalloc() + * + * Instructs KHO to unpreserve the area in vmalloc address space that was + * previously preserved with kho_preserve_vmalloc(). + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) +{ + if (kho_out.finalized) + return -EBUSY; + + kho_vmalloc_free_chunks(preservation); + + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_vmalloc); + /** * kho_restore_vmalloc - recreates and populates an area in vmalloc address * space from the preserved memory. --=20 2.51.1.930.gacf6e81ea2-goog From nobody Wed Dec 17 21:30:17 2025 Received: from mail-ua1-f53.google.com (mail-ua1-f53.google.com [209.85.222.53]) (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 58DD72F8BFF for ; Sat, 1 Nov 2025 14:23:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007023; cv=none; b=pXggljc8PHRl2/p6MFm3WmDiaI5mXXH4Hg8LzId52jmci5W/M8tZz6xik6bkGhxiugtg4P+Zip032WZMK95mu9o94bmy2qu20XjIeslyWOCxmp0fqrIV1q5vxmo2FsBdrkBvJnTWzbdP3nvMgtf2zjpwgrtDoGWHrLGW/IdmlF4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007023; c=relaxed/simple; bh=jB2u78ATcqK9LLqZZ+Q3rTKqdWaeTrOa+pQpqVZpFJA=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YfVb2QuWF2S9UHk8XD8aBvdHGFQEQfYTQyA3mjwMgl5HhIN7nUK3ZJxjyZOAecNlLmSxvkNaoLEr4Ra6/OTV7w19pGk1JIxqzbocuHF6oacSZ0ds63GB7GZydf5bZYU/DJWzj9zUBDGAYjInKg29aeGCljbHf2Az47adsqLXLZU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=b+JMHsP1; arc=none smtp.client-ip=209.85.222.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="b+JMHsP1" Received: by mail-ua1-f53.google.com with SMTP id a1e0cc1a2514c-89018ea5625so1504116241.0 for ; Sat, 01 Nov 2025 07:23:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007019; x=1762611819; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=1DCkHyYopvb0wF2qt5OuiBAkk+v7Kgo7WmWoUc1PDLE=; b=b+JMHsP1GZLHHDMivTmJN6GNkVuAnG9CRYQROZhNZqaryMcvcAobPVP9x11mJ3FPsm v2bjyOnroQUtxY5OXPbIMgEOsIPNP62TzinYe0uOhtVF3uHRWp6ZdoXV2e8H4A64YK/Y TEdH2py8+CeFXSrUM3mHD4xr6j/EAezkblxkCTf1Io9KS+0CiSRRl7HdrYNxerpAGDYC DEPiAYD2ZPTnaY2W0eCqxSvFyWMdrnojwUmw/WEdb+kK9BM9+npYdt28iRoySKi/x7se oSHrQq6rN0k1Q1EiIvf9icIZ8itvzoNRI93xhV7GCFE6ujPiv/bep7Vbp2/sq3MZGE7n 8OZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007019; x=1762611819; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1DCkHyYopvb0wF2qt5OuiBAkk+v7Kgo7WmWoUc1PDLE=; b=JtXYmhttBhffXlNGnUeyRqcqFaZe5HegHYjPMHgtNVCVGKmpJS1Pc8MouE4zNggSF6 aK/EKQbpcqp4yBfKgJvdIihJd20Mc1pw8Zz72ENBkdGQJJeibn5SJixC8qBcqKmynwaZ xJkQgonHkEHILUp/0yeUskFtqvK3VQTUP+mrYfzZo+XbVL8AoYVI9OtzFMVkPxMzSVzn /iGqCKVnBccwIJ629gQHErWfYA7idCv+sw18AsUCPmLsYAN2S25jUSrbRHADEEHihbYJ J9c31zr6V0Z57nFbnPyfCZhITQnmZONjL0V/xaBGaxOmnkSzmpXeErVJC1X1YAhoVS61 CJRQ== X-Forwarded-Encrypted: i=1; AJvYcCXWXk1Z5GYeGd8L5gW1wveZfjYzOVSLWoFJfUR1ZO8Ciu9CiSd02jeVTzzzn2wRnnc+/VIIBUsjV0PT1rw=@vger.kernel.org X-Gm-Message-State: AOJu0YxEIToowGYUZj/Pw7OksUPPPEtixDZFeADmsTssIIuYZ03DCCDR BKH6yOOLXoN70VLmzfcG5RZxfYWJHucSx0W8Xfl3CpMXMscWGVLnUMXiwcIhMpiSg9A= X-Gm-Gg: ASbGnct71WSIHO3iBQ+wUeEg2uBew+YYqd5SktU3/oUArKu8MG/qftOePvmx/V4ljr6 wW2oqmBXj8XauRLjkrtMul7qqEQZVVJa2qrapkEgkJriFQay14yWo89HrwdupGcpyY5/OMZ1fVQ 85bgiAeLFsRASC5m9O2a0utG/4cwTTYuvhOscPvWIt5LI6QEXQ6dMrxhLmDt4AdxZNRYbe0d7Hh DvyxwKrTZEKfblU+kMLFY8ewUkmTGPKqu2DXJFRxviy/DY0vu3yMHMJniAH8WFelgcPdY2j88dn UGFJx9AIV6I6Y1pVRQfWF+F+bHCkhtIDnFNgTatdeaU+2Fq268Ea8Pk1MwuCS6SNcuSIUKF17yj 1eBrb5MxYrkeZ2kkGA2LlULZbCtwEeZtANxbntow9m+mTYfL6gt2CwdjsUlmNz+I4jm307xHigF Jev2r0HX8WQevdQh/o88iNKcLrLoeeFR17nVx2PNtETk7H2j3VPqwAK7LfUjRcbOG+cBCpLVE= X-Google-Smtp-Source: AGHT+IGR/VzDF7AB+sIC/+cJHCH4X5S7Mi8sJ3f5dCfpSYmCmX5nmYDVJr+NLnssvgjti7LClYe3OA== X-Received: by 2002:a05:6122:21a8:b0:54a:23dd:5a9e with SMTP id 71dfb90a1353d-5593e270143mr2102007e0c.3.1762007019132; Sat, 01 Nov 2025 07:23:39 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:38 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 4/9] memblock: Unpreserve memory in case of error Date: Sat, 1 Nov 2025 10:23:20 -0400 Message-ID: <20251101142325.1326536-5-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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" If there is an error half way through KHO memory preservation, we should rollback and unpreserve everything that is partially preserved. Signed-off-by: Pasha Tatashin Suggested-by: Pratyush Yadav Reviewed-by: Mike Rapoport (Microsoft) Reviewed-by: Pratyush Yadav --- mm/memblock.c | 73 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/mm/memblock.c b/mm/memblock.c index e3bef9b35d63..f527ad1ca682 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -2445,29 +2445,60 @@ int reserve_mem_release_by_name(const char *name) #define MEMBLOCK_KHO_NODE_COMPATIBLE "memblock-v1" #define RESERVE_MEM_KHO_NODE_COMPATIBLE "reserve-mem-v1" =20 +static int __init reserved_mem_preserve(void) +{ + unsigned int nr_preserved =3D 0; + int err; + + for (unsigned int i =3D 0; i < reserved_mem_count; i++, nr_preserved++) { + struct reserve_mem_table *map =3D &reserved_mem_table[i]; + struct page *page =3D phys_to_page(map->start); + unsigned int nr_pages =3D map->size >> PAGE_SHIFT; + + err =3D kho_preserve_pages(page, nr_pages); + if (err) + goto err_unpreserve; + } + + return 0; + +err_unpreserve: + for (unsigned int i =3D 0; i < nr_preserved; i++) { + struct reserve_mem_table *map =3D &reserved_mem_table[i]; + struct page *page =3D phys_to_page(map->start); + unsigned int nr_pages =3D map->size >> PAGE_SHIFT; + + kho_unpreserve_pages(page, nr_pages); + } + + return err; +} + static int __init prepare_kho_fdt(void) { - int err =3D 0, i; struct page *fdt_page; void *fdt; + int err; =20 fdt_page =3D alloc_page(GFP_KERNEL); - if (!fdt_page) - return -ENOMEM; + if (!fdt_page) { + err =3D -ENOMEM; + goto err_no_fdt_page; + } =20 fdt =3D page_to_virt(fdt_page); + err =3D kho_preserve_pages(fdt_page, 1); + if (err) + goto err_free_fdt; =20 err |=3D fdt_create(fdt, PAGE_SIZE); err |=3D fdt_finish_reservemap(fdt); - err |=3D fdt_begin_node(fdt, ""); err |=3D fdt_property_string(fdt, "compatible", MEMBLOCK_KHO_NODE_COMPATI= BLE); - for (i =3D 0; i < reserved_mem_count; i++) { + + for (unsigned int i =3D 0; !err && i < reserved_mem_count; i++) { struct reserve_mem_table *map =3D &reserved_mem_table[i]; - struct page *page =3D phys_to_page(map->start); - unsigned int nr_pages =3D map->size >> PAGE_SHIFT; =20 - err |=3D kho_preserve_pages(page, nr_pages); err |=3D fdt_begin_node(fdt, map->name); err |=3D fdt_property_string(fdt, "compatible", RESERVE_MEM_KHO_NODE_COM= PATIBLE); err |=3D fdt_property(fdt, "start", &map->start, sizeof(map->start)); @@ -2477,15 +2508,27 @@ static int __init prepare_kho_fdt(void) err |=3D fdt_end_node(fdt); err |=3D fdt_finish(fdt); =20 - err |=3D kho_preserve_folio(page_folio(fdt_page)); + if (err) + goto err_unpreserve_fdt; =20 - if (!err) - err =3D kho_add_subtree(MEMBLOCK_KHO_FDT, fdt); + err =3D kho_add_subtree(MEMBLOCK_KHO_FDT, fdt); + if (err) + goto err_unpreserve_fdt; =20 - if (err) { - pr_err("failed to prepare memblock FDT for KHO: %d\n", err); - put_page(fdt_page); - } + err =3D reserved_mem_preserve(); + if (err) + goto err_remove_subtree; + + return 0; + +err_remove_subtree: + kho_remove_subtree(fdt); +err_unpreserve_fdt: + kho_unpreserve_pages(fdt_page, 1); +err_free_fdt: + put_page(fdt_page); +err_no_fdt_page: + pr_err("failed to prepare memblock FDT for KHO: %d\n", err); =20 return err; } --=20 2.51.1.930.gacf6e81ea2-goog From nobody Wed Dec 17 21:30:17 2025 Received: from mail-ua1-f45.google.com (mail-ua1-f45.google.com [209.85.222.45]) (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 6E4A82F6562 for ; Sat, 1 Nov 2025 14:23:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007024; cv=none; b=W6l+H/bbLH6mWPaBBSpCA2dXdcK5ggNT2LCN2Wp0EUw6w8/KfSVrW8w8IxZVy37aCwKbNwMYJNi7fZSng2AFoVsSuvk2acCewlIoZlwXt9zNABVAcQDLzbOlW8vfiLWeSzesVx0o3E8a1oMQwaiip3FCzFyL40zSsy+pAhI9gCQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007024; c=relaxed/simple; bh=yHqwthdjQR9NASx0Os0y7RkZY+CTnqkZiedG/ZfbJsM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q+dg7/Rk7Sh2C3qfImyVHRU8rv9PMst1Oj6DhxfSppMezyIlnT9kslYpQk1qnpC6LvCT0XHls41pKPf6KFUM5ODZGh0/5A8M/9bQ79W/WRl7aN/8kv2pR6Z/z/NGpEk6CmPom32aXZYgosOYoPdmQ0nyNr6HfqDug0l5rQ5Xwhg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=gN7eycO8; arc=none smtp.client-ip=209.85.222.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="gN7eycO8" Received: by mail-ua1-f45.google.com with SMTP id a1e0cc1a2514c-93515cb8c2bso1362286241.1 for ; Sat, 01 Nov 2025 07:23:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007021; x=1762611821; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=57rygU5OjDWbT5PCPIwncZxw1NBlZuRuRnZzBsppy54=; b=gN7eycO8W9hBtFwgbXMYmbIgawUgpGrbpoYURAUEQVZxFMrLP3ZULVAMwA7Tiw2n+q JU+NG6nxEUVIXRvxGHETXXpimzRta9F449hquKKDghUSwY+LzjG4Xl0wPSUyBbklSCa+ hTa3YF2PA7nry36oNU3ZIt6WdDLaq15lguMUQfZGlstObc7CjRcPXPancdnK/v4wBy7V 47X/8tL6dlU4lx0tWCx+DlFlj46Z+dA2fPtxBIkTnVrp6/qxY+XqG6bAViRPFIca9TPD nVo6F2YhIlUMbdWyl73lwoXZlMCosADB5wGnpf8RtzipK+9SAAKD+z0agucSl8q+RTyh xNeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007021; x=1762611821; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=57rygU5OjDWbT5PCPIwncZxw1NBlZuRuRnZzBsppy54=; b=klkeQ0MiwykC+2KeX+9niSPjP6tYmSetMn1pohTV7JaZ5LqVcrnv2SZoHB8bXUD79u mCnSfMfRLi5wXm4oDGbplB1z8FDWV2mCmjN4D/IGYlBiShSy75Ea/O5/fPcwISRwbRsf oQSx6QHU8m/lv1zqBdH6TyFm/t89vLXkh/JFC3vrikdxLWptdW+OfY9avJu3zVJ2MpQD 7MNXhcEwwglYEkhEgYXfa+LS696qYHKTmMg6ThoAvTriIYi22fRfljnw/zxCTXdYnLe/ fOuXEtmA+M0egPib9wDPLlboezglH3CCMfgi82dnNfWLrxEURg9qp6N9/30AcreFaToL Wbcg== X-Forwarded-Encrypted: i=1; AJvYcCUVZ5RmJ8dgDdfyiEL3CfuZhOYx9P4xqwbrMxqhFoiyA19l+bU94mWHVU+D+OxKQeDhgw+Ih6XtXbwTy2o=@vger.kernel.org X-Gm-Message-State: AOJu0YzTugOhnrrBDr19tjt/DrfqmHze7CnKLXhCh8HlgSKPHrY/YxbV ueci/6/ZtbeuXb4ccFuY3l4mWkUdWnhAQBWkQ3QUkl945K5iBOybztC4+2ADjUFkFA4= X-Gm-Gg: ASbGnctJyiliZWwyeg13nwRMQek43NpiN9d3GMSS84RlNBKeqP4B4kdG/hNrcQEOdJA Q6iJFbUl5s85aQnes+z16zZZeGckSumJ2c7QEnYZDRt9wdZl1gKRhFJ89pkUAuuSmV53T4852mZ /9NSt8Ri7RJlTT/k7NO32n2TSDr4p/VumbEeH5daWHQyqQPo2AY3BsFCLAgWRh4KaZwSmOSj+tz hovUYXjQlnlJr9LbMR7dbhcKL2NzRzs3rHQYF1gf7xrJomYLYXqcXjqsziLpUIZkCIsqYSr8duI v7IcEDW9GYqLtTg2YkqIQTaGVmhsEJs4zFifnIe/QCVO/V1C9sTvtkUjz9AcSI4gLa3lFqStImv 2INr10rfDyYsuiIMoUQdoCvplPWW/Ga76d3r66kmCNOlifC8IsEiO6gCBwBsnuMZEt7eVastoa4 M6QjrmRNLeMIX5UyHDL2XFTRpp4xflrYCHxxd3qeafjxGBzQOBSPGXL8IS9mtN X-Google-Smtp-Source: AGHT+IFHTA9MFhIfCaO4quOEqPC9MjBBViuMWnhpeFtjZfr2lHvftLMFFMHCzKtyyjM8DjV8X9i0hw== X-Received: by 2002:a05:6122:90c:b0:554:e4ba:4408 with SMTP id 71dfb90a1353d-5593e006778mr2627356e0c.0.1762007021390; Sat, 01 Nov 2025 07:23:41 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:40 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 5/9] test_kho: Unpreserve memory in case of error Date: Sat, 1 Nov 2025 10:23:21 -0400 Message-ID: <20251101142325.1326536-6-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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" If there is an error half way through KHO memory preservation, we should rollback and unpreserve everything that is partially preserved. Co-developed-by: Mike Rapoport (Microsoft) Signed-off-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin --- lib/test_kho.c | 103 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 30 deletions(-) diff --git a/lib/test_kho.c b/lib/test_kho.c index 9f7cfa6ac855..025ea251a186 100644 --- a/lib/test_kho.c +++ b/lib/test_kho.c @@ -33,17 +33,28 @@ struct kho_test_state { unsigned int nr_folios; struct folio **folios; phys_addr_t *folios_info; + struct kho_vmalloc folios_info_phys; + int nr_folios_preserved; struct folio *fdt; __wsum csum; }; =20 static struct kho_test_state kho_test_state; =20 -static int kho_test_save_data(struct kho_test_state *state, void *fdt) +static void kho_test_unpreserve_data(struct kho_test_state *state) +{ + for (int i =3D 0; i < state->nr_folios_preserved; i++) + kho_unpreserve_folio(state->folios[i]); + + kho_unpreserve_vmalloc(&state->folios_info_phys); + vfree(state->folios_info); +} + +static int kho_test_preserve_data(struct kho_test_state *state) { - phys_addr_t *folios_info __free(kvfree) =3D NULL; struct kho_vmalloc folios_info_phys; - int err =3D 0; + phys_addr_t *folios_info; + int err; =20 folios_info =3D vmalloc_array(state->nr_folios, sizeof(*folios_info)); if (!folios_info) @@ -51,64 +62,98 @@ static int kho_test_save_data(struct kho_test_state *st= ate, void *fdt) =20 err =3D kho_preserve_vmalloc(folios_info, &folios_info_phys); if (err) - return err; + goto err_free_info; + + state->folios_info_phys =3D folios_info_phys; + state->folios_info =3D folios_info; =20 for (int i =3D 0; i < state->nr_folios; i++) { struct folio *folio =3D state->folios[i]; unsigned int order =3D folio_order(folio); =20 folios_info[i] =3D virt_to_phys(folio_address(folio)) | order; - err =3D kho_preserve_folio(folio); if (err) - break; + goto err_unpreserve; + state->nr_folios_preserved++; } =20 + return 0; + +err_unpreserve: + /* + * kho_test_unpreserve_data frees folio_info, bail out immediately to + * avoid double free + */ + kho_test_unpreserve_data(state); + return err; + +err_free_info: + vfree(folios_info); + return err; +} + +static int kho_test_prepare_fdt(struct kho_test_state *state, ssize_t fdt_= size) +{ + const char compatible[] =3D KHO_TEST_COMPAT; + unsigned int magic =3D KHO_TEST_MAGIC; + void *fdt =3D folio_address(state->fdt); + int err; + + err =3D fdt_create(fdt, fdt_size); + err |=3D fdt_finish_reservemap(fdt); + err |=3D fdt_begin_node(fdt, ""); + err |=3D fdt_property(fdt, "compatible", compatible, sizeof(compatible)); + err |=3D fdt_property(fdt, "magic", &magic, sizeof(magic)); + err |=3D fdt_begin_node(fdt, "data"); err |=3D fdt_property(fdt, "nr_folios", &state->nr_folios, sizeof(state->nr_folios)); - err |=3D fdt_property(fdt, "folios_info", &folios_info_phys, - sizeof(folios_info_phys)); + err |=3D fdt_property(fdt, "folios_info", &state->folios_info_phys, + sizeof(state->folios_info_phys)); err |=3D fdt_property(fdt, "csum", &state->csum, sizeof(state->csum)); err |=3D fdt_end_node(fdt); =20 - if (!err) - state->folios_info =3D no_free_ptr(folios_info); + err |=3D fdt_end_node(fdt); + err |=3D fdt_finish(fdt); =20 return err; } =20 -static int kho_test_prepare_fdt(struct kho_test_state *state) +static int kho_test_preserve(struct kho_test_state *state) { - const char compatible[] =3D KHO_TEST_COMPAT; - unsigned int magic =3D KHO_TEST_MAGIC; ssize_t fdt_size; - int err =3D 0; - void *fdt; + int err; =20 fdt_size =3D state->nr_folios * sizeof(phys_addr_t) + PAGE_SIZE; state->fdt =3D folio_alloc(GFP_KERNEL, get_order(fdt_size)); if (!state->fdt) return -ENOMEM; =20 - fdt =3D folio_address(state->fdt); - - err |=3D kho_preserve_folio(state->fdt); - err |=3D fdt_create(fdt, fdt_size); - err |=3D fdt_finish_reservemap(fdt); + err =3D kho_preserve_folio(state->fdt); + if (err) + goto err_free_fdt; =20 - err |=3D fdt_begin_node(fdt, ""); - err |=3D fdt_property(fdt, "compatible", compatible, sizeof(compatible)); - err |=3D fdt_property(fdt, "magic", &magic, sizeof(magic)); - err |=3D kho_test_save_data(state, fdt); - err |=3D fdt_end_node(fdt); + err =3D kho_test_preserve_data(state); + if (err) + goto err_unpreserve_fdt; =20 - err |=3D fdt_finish(fdt); + err =3D kho_test_prepare_fdt(state, fdt_size); + if (err) + goto err_unpreserve_data; =20 err =3D kho_add_subtree(KHO_TEST_FDT, folio_address(state->fdt)); if (err) - folio_put(state->fdt); + goto err_unpreserve_data; =20 + return 0; + +err_unpreserve_data: + kho_test_unpreserve_data(state); +err_unpreserve_fdt: + kho_unpreserve_folio(state->fdt); +err_free_fdt: + folio_put(state->fdt); return err; } =20 @@ -174,14 +219,12 @@ static int kho_test_save(void) if (err) goto err_free_folios; =20 - err =3D kho_test_prepare_fdt(state); + err =3D kho_test_preserve(state); if (err) goto err_free_folios; =20 return 0; =20 -err_free_fdt: - folio_put(state->fdt); err_free_folios: kvfree(folios); return err; --=20 2.51.1.930.gacf6e81ea2-goog From nobody Wed Dec 17 21:30:17 2025 Received: from mail-vs1-f51.google.com (mail-vs1-f51.google.com [209.85.217.51]) (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 96F2E2F9DBC for ; Sat, 1 Nov 2025 14:23:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.217.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007026; cv=none; b=sNyXFUlAb0eAvMwWKSgKGHBpWPAUtablrNbSSdcv7ut7360kwsLNVRGmtPpRwaUD2JGpWluv/T6KrYhxknLZgfOVC3FDuo+yGPY0wc0xHRg+7oMoJ29+e05eK8f4bJfNmpGP7i705mtJTqpjSJLv0ZJ+VQBMQvM2y5DiFQi68nc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007026; c=relaxed/simple; bh=+LuQqkGCe84RIp2fAEq/d3OCjgqkDPmWEUoXD9tp6JQ=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qmvtAMD365Be7dsvClOlurcXZYAV5xgwdbai2K9C46DdhWIOolbcmMVTlu2I/ZANusnhA5A7rrDM8cfjfcxo5e3Sp5742CFb+maY7blb6+ZxzvEEpG21rB1/6/Poy3nJpMNDqxGhnN/hTb3hLo7eg0S/T+dJxo9PohztmLSsBqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=bFlitAdO; arc=none smtp.client-ip=209.85.217.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="bFlitAdO" Received: by mail-vs1-f51.google.com with SMTP id ada2fe7eead31-5d967b67003so4059682137.2 for ; Sat, 01 Nov 2025 07:23:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007023; x=1762611823; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=/3sZsODYdE+lXQW6sSfXvI4QX3oinLZLnJVK+OowB7E=; b=bFlitAdOMFOlBGqOhB/WtEoPPxWEoQnpku9XX5BdVj4stcmqVMraZiyeck1o8S6Hmc ihe9wpxvUT/YnAwr1SUOMoWbe45W5NBVIgepJ9YLjhrFHogtoJIPnm31qlnwf5e1jzzU /3/EH3VOnaoWdhkvNoMTGzlF5OdmWFhlEIsJkeItHKWL/W8KTqmyRjGbtzAPZnGzEARg s/1x0SRDsyR/VjRHVvopZpXoTUTBhDp9kmYGm446N1CqUm+JjpyU5VRkxbtxLa7n5dyv 77Sz9h91Ca0i2Xx5wkoUP0Ib3YNaSP6KEMQ8P8tm8yybQ8moKDHUfM0gpTlykavElUOi KFtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007023; x=1762611823; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/3sZsODYdE+lXQW6sSfXvI4QX3oinLZLnJVK+OowB7E=; b=wSwKokdzyX21ClP0iGRRc0QrRt6rFB6oI1bdGWL731XZSWb/SHyS0+n3YfX1YZtwk2 7ijagk9Il83aZpCyv7Vwb8YKSyCEGYowz7oLk0gOivJIISd1G+mk/f0wv4WcgWClqgYD 5y79pNOND4NTgY3Cbv94grA/AWxe5jX53UoDNdpFTSrryDfdLmxtfSqn3YdxY2dNFtJJ XwvcglwDRR9s+9EhLntKddzLGt5jSvN+eP3QGS7A5FkaKjDBwA47Cif9agBqF+v3C6HH xJxiznZDGaSGTRfkqrHv3/lQgKt+89BmdkQhsdD19IlwKXGt9sxmcZH8/bZpRpNaClvM 7s6g== X-Forwarded-Encrypted: i=1; AJvYcCWIi6urAv00v4LmAFH3HMgSA4MXw/qo3xw1WrIp+T6VP2spKXX/NpvAzcmCIM6criKSrB/NIc6ENbD/XzQ=@vger.kernel.org X-Gm-Message-State: AOJu0YznkdSIflATMlB18NY6+2DYARPG2vrzC4GiBRY3556QjLAOz9y0 ERybSHvkuPtwDuNoSrMOIr0pN15MOdP9NAHqg+iQ8Cb2hscnqJFGD4+maNG7hLf+2XA= X-Gm-Gg: ASbGncucos0Dk8HhnEuxIPYwTigfnk8XInMRh5AoBiQK3jecrlhGPpaicX/Qs94hawS 26BFeIQm6aIuOv7SOTgy+cWC8Kqj9Qkh9tQ4k4escl5wejdGGeQav6/mg2oKVZN7lgGy66OKbfY ZZV8eXSPmJjFEJx0Qz00u0km+89O52dhRoLRDwmZ+AgBXXjO3JVZgcRRlf6fTOF9LNiiIbhav6Y cc19uOKyK2KdfUKRQGPi2mAVOxma19if3jYdA6Ryonb/8+gco1fyFLe99Uvj13s53366ejg3t4c ATMnMAwrIlmbb2wcErFUJL+hlrHe6ZmUgNx+8asL8G05Of7SPd5azwygvaiqWParRY8czA0QSk9 372FJT0JrHgLB+AnbNeLuBaDOFu2LYPREwk3GsOWZMd6n9OTLYtMV7SD1ZcdvuSfLlf2UD8wWnJ 7QwpBqQESvk6IWjV31nwBlrRfSk1VxZwKfnx8WnU7uKZ6lKG4pvCqAcgRGiU59mKVbip9n/Xg= X-Google-Smtp-Source: AGHT+IEW1fTK12XGUTtqXJsef8/76poVKTgBxu4YxD9HHtSEN7ne/NH+yy5cGEPUcuJdr6fOnT+fYw== X-Received: by 2002:a05:6102:8349:20b0:59f:4f48:4e31 with SMTP id ada2fe7eead31-5dbb11f91c3mr1950860137.1.1762007023601; Sat, 01 Nov 2025 07:23:43 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:42 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 6/9] kho: don't unpreserve memory during abort Date: Sat, 1 Nov 2025 10:23:22 -0400 Message-ID: <20251101142325.1326536-7-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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" KHO allows clients to preserve memory regions at any point before the KHO state is finalized. The finalization process itself involves KHO performing its own actions, such as serializing the overall preserved memory map. If this finalization process is aborted, the current implementation destroys KHO's internal memory tracking structures (`kho_out.ser.track.orders`). This behavior effectively unpreserves all memory from KHO's perspective, regardless of whether those preservations were made by clients before the finalization attempt or by KHO itself during finalization. This premature unpreservation is incorrect. An abort of the finalization process should only undo actions taken by KHO as part of that specific finalization attempt. Individual memory regions preserved by clients prior to finalization should remain preserved, as their lifecycle is managed by the clients themselves. These clients might still need to call kho_unpreserve_folio() or kho_unpreserve_phys() based on their own logic, even after a KHO finalization attempt is aborted. Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav --- kernel/kexec_handover.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index c514b300ebe6..3adf86c7c2db 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -1118,31 +1118,12 @@ EXPORT_SYMBOL_GPL(kho_restore_vmalloc); =20 static int __kho_abort(void) { - int err =3D 0; - unsigned long order; - struct kho_mem_phys *physxa; - - xa_for_each(&kho_out.track.orders, order, physxa) { - struct kho_mem_phys_bits *bits; - unsigned long phys; - - xa_for_each(&physxa->phys_bits, phys, bits) - kfree(bits); - - xa_destroy(&physxa->phys_bits); - kfree(physxa); - } - xa_destroy(&kho_out.track.orders); - if (kho_out.preserved_mem_map) { kho_mem_ser_free(kho_out.preserved_mem_map); kho_out.preserved_mem_map =3D NULL; } =20 - if (err) - pr_err("Failed to abort KHO finalization: %d\n", err); - - return err; + return 0; } =20 int kho_abort(void) --=20 2.51.1.930.gacf6e81ea2-goog From nobody Wed Dec 17 21:30:17 2025 Received: from mail-vk1-f173.google.com (mail-vk1-f173.google.com [209.85.221.173]) (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 41C692FB988 for ; Sat, 1 Nov 2025 14:23:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007028; cv=none; b=dG30COaOyO0gfgVh2es0E7aWkUoqJPMHmBfTxjDgH1MbiVPMfMyN+MSYbH28LDwAHdJMZi8kJ2JflLodKjzB7B9csa2EC3C7cQCImn5cqv/XIVuVSBXrCYaDz8Lmp9OUH37O6FEfmoG6DS6P66ZtY8YdMiS+iw3buy5jM1MMXHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007028; c=relaxed/simple; bh=Sz6qvH3kZZly7FxwahblwfCH26skEMNmJunfLKVFLiY=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ro84iR8N5eexfoxApvzknInMxLNtd5nx6Wrig9gKAVBB6nsi+NeJr215mCIGHiYnac3PpiQpTWZ2OzsD9kWnBEE5IpPlfvm+ybRUFovAMQIysaWLWva0RYTq4hqXr99tAuG/n0mKvQuIm13er+lfuZEuW24msuxUyp6ELLN9ouQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=Q8hF631B; arc=none smtp.client-ip=209.85.221.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="Q8hF631B" Received: by mail-vk1-f173.google.com with SMTP id 71dfb90a1353d-5563c36f6d4so3234329e0c.1 for ; Sat, 01 Nov 2025 07:23:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007025; x=1762611825; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=GqNjQc+nWE3xdzzLNsyLKvDeccdmT+igcGJuf8ZrBtc=; b=Q8hF631BsLLm76sDVONF8JXZiWa0IrI2d3Ie4tbwxb56JjjGTH2W+inbYiPElSXGae wLTKKTrB/ZSaqiAXr9XQN2VZzJvOOPJvcAQdfXcEDyHDNHGitReCRLMn0y2ejXKfLVDq LxOughvsVo2Y4awPiRZ8oFFYX/ej/rKsiRbmatK4NbBWpRVlC5AHxEw/lhartnPEIwr8 7dUrUwzdnsEgbw4NVT0Xzqv2xGpzgcp3cteGclv17nG+dvIFSJHBguIDE1nAWdNr9P9Y hHlyzxGIrqyNJSG/s6ejET1LM8MumQ0cHoK0ipsgO3UOpNWwr5cUyFiTSdkc4oJ/X5pV fTeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007025; x=1762611825; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GqNjQc+nWE3xdzzLNsyLKvDeccdmT+igcGJuf8ZrBtc=; b=iTx1jHQvaKFm5SCWAu7Y/ODjDXFsu6nTaL36mpEtICdox3vIN1Vm7Wptlno8hwwwsi oJA7mWuUoxru6fRCTrQJsNSMULPV3CgjX5+p2i9KjcnDtpeL9NIgEJ94/HKP2ZkUkHF1 MnrRvNu0CGcOhXYQbCUZYhoXituLN0d9cNbKuzPVEvH9lRVLpusfWixXQq0h9eNY74+i DZ9x8Ee2djI0pmbpGaLcOhpPgXQgY6nx3lb6uVY/Qce1D6pH+qavR+TJOXZpiFxQuLnS NAuuVnraaTzzLDSlPOmaNDSIrFZ6/XCSPiw4NwYtCJ3ryEp6R7i8DcbPco7pxYNdCzcW /RKg== X-Forwarded-Encrypted: i=1; AJvYcCXPCE6JWW2dxccXBbwYWxsf/oPdh1/Dic5Uz3v4qlB3XhQMLDkv+Z5CyTeIeBXGhRV9mwjIx/JeJC6AAyg=@vger.kernel.org X-Gm-Message-State: AOJu0YzCpRcwSKktqlKahu89P+oQe/oCPyUGFtnw1fClCy+jLbI3pTYe U+3/t5M5GicISOZUf5+3p6C4xgTK+O9/CIeTgACf4ILRcezBHbFgLI9PIavM2Kfr7ec= X-Gm-Gg: ASbGnctb5N7xoODO4FTMubtcQCJ643jQvS0neWEC2Fyxkrm6ljj+9c7NRbhV3fFwPOl EC7Z0nB8ZpQRlhEArELplIQGyKn+Qosh7tuLgUVd/2dBrxTWw+H1wRdG8QbVe7AcMaSmUu4Ak2g kpFFTFRIRhIKvDsifTc+NFzXrAnk5hChwsMFZ6mD0UEsO3f28Gg/sJg+BL3Fdgz68DxWwPX7abI Wxi7GsuuvKAtJ3/jSy7kc/QyQt6uyyIB4wF/EKGworkELqJqtDFwgkRCsgrH1AcU615lSsk4Zjk G5voMUFKtTosngr2mXRmMrUSgqOscgDx6m2LCS4iH+kw6jBeDz1VshaWkQQnUTR5UK2IVuns0iK CeJhQqUgchwv42tIS8f2NC9ixWCFCp/sE3WGiSPn/6U+eiNZwqtoHqCMZWw5oWWSueEWjMmR160 fDHWlQQwbDJaXnFcKBWTtECuWX2lxaK2I+18PdLIafrQdbv0m9rQtj2d7XJhbk X-Google-Smtp-Source: AGHT+IHYfN0T4cVNH96uqE/VxqJsEPgIJwOQllfGh/DOiPLvpYAfaaq3PsJ2yY0Nnq8P1OfSoH8nvw== X-Received: by 2002:a05:6122:3289:b0:552:3366:e822 with SMTP id 71dfb90a1353d-5593e260540mr2675875e0c.1.1762007025167; Sat, 01 Nov 2025 07:23:45 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:44 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 7/9] liveupdate: kho: move to kernel/liveupdate Date: Sat, 1 Nov 2025 10:23:23 -0400 Message-ID: <20251101142325.1326536-8-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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" Move KHO to kernel/liveupdate/ in preparation of placing all Live Update core kernel related files to the same place. Signed-off-by: Pasha Tatashin Reviewed-by: Jason Gunthorpe Reviewed-by: Mike Rapoport (Microsoft) --- Documentation/core-api/kho/concepts.rst | 2 +- MAINTAINERS | 2 +- init/Kconfig | 2 + kernel/Kconfig.kexec | 34 ---------------- kernel/Makefile | 4 +- kernel/liveupdate/Kconfig | 39 +++++++++++++++++++ kernel/liveupdate/Makefile | 5 +++ kernel/{ =3D> liveupdate}/kexec_handover.c | 4 +- .../{ =3D> liveupdate}/kexec_handover_debug.c | 0 .../{ =3D> liveupdate}/kexec_handover_debugfs.c | 0 .../kexec_handover_internal.h | 0 11 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 kernel/liveupdate/Kconfig create mode 100644 kernel/liveupdate/Makefile rename kernel/{ =3D> liveupdate}/kexec_handover.c (99%) rename kernel/{ =3D> liveupdate}/kexec_handover_debug.c (100%) rename kernel/{ =3D> liveupdate}/kexec_handover_debugfs.c (100%) rename kernel/{ =3D> liveupdate}/kexec_handover_internal.h (100%) diff --git a/Documentation/core-api/kho/concepts.rst b/Documentation/core-a= pi/kho/concepts.rst index 36d5c05cfb30..d626d1dbd678 100644 --- a/Documentation/core-api/kho/concepts.rst +++ b/Documentation/core-api/kho/concepts.rst @@ -70,5 +70,5 @@ in the FDT. That state is called the KHO finalization pha= se. =20 Public API =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -.. kernel-doc:: kernel/kexec_handover.c +.. kernel-doc:: kernel/liveupdate/kexec_handover.c :export: diff --git a/MAINTAINERS b/MAINTAINERS index bdd0a1260421..764df916fae7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13795,7 +13795,7 @@ S: Maintained F: Documentation/admin-guide/mm/kho.rst F: Documentation/core-api/kho/* F: include/linux/kexec_handover.h -F: kernel/kexec_handover* +F: kernel/liveupdate/kexec_handover* F: tools/testing/selftests/kho/ =20 KEYS-ENCRYPTED diff --git a/init/Kconfig b/init/Kconfig index cab3ad28ca49..0605de5d96c0 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2138,6 +2138,8 @@ config TRACEPOINTS =20 source "kernel/Kconfig.kexec" =20 +source "kernel/liveupdate/Kconfig" + endmenu # General setup =20 source "arch/Kconfig" diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec index cc6743137946..15632358bcf7 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -94,40 +94,6 @@ config KEXEC_JUMP Jump between original kernel and kexeced kernel and invoke code in physical address mode via KEXEC =20 -config KEXEC_HANDOVER - bool "kexec handover" - depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE - depends on !DEFERRED_STRUCT_PAGE_INIT - select MEMBLOCK_KHO_SCRATCH - select KEXEC_FILE - select LIBFDT - select CMA - help - Allow kexec to hand over state across kernels by generating and - passing additional metadata to the target kernel. This is useful - to keep data or state alive across the kexec. For this to work, - both source and target kernels need to have this option enabled. - -config KEXEC_HANDOVER_DEBUG - bool "Enable Kexec Handover debug checks" - depends on KEXEC_HANDOVER - help - This option enables extra sanity checks for the Kexec Handover - subsystem. Since, KHO performance is crucial in live update - scenarios and the extra code might be adding overhead it is - only optionally enabled. - -config KEXEC_HANDOVER_DEBUGFS - bool "kexec handover debugfs interface" - default KEXEC_HANDOVER - depends on KEXEC_HANDOVER - select DEBUG_FS - help - Allow to control kexec handover device tree via debugfs - interface, i.e. finalize the state or aborting the finalization. - Also, enables inspecting the KHO fdt trees with the debugfs binary - blobs. - config CRASH_DUMP bool "kernel crash dumps" default ARCH_DEFAULT_CRASH_DUMP diff --git a/kernel/Makefile b/kernel/Makefile index 2cf7909a74e5..e83669841b8c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -52,6 +52,7 @@ obj-y +=3D printk/ obj-y +=3D irq/ obj-y +=3D rcu/ obj-y +=3D livepatch/ +obj-y +=3D liveupdate/ obj-y +=3D dma/ obj-y +=3D entry/ obj-y +=3D unwind/ @@ -82,9 +83,6 @@ obj-$(CONFIG_CRASH_DUMP_KUNIT_TEST) +=3D crash_core_test.o obj-$(CONFIG_KEXEC) +=3D kexec.o obj-$(CONFIG_KEXEC_FILE) +=3D kexec_file.o obj-$(CONFIG_KEXEC_ELF) +=3D kexec_elf.o -obj-$(CONFIG_KEXEC_HANDOVER) +=3D kexec_handover.o -obj-$(CONFIG_KEXEC_HANDOVER_DEBUG) +=3D kexec_handover_debug.o -obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS) +=3D kexec_handover_debugfs.o obj-$(CONFIG_BACKTRACE_SELF_TEST) +=3D backtracetest.o obj-$(CONFIG_COMPAT) +=3D compat.o obj-$(CONFIG_CGROUPS) +=3D cgroup/ diff --git a/kernel/liveupdate/Kconfig b/kernel/liveupdate/Kconfig new file mode 100644 index 000000000000..1379a4c40b09 --- /dev/null +++ b/kernel/liveupdate/Kconfig @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0-only + +menu "Live Update and Kexec HandOver" + +config KEXEC_HANDOVER + bool "kexec handover" + depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE + depends on !DEFERRED_STRUCT_PAGE_INIT + select MEMBLOCK_KHO_SCRATCH + select KEXEC_FILE + select LIBFDT + select CMA + help + Allow kexec to hand over state across kernels by generating and + passing additional metadata to the target kernel. This is useful + to keep data or state alive across the kexec. For this to work, + both source and target kernels need to have this option enabled. + +config KEXEC_HANDOVER_DEBUG + bool "Enable Kexec Handover debug checks" + depends on KEXEC_HANDOVER + help + This option enables extra sanity checks for the Kexec Handover + subsystem. Since, KHO performance is crucial in live update + scenarios and the extra code might be adding overhead it is + only optionally enabled. + +config KEXEC_HANDOVER_DEBUGFS + bool "kexec handover debugfs interface" + default KEXEC_HANDOVER + depends on KEXEC_HANDOVER + select DEBUG_FS + help + Allow to control kexec handover device tree via debugfs + interface, i.e. finalize the state or aborting the finalization. + Also, enables inspecting the KHO fdt trees with the debugfs binary + blobs. + +endmenu diff --git a/kernel/liveupdate/Makefile b/kernel/liveupdate/Makefile new file mode 100644 index 000000000000..f52ce1ebcf86 --- /dev/null +++ b/kernel/liveupdate/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_KEXEC_HANDOVER) +=3D kexec_handover.o +obj-$(CONFIG_KEXEC_HANDOVER_DEBUG) +=3D kexec_handover_debug.o +obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS) +=3D kexec_handover_debugfs.o diff --git a/kernel/kexec_handover.c b/kernel/liveupdate/kexec_handover.c similarity index 99% rename from kernel/kexec_handover.c rename to kernel/liveupdate/kexec_handover.c index 3adf86c7c2db..be945c133a2f 100644 --- a/kernel/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -26,8 +26,8 @@ * KHO is tightly coupled with mm init and needs access to some of mm * internal APIs. */ -#include "../mm/internal.h" -#include "kexec_internal.h" +#include "../../mm/internal.h" +#include "../kexec_internal.h" #include "kexec_handover_internal.h" =20 #define KHO_FDT_COMPATIBLE "kho-v1" diff --git a/kernel/kexec_handover_debug.c b/kernel/liveupdate/kexec_handov= er_debug.c similarity index 100% rename from kernel/kexec_handover_debug.c rename to kernel/liveupdate/kexec_handover_debug.c diff --git a/kernel/kexec_handover_debugfs.c b/kernel/liveupdate/kexec_hand= over_debugfs.c similarity index 100% rename from kernel/kexec_handover_debugfs.c rename to kernel/liveupdate/kexec_handover_debugfs.c diff --git a/kernel/kexec_handover_internal.h b/kernel/liveupdate/kexec_han= dover_internal.h similarity index 100% rename from kernel/kexec_handover_internal.h rename to kernel/liveupdate/kexec_handover_internal.h --=20 2.51.1.930.gacf6e81ea2-goog From nobody Wed Dec 17 21:30:17 2025 Received: from mail-ua1-f44.google.com (mail-ua1-f44.google.com [209.85.222.44]) (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 8FED92FBDE6 for ; Sat, 1 Nov 2025 14:23:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007030; cv=none; b=IGv7y493dYVWYvGz+0DQTEXVQ1dej5dCZ+W2OQRMW2MuVdcw7GP8LfatLGqQuxWjAP8Co2h0S5tu93eP9HwGDgHmYAI05NLHTPBYtrvk+nrQb1p/CYZZqw9cpWMmSmXEzMhyXcwlJl0xy8w+QDT2jWOUs13x0Y9ZmaPv7+OPPgY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007030; c=relaxed/simple; bh=KY8qnH0TrVjhNGmZIwNjdy8NbnBQP/+RCC+BIUEXvo4=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dSnNl1b3cUZLqobbJcWcE4lPUbUtg1oY7yL0fKOUaUP9YMMqT1Ui9XETml0IMPHHVTIFb413YJnnN98rYlNiVDOzS/AoU351JweoLtzUW8FaX1XqRtMs4lapSFVQBDQok1v3mDcWLhiB5OmAKAppinuAh4pNXQ6YqOh1SVE9+aU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=YwXgG61n; arc=none smtp.client-ip=209.85.222.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="YwXgG61n" Received: by mail-ua1-f44.google.com with SMTP id a1e0cc1a2514c-9351ed45fb8so280770241.0 for ; Sat, 01 Nov 2025 07:23:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007027; x=1762611827; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=pSrsMv9vHZViaOOimguQYKUYT4fHRN671HybCTbnJQs=; b=YwXgG61nEjNDMKgQUO/WwJafAZP9oLDVnssvz5kckyJakhbeoqAw4e1oXInPAoykhh MMzm7Ox0VnhP59uv9V/pf8SYzXRicZ6lq1TSosc92JoCSzePSMvDjN8RBHABXyu/MuTJ g1Le0wvH2q8gFJkHDDplQ/eUassc1F0XVGjekJKM9/V0n7DNLXg3iKWRZYEahMnJOku+ MPycTsueCojkEfApi/zfEQXvggAl+/mkCZ0yrUpVc410G5ClHs6XX7PBjm9ISuktgBI4 5gARohsJGqi5qm2OQMYhnZERkNxBh2Z88SkDmS5u9okDRZxGXZQthbaIpoh6DpJygvyc F5hQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007027; x=1762611827; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pSrsMv9vHZViaOOimguQYKUYT4fHRN671HybCTbnJQs=; b=ocGAT9KlQqT/nVzVq5PeTroxkKcdTzzDW0wbcw+tfxHQllxRiak+tXoE2b9B6Odtn5 xEm70291FVmhWnKuYU/GWDk7HHdhx7Mcp9thba8diDRR6wuIwdpKRKgV1am1JVOWDA2Y A3pNarZvkSPxk9mJObafxVq6Dz0eDTP9Uuvt4qbzP1fZ0ficnNN/Aj9A3RKGgratefEQ ZawDm6dIcLhggN3ibm2GgBk8mroaFeI14m995nFZxtzpwoThKuL6g6EU1PSLn+Q+ltyT pLXWB2DMjq2htEs06h9Gw6KkJaU+Bk03GlR9TFVuS2xGusPFEAjmbFVUksQjRPz6MYqN LDPg== X-Forwarded-Encrypted: i=1; AJvYcCVf5mmuwBpWxZCNAk3VLD9x61svlM8zCz2nz6P5FE0gr2qD2W4La9CP/cYU/JQjCJpLRO5h2ETfvl5/7xM=@vger.kernel.org X-Gm-Message-State: AOJu0Yw6XKexqGiud2gOFuRXSoABpcPvh7qzKwOkNxw+nn05ZzcM59Vh PWosOE5YKOgOT5VAhU6OmGDJ+WiUJbsOEdHq0nOZgYsdhn+RVhb/1DFsA3qEB86ILwk= X-Gm-Gg: ASbGncto2wBDbuKbGi6P4HQlQQifTRaByp4louy22bedQsZrb4CNc8V45DshiyvTq6h 7i1GPvwLlMQtOdRg40GjUmxwAAyuR97KRCKLy/ErRfXmV7I+HJbYiphBkl0t/y2aDRHwLY0KB6b JFvQmQBbSAhLbFiXMkaXrVoRsX17crU4rEU519UH/IulUD1l/NGJB7y/olpViKe8JL346SwzVGm rILyyC16dos6Q+suUwjGwTCJZoTIhXv+z+JmC2dRzkBKJqfDNM4UHcDh2rwYKQSDg4udpg4VlmQ 0HWmh5mHb+Nchet5c5f6ymi8hNHPAl3x1VjeXSuLAk1YQL8Q39/rEFE2yawHDmvJ8YsZTBNWGVV xL4uvWYwipafD3xsPHsr69nXGssQxq9D4meq2ETn9dHv2AR0m6DSMOZiJQdt+zu/81rSCltDjCT g+j2h/Zv8OnQ+UWj+8gTzrrcA6DVPCEEPXkK4QG3syB2cM1VScdHo4RM6io579 X-Google-Smtp-Source: AGHT+IEQrc/UahYLt7ANSOW5+mMj6ZVaZ8HuruQYEbIlio2ExuETGUVUCqnEvcl9P/bAjVq8vDxMwQ== X-Received: by 2002:a05:6123:2e9:b0:552:2c5a:c057 with SMTP id 71dfb90a1353d-5593e548e2amr2464325e0c.13.1762007027406; Sat, 01 Nov 2025 07:23:47 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:46 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 8/9] MAINTAINERS: update KHO maintainers Date: Sat, 1 Nov 2025 10:23:24 -0400 Message-ID: <20251101142325.1326536-9-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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" Changyuan does not have cycles to commit to the upstream work of KHO. Remove from KHO maintainers. Signed-off-by: Changyuan Lyu Signed-off-by: Pasha Tatashin Reviewed-by: Mike Rapoport (Microsoft) --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 764df916fae7..6200de2027fe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13788,7 +13788,7 @@ F: kernel/kexec* KEXEC HANDOVER (KHO) M: Alexander Graf M: Mike Rapoport -M: Changyuan Lyu +M: Pasha Tatashin L: kexec@lists.infradead.org L: linux-mm@kvack.org S: Maintained --=20 2.51.1.930.gacf6e81ea2-goog From nobody Wed Dec 17 21:30:17 2025 Received: from mail-vs1-f54.google.com (mail-vs1-f54.google.com [209.85.217.54]) (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 171CB2FC866 for ; Sat, 1 Nov 2025 14:23:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.217.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007031; cv=none; b=FAPyXUGSWhghwtUx/+Jy9xEo0tav02iSfllUMhKhzPEgw3gXmfOuXOFCwC7YSRtGa9x7Hr45wv9Bb4YTHjrS/QvY06OHEhQPe45j4gxN8WzBRrZmxRuXFW/3SojVj1EZ6mevcFNnDljAVtx581OyuQ/RymnUS8cJv5xITTYFpnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762007031; c=relaxed/simple; bh=Oqtj3JWIeCIubS0ImzITam9qN03yIsBoqb2XmRHV0gQ=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jbTjjBUKmjox95x86v/J6N5Xa/3El1Cbbrp/RiIGNhhZ5sXRIrvcu+14MzCPBzYu/ObHwqLSakg/G0BGV+CXkXP7F7puaJwXadBl3vXnywteDt+GvxBwsRasXwxiuWnTPm+hA8qSehmhvbWVCLnhAICzy4/1JnC+LaT79Hqfx4Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=EfpmVhp6; arc=none smtp.client-ip=209.85.217.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="EfpmVhp6" Received: by mail-vs1-f54.google.com with SMTP id ada2fe7eead31-5dbd150efe8so16714137.0 for ; Sat, 01 Nov 2025 07:23:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1762007029; x=1762611829; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Y89e1Xc3DS2D9wc25qIhLt1elzzrVrlmI1KWnbpgyDg=; b=EfpmVhp6JcEhxU01fAVXy3zpa5VJopT6YsxUmzHJ7HTQhogkzVqTZVNPzaZROChJcX NjdqnoHaJTval7JoQS+TMXg6UtWtIlpflZVjWpiz047RUgnR83QLHzYN3naKo4AR4uvT W3+XatYzNkj1xoXhh7wUoPtiDwljaAbwtzMZ6yRUQkXjCVrQpTpFr0ZfoKmu5ZY5Ycq6 zEqHvLuiZ6XA0I7TNz8vVsA3c66dkAjXJIRjMitPwH0KOJmVP9ERAuR/7HdyW2GHVDXz H1/l6OrNlbe63RpZoP6LcLzvf92w9NZ1QnwYjhohRSFObLvVYCSZZ6uxnNU3n8X4Rp/s j4uQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762007029; x=1762611829; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Y89e1Xc3DS2D9wc25qIhLt1elzzrVrlmI1KWnbpgyDg=; b=WwXBw9P5EvcAx5xaLES37St2ws1PdGFDYqtvMmr4nzknFSPObeJ3j7xYq4YT8DzXuX 3m/oQdS9pctoc6IcSa5MXmK2jEHU25ciH5m5z9n9jRzvYNymctaQ+cWwitc105GigPdE uuSeWghGGPbgK6ZoofOXZyQKwNkJOyamFnfyax6a45TVJDcFCSNLNHGwCzYd/xtOTKVW bgI1SefvXwYqQoJOa73hTVkfOProMfAlekK4OiKUtpKfd8isGsbpnrNzBY6zzaa6CItP 5i1yjBbBEgTRbFreqwPWx7fWP2qusBFAPFMfr3lHzGQ5pfvSW6AeXRvBTbHPdcJEyrVo 2pnA== X-Forwarded-Encrypted: i=1; AJvYcCXKAhEQAooyTn2buVpC6QNFuEDWIlJAi3B591cRlh1qbjPBAwDFzsUYXY8N1SIh1pNOQc7jBjVR3EkfcxU=@vger.kernel.org X-Gm-Message-State: AOJu0YzDtTeRFGJffdbnfiSDbBsiwh5EqvL1Y4pm080CHAz15ENK0eHF kHd8YnQT57Xrby+9SF1HjpWuW2RECsm4SdcbNUDjaNSXYsAndfHxMf3jHYxP0bzvgk0= X-Gm-Gg: ASbGncth1MPTstOpqC19tWBwLH7KChu77t6Jgf6HdebXwKfT91KtV/L6nOztpw95cVY 4kq3JED7BeVwpfNBUUzi0sTiqK4N2/G3qd6F7QERq4famMUGwWC5CGrMh00mHpoDC8cXNOlZKJn Hd4PrTsiC0Ia2+/vuaz1cuc2oDAR4G0VaYln0LIt3APvo8O61qajMh8Bm0bIt0gmE4nag6s4PN4 M7QNGJQzzwsco0ydflE83hHB4MelXjMuUocwlbGDz0Z2Og7WY+S+m9gGBW7/Dlf81ck2lD82KM0 /ocU1bbXCJY39qIDNQxuEFVX6pIWFPYZiaDh268g3HpxiNvbHkhCrmIfjNjhFGRi46UhoJLHOSy 96awVcloZYNyVXeJtji50eUv0HrDXiyyX6SG1FwVvQ1FwHtYu8JtOuPgeekb4PV290HeDDKxS7+ 1CMn//rQmq7LVywcfBuSIVAhHBQ2hdaOGjA9kzHS4WwOB9N1VafUdG3oO0urs1 X-Google-Smtp-Source: AGHT+IGFDCScfqliWb9KcrLwkQzx/ze/7HdLlm3rrxqjpvvjEhbQ+nHt0IFtgECikftA3CUT6aFcGQ== X-Received: by 2002:a05:6102:441b:b0:5d6:5e9:9e0c with SMTP id ada2fe7eead31-5dbb11f02d1mr1796389137.4.1762007029092; Sat, 01 Nov 2025 07:23:49 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-559449647e0sm1776242e0c.3.2025.11.01.07.23.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 07:23:48 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org, yanjun.zhu@linux.dev Subject: [PATCH v9 9/9] liveupdate: kho: Use %pe format specifier for error pointer printing Date: Sat, 1 Nov 2025 10:23:25 -0400 Message-ID: <20251101142325.1326536-10-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com> References: <20251101142325.1326536-1-pasha.tatashin@soleen.com> 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: Zhu Yanjun Make pr_xxx() call to use the %pe format specifier instead of %d. The %pe specifier prints a symbolic error string (e.g., -ENOMEM, -EINVAL) when given an error pointer created with ERR_PTR(err). This change enhances the clarity and diagnostic value of the error message by showing a descriptive error name rather than a numeric error code. Note, that some err are still printed by value, as those errors might come from libfdt and not regular errnos. Signed-off-by: Zhu Yanjun Co-developed-by: Pasha Tatashin Signed-off-by: Pasha Tatashin Reviewed-by: Simon Horman Reviewed-by: Mike Rapoport (Microsoft) Reviewed-by: Pratyush Yadav --- kernel/liveupdate/kexec_handover.c | 4 ++-- kernel/liveupdate/kexec_handover_debugfs.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_h= andover.c index be945c133a2f..167c761988d3 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -1448,8 +1448,8 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fd= t_len, memblock_add(area->addr, size); err =3D memblock_mark_kho_scratch(area->addr, size); if (WARN_ON(err)) { - pr_warn("failed to mark the scratch region 0x%pa+0x%pa: %d", - &area->addr, &size, err); + pr_warn("failed to mark the scratch region 0x%pa+0x%pa: %pe", + &area->addr, &size, ERR_PTR(err)); goto out; } pr_debug("Marked 0x%pa+0x%pa as scratch", &area->addr, &size); diff --git a/kernel/liveupdate/kexec_handover_debugfs.c b/kernel/liveupdate= /kexec_handover_debugfs.c index 46e9e6c0791f..ac739d25094d 100644 --- a/kernel/liveupdate/kexec_handover_debugfs.c +++ b/kernel/liveupdate/kexec_handover_debugfs.c @@ -150,8 +150,8 @@ __init void kho_in_debugfs_init(struct kho_debugfs *dbg= , const void *fdt) err =3D __kho_debugfs_fdt_add(&dbg->fdt_list, sub_fdt_dir, name, phys_to_virt(*fdt_phys)); if (err) { - pr_warn("failed to add fdt %s to debugfs: %d\n", name, - err); + pr_warn("failed to add fdt %s to debugfs: %pe\n", name, + ERR_PTR(err)); continue; } } @@ -168,8 +168,10 @@ __init void kho_in_debugfs_init(struct kho_debugfs *db= g, const void *fdt) * reviving state from KHO and setting up KHO for the next * kexec. */ - if (err) - pr_err("failed exposing handover FDT in debugfs: %d\n", err); + if (err) { + pr_err("failed exposing handover FDT in debugfs: %pe\n", + ERR_PTR(err)); + } } =20 __init int kho_out_debugfs_init(struct kho_debugfs *dbg) --=20 2.51.1.930.gacf6e81ea2-goog