]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
kho: relocate vmalloc preservation structure to KHO ABI header
authorJason Miu <jasonmiu@google.com>
Mon, 5 Jan 2026 16:58:38 +0000 (18:58 +0200)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 27 Jan 2026 03:07:12 +0000 (19:07 -0800)
The `struct kho_vmalloc` defines the in-memory layout for preserving
vmalloc regions across kexec.  This layout is a contract between kernels
and part of the KHO ABI.

To reflect this relationship, the related structs and helper macros are
relocated to the ABI header, `include/linux/kho/abi/kexec_handover.h`.
This move places the structure's definition under the protection of the
KHO_FDT_COMPATIBLE version string.

The structure and its components are now also documented within the ABI
header to describe the contract and prevent ABI breaks.

[rppt@kernel.org: update comment, per Pratyush]
Link: https://lkml.kernel.org/r/aW_Mqp6HcqLwQImS@kernel.org
Link: https://lkml.kernel.org/r/20260105165839.285270-6-rppt@kernel.org
Signed-off-by: Jason Miu <jasonmiu@google.com>
Co-developed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: Alexander Graf <graf@amazon.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Documentation/core-api/kho/abi.rst
include/linux/kexec_handover.h
include/linux/kho/abi/kexec_handover.h
include/linux/kho/abi/memfd.h
kernel/liveupdate/kexec_handover.c
lib/test_kho.c

index a1ee0f481727888c9b33b3a39dd8e27999b658aa..1d9916adee233dcd33611000f47967665e183e40 100644 (file)
@@ -10,6 +10,12 @@ Core Kexec Handover ABI
 .. kernel-doc:: include/linux/kho/abi/kexec_handover.h
    :doc: Kexec Handover ABI
 
+vmalloc preservation ABI
+========================
+
+.. kernel-doc:: include/linux/kho/abi/kexec_handover.h
+   :doc: Kexec Handover ABI for vmalloc Preservation
+
 See Also
 ========
 
index 5f7b9de97e8d38a8653ce835bb7d1aa1297732dc..a56ff3ffaf176d563af00e66ed45dfc0f5e6edc3 100644 (file)
@@ -11,34 +11,11 @@ struct kho_scratch {
        phys_addr_t size;
 };
 
+struct kho_vmalloc;
+
 struct folio;
 struct page;
 
-#define DECLARE_KHOSER_PTR(name, type) \
-       union {                        \
-               phys_addr_t phys;      \
-               type ptr;              \
-       } name
-#define KHOSER_STORE_PTR(dest, val)               \
-       ({                                        \
-               typeof(val) v = val;              \
-               typecheck(typeof((dest).ptr), v); \
-               (dest).phys = virt_to_phys(v);    \
-       })
-#define KHOSER_LOAD_PTR(src)                                                 \
-       ({                                                                   \
-               typeof(src) s = src;                                         \
-               (typeof((s).ptr))((s).phys ? phys_to_virt((s).phys) : NULL); \
-       })
-
-struct kho_vmalloc_chunk;
-struct kho_vmalloc {
-       DECLARE_KHOSER_PTR(first, struct kho_vmalloc_chunk *);
-       unsigned int total_pages;
-       unsigned short flags;
-       unsigned short order;
-};
-
 #ifdef CONFIG_KEXEC_HANDOVER
 bool kho_is_enabled(void);
 bool is_kho_boot(void);
index af9fa8c134c737d8e667279f69e7e0a4b6343a85..2201a0d2c159a2d10ac0c32552ff4686b9bb6346 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef _LINUX_KHO_ABI_KEXEC_HANDOVER_H
 #define _LINUX_KHO_ABI_KEXEC_HANDOVER_H
 
+#include <linux/types.h>
+
 /**
  * DOC: Kexec Handover ABI
  *
 /* The FDT property for sub-FDTs. */
 #define KHO_FDT_SUB_TREE_PROP_NAME "fdt"
 
+/**
+ * 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 */
index c211c31334a36b80f4706adc5ca83151a9ca9491..68cb6303b846eb2a4728695b157f60f9e17f99bf 100644 (file)
@@ -12,7 +12,7 @@
 #define _LINUX_KHO_ABI_MEMFD_H
 
 #include <linux/types.h>
-#include <linux/kexec_handover.h>
+#include <linux/kho/abi/kexec_handover.h>
 
 /**
  * DOC: memfd Live Update ABI
index 8f57d6e040afb5fe66499954c511e32b242fab88..66fcdda0ebdcc610531927adc4489a827688c1ea 100644 (file)
@@ -876,21 +876,6 @@ void kho_unpreserve_pages(struct page *page, unsigned int nr_pages)
 }
 EXPORT_SYMBOL_GPL(kho_unpreserve_pages);
 
-struct kho_vmalloc_hdr {
-       DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *);
-};
-
-#define KHO_VMALLOC_SIZE                               \
-       ((PAGE_SIZE - sizeof(struct kho_vmalloc_hdr)) / \
-        sizeof(phys_addr_t))
-
-struct kho_vmalloc_chunk {
-       struct kho_vmalloc_hdr hdr;
-       phys_addr_t phys[KHO_VMALLOC_SIZE];
-};
-
-static_assert(sizeof(struct kho_vmalloc_chunk) == PAGE_SIZE);
-
 /* vmalloc flags KHO supports */
 #define KHO_VMALLOC_SUPPORTED_FLAGS    (VM_ALLOC | VM_ALLOW_HUGE_VMAP)
 
index 47de5628079557195246e1d261a20e3fca9a5a26..3431daca69689ac2a5bfb9c7baff6ae9067ced25 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/printk.h>
 #include <linux/vmalloc.h>
 #include <linux/kexec_handover.h>
+#include <linux/kho/abi/kexec_handover.h>
 
 #include <net/checksum.h>