From: Lance Yang <[email protected]>
On Fri, 14 Nov 2025 13:59:52 -0500, Pasha Tatashin wrote: > Currently, clients of KHO must manually allocate memory (e.g., via > alloc_pages), calculate the page order, and explicitly call > kho_preserve_folio(). Similarly, cleanup requires separate calls to > unpreserve and free the memory. > > Introduce a high-level API to streamline this common pattern: > > - kho_alloc_preserve(size): Allocates physically contiguous, zeroed > memory and immediately marks it for preservation. > - kho_unpreserve_free(ptr): Unpreserves and frees the memory > in the current kernel. > - kho_restore_free(ptr): Restores the struct page state of > preserved memory in the new kernel and immediately frees it to the > page allocator. > > Signed-off-by: Pasha Tatashin <[email protected]> > Reviewed-by: Mike Rapoport (Microsoft) <[email protected]> > --- > include/linux/kexec_handover.h | 22 +++++--- > kernel/liveupdate/kexec_handover.c | 87 ++++++++++++++++++++++++++++++ > 2 files changed, 102 insertions(+), 7 deletions(-) > > diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h > index 80ece4232617..38a9487a1a00 100644 > --- a/include/linux/kexec_handover.h > +++ b/include/linux/kexec_handover.h > @@ -2,8 +2,9 @@ > #ifndef LINUX_KEXEC_HANDOVER_H > #define LINUX_KEXEC_HANDOVER_H > > -#include <linux/types.h> > +#include <linux/err.h> > #include <linux/errno.h> > +#include <linux/types.h> > > struct kho_scratch { > phys_addr_t addr; > @@ -48,6 +49,9 @@ 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); > +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 int nr_pages); > void *kho_restore_vmalloc(const struct kho_vmalloc *preservation); > @@ -101,6 +105,14 @@ static inline int kho_unpreserve_vmalloc(struct > kho_vmalloc *preservation) > return -EOPNOTSUPP; > } > > +void *kho_alloc_preserve(size_t size) > +{ > + return ERR_PTR(-EOPNOTSUPP); > +} > + > +void kho_unpreserve_free(void *mem) { } > +void kho_restore_free(void *mem) { } The compile is unhapply here when CONFIG_KEXEC_HANDOVER is not set ... ``` ld: arch/x86/realmode/rm/video-mode.o: in function `kho_alloc_preserve': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: multiple definition of `kho_alloc_preserve'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: first defined here ld: arch/x86/realmode/rm/video-mode.o: in function `kho_unpreserve_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: multiple definition of `kho_unpreserve_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: first defined here ld: arch/x86/realmode/rm/video-mode.o: in function `kho_restore_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: multiple definition of `kho_restore_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: first defined here ld: arch/x86/realmode/rm/regs.o: in function `kho_alloc_preserve': /home/runner/work/mm-test-robot/mm-test-robot/linux/arch/x86/realmode/rm/regs.c:102: multiple definition of `kho_alloc_preserve'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: first defined here ld: arch/x86/realmode/rm/regs.o: in function `kho_unpreserve_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/arch/x86/realmode/rm/regs.c:104: multiple definition of `kho_unpreserve_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: first defined here ld: arch/x86/realmode/rm/regs.o: in function `kho_restore_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/arch/x86/realmode/rm/regs.c:105: multiple definition of `kho_restore_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: first defined here ld: arch/x86/realmode/rm/video-vga.o: in function `kho_alloc_preserve': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: multiple definition of `kho_alloc_preserve'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: first defined here ld: arch/x86/realmode/rm/video-vga.o: in function `kho_unpreserve_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: multiple definition of `kho_unpreserve_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: first defined here ld: arch/x86/realmode/rm/video-vga.o: in function `kho_restore_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: multiple definition of `kho_restore_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: first defined here ld: arch/x86/realmode/rm/video-vesa.o: in function `kho_alloc_preserve': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: multiple definition of `kho_alloc_preserve'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: first defined here ld: arch/x86/realmode/rm/video-vesa.o: in function `kho_unpreserve_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: multiple definition of `kho_unpreserve_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: first defined here ld: arch/x86/realmode/rm/video-vesa.o: in function `kho_restore_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: multiple definition of `kho_restore_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: first defined here ld: arch/x86/realmode/rm/video-bios.o: in function `kho_alloc_preserve': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: multiple definition of `kho_alloc_preserve'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:102: first defined here ld: arch/x86/realmode/rm/video-bios.o: in function `kho_unpreserve_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: multiple definition of `kho_unpreserve_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:104: first defined here ld: arch/x86/realmode/rm/video-bios.o: in function `kho_restore_free': /home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: multiple definition of `kho_restore_free'; arch/x86/realmode/rm/wakemain.o:/home/runner/work/mm-test-robot/mm-test-robot/linux/./include/linux/kexec_handover.h:105: first defined here make[5]: *** [arch/x86/realmode/rm/Makefile:49: arch/x86/realmode/rm/realmode.elf] Error 1 make[4]: *** [arch/x86/realmode/Makefile:22: arch/x86/realmode/rm/realmode.bin] Error 2 make[3]: *** [scripts/Makefile.build:556: arch/x86/realmode] Error 2 ``` Perhaps these stubs should be declared as static inline? That should make the compiler happy and resolve the linking errors :) ----8<---- diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 6dd0dcdf0ec1..5f7b9de97e8d 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -96,13 +96,13 @@ static inline int kho_preserve_vmalloc(void *ptr, static inline void kho_unpreserve_vmalloc(struct kho_vmalloc *preservation) { } -void *kho_alloc_preserve(size_t size) +static inline void *kho_alloc_preserve(size_t size) { return ERR_PTR(-EOPNOTSUPP); } -void kho_unpreserve_free(void *mem) { } -void kho_restore_free(void *mem) { } +static inline void kho_unpreserve_free(void *mem) { } +static inline void kho_restore_free(void *mem) { } static inline struct folio *kho_restore_folio(phys_addr_t phys) { --- [...] Cheers, Lance
