Re: [PATCH v2 03/13] kho: Introduce high-level memory allocation API

Pasha Tatashin
2025-11-16T14:57:44Z

On Sun, Nov 16, 2025 at 1:49 AM Lance Yang <ioworker0@gmail.com> wrote:
>
> From: Lance Yang <lance.yang@linux.dev>
>
>
> 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 <pasha.tatashin@soleen.com>
> > Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> > ---
> > 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 ...

Thank you, Andrew already applied a fix:
https://lore.kernel.org/all/CA+CK2bBgXDhrHwTVgxrw7YTQ-0=LgW0t66CwPCgG=C85ftz4zw@mail.gmail.com/T/#u

>
> ```
> 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