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 <[email protected]> --- 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 <[email protected]> + * Copyright (C) 2025 Pasha Tatashin <[email protected]> + */ + +/** + * 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

