[RFC v1 4/9] kho: split vmalloc headers out of kexec_handover.h
Pasha Tatashin
pasha.tatashin at soleen.com
Thu Jun 4 20:32:30 PDT 2026
Split the vmalloc-related ABI definitions and header declarations out
of the monolithic kexec_handover.h header into a dedicated header
file (vmalloc.h).
This is a pure code movement patch; no logic or functional changes are
introduced.
Signed-off-by: Pasha Tatashin <pasha.tatashin at soleen.com>
---
Documentation/core-api/kho/abi.rst | 3 +-
include/linux/kexec_handover.h | 18 -----
include/linux/kho/abi/kexec_handover.h | 77 +-------------------
include/linux/kho/abi/memfd.h | 3 +-
include/linux/kho/abi/vmalloc.h | 99 ++++++++++++++++++++++++++
include/linux/kho/vmalloc.h | 34 +++++++++
6 files changed, 137 insertions(+), 97 deletions(-)
create mode 100644 include/linux/kho/abi/vmalloc.h
create mode 100644 include/linux/kho/vmalloc.h
diff --git a/Documentation/core-api/kho/abi.rst b/Documentation/core-api/kho/abi.rst
index da5c6636bb17..b61363679829 100644
--- a/Documentation/core-api/kho/abi.rst
+++ b/Documentation/core-api/kho/abi.rst
@@ -13,8 +13,7 @@ Core Kexec Handover ABI
vmalloc preservation ABI
========================
-.. kernel-doc:: include/linux/kho/abi/kexec_handover.h
- :doc: Kexec Handover ABI for vmalloc Preservation
+.. kernel-doc:: include/linux/kho/abi/vmalloc.h
memblock preservation ABI
=========================
diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h
index 8968c56d2d73..518fdab2a4d1 100644
--- a/include/linux/kexec_handover.h
+++ b/include/linux/kexec_handover.h
@@ -11,8 +11,6 @@ struct kho_scratch {
phys_addr_t size;
};
-struct kho_vmalloc;
-
struct folio;
struct page;
@@ -24,14 +22,11 @@ int kho_preserve_folio(struct folio *folio);
void kho_unpreserve_folio(struct folio *folio);
int kho_preserve_pages(struct page *page, unsigned long nr_pages);
void kho_unpreserve_pages(struct page *page, unsigned long nr_pages);
-int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation);
-void kho_unpreserve_vmalloc(struct kho_vmalloc *preservation);
void *kho_alloc_preserve(size_t size);
void kho_unpreserve_free(void *mem);
void kho_restore_free(void *mem);
struct folio *kho_restore_folio(phys_addr_t phys);
struct page *kho_restore_pages(phys_addr_t phys, unsigned long nr_pages);
-void *kho_restore_vmalloc(const struct kho_vmalloc *preservation);
int kho_add_subtree(const char *name, void *blob, size_t size);
void kho_remove_subtree(void *blob);
int kho_retrieve_subtree(const char *name, phys_addr_t *phys, size_t *size);
@@ -65,14 +60,6 @@ static inline int kho_preserve_pages(struct page *page, unsigned int nr_pages)
static inline void kho_unpreserve_pages(struct page *page, unsigned int nr_pages) { }
-static inline int kho_preserve_vmalloc(void *ptr,
- struct kho_vmalloc *preservation)
-{
- return -EOPNOTSUPP;
-}
-
-static inline void kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) { }
-
static inline void *kho_alloc_preserve(size_t size)
{
return ERR_PTR(-EOPNOTSUPP);
@@ -92,11 +79,6 @@ static inline struct page *kho_restore_pages(phys_addr_t phys,
return NULL;
}
-static inline void *kho_restore_vmalloc(const struct kho_vmalloc *preservation)
-{
- return NULL;
-}
-
static inline int kho_add_subtree(const char *name, void *blob, size_t size)
{
return -EOPNOTSUPP;
diff --git a/include/linux/kho/abi/kexec_handover.h b/include/linux/kho/abi/kexec_handover.h
index 99e4a53d4e35..c893b5045078 100644
--- a/include/linux/kho/abi/kexec_handover.h
+++ b/include/linux/kho/abi/kexec_handover.h
@@ -96,80 +96,5 @@
/* The FDT property for the size of preserved data blobs. */
#define KHO_SUB_TREE_SIZE_PROP_NAME "blob-size"
-/**
- * DOC: Kexec Handover ABI for vmalloc Preservation
- *
- * The Kexec Handover ABI for preserving vmalloc'ed memory is defined by
- * a set of structures and helper macros. The layout of these structures is a
- * stable contract between kernels and is versioned by the KHO_FDT_COMPATIBLE
- * string.
- *
- * The preservation is managed through a main descriptor &struct kho_vmalloc,
- * which points to a linked list of &struct kho_vmalloc_chunk structures. These
- * chunks contain the physical addresses of the preserved pages, allowing the
- * next kernel to reconstruct the vmalloc area with the same content and layout.
- * Helper macros are also defined for storing and loading pointers within
- * these structures.
- */
-
-/* Helper macro to define a union for a serializable pointer. */
-#define DECLARE_KHOSER_PTR(name, type) \
- union { \
- u64 phys; \
- type ptr; \
- } name
-
-/* Stores the physical address of a serializable pointer. */
-#define KHOSER_STORE_PTR(dest, val) \
- ({ \
- typeof(val) v = val; \
- typecheck(typeof((dest).ptr), v); \
- (dest).phys = virt_to_phys(v); \
- })
-
-/* Loads the stored physical address back to a pointer. */
-#define KHOSER_LOAD_PTR(src) \
- ({ \
- typeof(src) s = src; \
- (typeof((s).ptr))((s).phys ? phys_to_virt((s).phys) : NULL); \
- })
-
-/*
- * This header is embedded at the beginning of each `kho_vmalloc_chunk`
- * and contains a pointer to the next chunk in the linked list,
- * stored as a physical address for handover.
- */
-struct kho_vmalloc_hdr {
- DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *);
-};
-
-#define KHO_VMALLOC_SIZE \
- ((PAGE_SIZE - sizeof(struct kho_vmalloc_hdr)) / \
- sizeof(u64))
-
-/*
- * Each chunk is a single page and is part of a linked list that describes
- * a preserved vmalloc area. It contains the header with the link to the next
- * chunk and a zero terminated array of physical addresses of the pages that
- * make up the preserved vmalloc area.
- */
-struct kho_vmalloc_chunk {
- struct kho_vmalloc_hdr hdr;
- u64 phys[KHO_VMALLOC_SIZE];
-};
-
-static_assert(sizeof(struct kho_vmalloc_chunk) == PAGE_SIZE);
-
-/*
- * Describes a preserved vmalloc memory area, including the
- * total number of pages, allocation flags, page order, and a pointer to the
- * first chunk of physical page addresses.
- */
-struct kho_vmalloc {
- DECLARE_KHOSER_PTR(first, struct kho_vmalloc_chunk *);
- unsigned int total_pages;
- unsigned short flags;
- unsigned short order;
-};
-
#endif /* _LINUX_KHO_ABI_KEXEC_HANDOVER_H */
+
diff --git a/include/linux/kho/abi/memfd.h b/include/linux/kho/abi/memfd.h
index 08b10fea2afc..af310c0c9fdf 100644
--- a/include/linux/kho/abi/memfd.h
+++ b/include/linux/kho/abi/memfd.h
@@ -11,8 +11,9 @@
#ifndef _LINUX_KHO_ABI_MEMFD_H
#define _LINUX_KHO_ABI_MEMFD_H
-#include <linux/types.h>
#include <linux/kho/abi/kexec_handover.h>
+#include <linux/kho/abi/vmalloc.h>
+#include <linux/types.h>
/**
* DOC: memfd Live Update ABI
diff --git a/include/linux/kho/abi/vmalloc.h b/include/linux/kho/abi/vmalloc.h
new file mode 100644
index 000000000000..87650e1dd774
--- /dev/null
+++ b/include/linux/kho/abi/vmalloc.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2025 Microsoft Corporation, Mike Rapoport <rppt at kernel.org>
+ * Copyright (C) 2025 Pasha Tatashin <pasha.tatashin at soleen.com>
+ */
+
+/**
+ * DOC: Kexec Handover ABI for vmalloc Preservation
+ *
+ * The Kexec Handover ABI for preserving vmalloc'ed memory is defined by
+ * a set of structures and helper macros. The layout of these structures is a
+ * stable contract between kernels and is versioned by the KHO_FDT_COMPATIBLE
+ * string.
+ *
+ * This interface is a contract. Any modification to the structure fields,
+ * compatible strings, or the layout of the serialization structures defined
+ * here constitutes a breaking change. Such changes require incrementing the
+ * version number in the `KHO_FDT_COMPATIBLE` string to prevent a new kernel
+ * from misinterpreting data from an old kernel.
+ *
+ * Changes are allowed provided the compatibility version is incremented;
+ * however, backward/forward compatibility is only guaranteed for kernels
+ * supporting the same ABI version.
+ *
+ * The preservation is managed through a main descriptor &struct kho_vmalloc,
+ * which points to a linked list of &struct kho_vmalloc_chunk structures. These
+ * chunks contain the physical addresses of the preserved pages, allowing the
+ * next kernel to reconstruct the vmalloc area with the same content and layout.
+ * Helper macros are also defined for storing and loading pointers within
+ * these structures.
+ */
+
+#ifndef _LINUX_KHO_ABI_VMALLOC_H
+#define _LINUX_KHO_ABI_VMALLOC_H
+
+#include <linux/types.h>
+#include <asm/page.h>
+
+/* Helper macro to define a union for a serializable pointer. */
+#define DECLARE_KHOSER_PTR(name, type) \
+ union { \
+ u64 phys; \
+ type ptr; \
+ } name
+
+/* Stores the physical address of a serializable pointer. */
+#define KHOSER_STORE_PTR(dest, val) \
+ ({ \
+ typeof(val) v = val; \
+ typecheck(typeof((dest).ptr), v); \
+ (dest).phys = virt_to_phys(v); \
+ })
+
+/* Loads the stored physical address back to a pointer. */
+#define KHOSER_LOAD_PTR(src) \
+ ({ \
+ typeof(src) s = src; \
+ (typeof((s).ptr))((s).phys ? phys_to_virt((s).phys) : NULL); \
+ })
+
+/*
+ * This header is embedded at the beginning of each `kho_vmalloc_chunk`
+ * and contains a pointer to the next chunk in the linked list,
+ * stored as a physical address for handover.
+ */
+struct kho_vmalloc_hdr {
+ DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *);
+};
+
+#define KHO_VMALLOC_SIZE \
+ ((PAGE_SIZE - sizeof(struct kho_vmalloc_hdr)) / \
+ sizeof(u64))
+
+/*
+ * Each chunk is a single page and is part of a linked list that describes
+ * a preserved vmalloc area. It contains the header with the link to the next
+ * chunk and a zero terminated array of physical addresses of the pages that
+ * make up the preserved vmalloc area.
+ */
+struct kho_vmalloc_chunk {
+ struct kho_vmalloc_hdr hdr;
+ u64 phys[KHO_VMALLOC_SIZE];
+};
+
+static_assert(sizeof(struct kho_vmalloc_chunk) == PAGE_SIZE);
+
+/*
+ * Describes a preserved vmalloc memory area, including the
+ * total number of pages, allocation flags, page order, and a pointer to the
+ * first chunk of physical page addresses.
+ */
+struct kho_vmalloc {
+ DECLARE_KHOSER_PTR(first, struct kho_vmalloc_chunk *);
+ unsigned int total_pages;
+ unsigned short flags;
+ unsigned short order;
+};
+
+#endif /* _LINUX_KHO_ABI_VMALLOC_H */
diff --git a/include/linux/kho/vmalloc.h b/include/linux/kho/vmalloc.h
new file mode 100644
index 000000000000..2d1b5d282a93
--- /dev/null
+++ b/include/linux/kho/vmalloc.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_KHO_VMALLOC_H
+#define _LINUX_KHO_VMALLOC_H
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/kho/abi/vmalloc.h>
+
+struct page;
+
+#ifdef CONFIG_KEXEC_HANDOVER
+
+int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation);
+void kho_unpreserve_vmalloc(struct kho_vmalloc *preservation);
+void *kho_restore_vmalloc(const struct kho_vmalloc *preservation);
+
+#else /* CONFIG_KEXEC_HANDOVER */
+
+static inline int kho_preserve_vmalloc(void *ptr,
+ struct kho_vmalloc *preservation)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) { }
+
+static inline void *kho_restore_vmalloc(const struct kho_vmalloc *preservation)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_KEXEC_HANDOVER */
+
+#endif /* _LINUX_KHO_VMALLOC_H */
--
2.53.0
More information about the kexec
mailing list