mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-21 15:43:21 +02:00
85e4139282
kho_add_subtree() accepts a size parameter but only forwards it to debugfs. The size is not persisted in the KHO FDT, so it is lost across kexec. This makes it impossible for the incoming kernel to determine the blob size without understanding the blob format. Store the blob size as a "blob-size" property in the KHO FDT alongside the "preserved-data" physical address. This allows the receiving kernel to recover the size for any blob regardless of format. Also extend kho_retrieve_subtree() with an optional size output parameter so callers can learn the blob size without needing to understand the blob format. Update all callers to pass NULL for the new parameter. Link: https://lore.kernel.org/20260316-kho-v9-3-ed6dcd951988@debian.org Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Pratyush Yadav <pratyush@kernel.org> Cc: Alexander Graf <graf@amazon.com> Cc: David Hildenbrand <david@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: "Liam R. Howlett" <Liam.Howlett@oracle.com> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Pasha Tatashin <pasha.tatashin@soleen.com> Cc: SeongJae Park <sj@kernel.org> Cc: Shuah Khan <skhan@linuxfoundation.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
122 lines
3.0 KiB
C
122 lines
3.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef LINUX_KEXEC_HANDOVER_H
|
|
#define LINUX_KEXEC_HANDOVER_H
|
|
|
|
#include <linux/err.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/types.h>
|
|
|
|
struct kho_scratch {
|
|
phys_addr_t addr;
|
|
phys_addr_t size;
|
|
};
|
|
|
|
struct kho_vmalloc;
|
|
|
|
struct folio;
|
|
struct page;
|
|
|
|
#ifdef CONFIG_KEXEC_HANDOVER
|
|
bool kho_is_enabled(void);
|
|
bool is_kho_boot(void);
|
|
|
|
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);
|
|
|
|
void kho_memory_init(void);
|
|
|
|
void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys,
|
|
u64 scratch_len);
|
|
#else
|
|
static inline bool kho_is_enabled(void)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline bool is_kho_boot(void)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline int kho_preserve_folio(struct folio *folio)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline void kho_unpreserve_folio(struct folio *folio) { }
|
|
|
|
static inline int kho_preserve_pages(struct page *page, unsigned int nr_pages)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline struct page *kho_restore_pages(phys_addr_t phys,
|
|
unsigned int nr_pages)
|
|
{
|
|
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;
|
|
}
|
|
|
|
static inline void kho_remove_subtree(void *blob) { }
|
|
|
|
static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys,
|
|
size_t *size)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline void kho_memory_init(void) { }
|
|
|
|
static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
|
|
phys_addr_t scratch_phys, u64 scratch_len)
|
|
{
|
|
}
|
|
#endif /* CONFIG_KEXEC_HANDOVER */
|
|
|
|
#endif /* LINUX_KEXEC_HANDOVER_H */
|