mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Previously, KHO required a dedicated kho_abort() function to clean up state before kho_finalize() could be called again. This was necessary to handle complex unwind paths when using notifiers. With the shift to direct memory preservation, the explicit abort step is no longer strictly necessary. Remove kho_abort() and refactor kho_finalize() to handle re-entry. If kho_finalize() is called while KHO is already finalized, it will now automatically clean up the previous memory map and state before generating a new one. This allows the KHO state to be updated/refreshed simply by triggering finalize again. Update debugfs to return -EINVAL if userspace attempts to write 0 to the finalize attribute, as explicit abort is no longer supported. Link: https://lkml.kernel.org/r/20251114190002.3311679-10-pasha.tatashin@soleen.com Suggested-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Pratyush Yadav <pratyush@kernel.org> Cc: Alexander Graf <graf@amazon.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Baoquan He <bhe@redhat.com> Cc: Coiby Xu <coxu@redhat.com> Cc: Dave Vasilevsky <dave@vasilevsky.ca> Cc: Eric Biggers <ebiggers@google.com> Cc: Kees Cook <kees@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
56 lines
1.6 KiB
C
56 lines
1.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef LINUX_KEXEC_HANDOVER_INTERNAL_H
|
|
#define LINUX_KEXEC_HANDOVER_INTERNAL_H
|
|
|
|
#include <linux/kexec_handover.h>
|
|
#include <linux/list.h>
|
|
#include <linux/types.h>
|
|
|
|
#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS
|
|
#include <linux/debugfs.h>
|
|
|
|
struct kho_debugfs {
|
|
struct dentry *dir;
|
|
struct dentry *sub_fdt_dir;
|
|
struct list_head fdt_list;
|
|
};
|
|
|
|
#else
|
|
struct kho_debugfs {};
|
|
#endif
|
|
|
|
extern struct kho_scratch *kho_scratch;
|
|
extern unsigned int kho_scratch_cnt;
|
|
|
|
bool kho_finalized(void);
|
|
int kho_finalize(void);
|
|
|
|
#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS
|
|
int kho_debugfs_init(void);
|
|
void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt);
|
|
int kho_out_debugfs_init(struct kho_debugfs *dbg);
|
|
int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name,
|
|
const void *fdt, bool root);
|
|
void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, void *fdt);
|
|
#else
|
|
static inline int kho_debugfs_init(void) { return 0; }
|
|
static inline void kho_in_debugfs_init(struct kho_debugfs *dbg,
|
|
const void *fdt) { }
|
|
static inline int kho_out_debugfs_init(struct kho_debugfs *dbg) { return 0; }
|
|
static inline int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name,
|
|
const void *fdt, bool root) { return 0; }
|
|
static inline void kho_debugfs_fdt_remove(struct kho_debugfs *dbg,
|
|
void *fdt) { }
|
|
#endif /* CONFIG_KEXEC_HANDOVER_DEBUGFS */
|
|
|
|
#ifdef CONFIG_KEXEC_HANDOVER_DEBUG
|
|
bool kho_scratch_overlap(phys_addr_t phys, size_t size);
|
|
#else
|
|
static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size)
|
|
{
|
|
return false;
|
|
}
|
|
#endif /* CONFIG_KEXEC_HANDOVER_DEBUG */
|
|
|
|
#endif /* LINUX_KEXEC_HANDOVER_INTERNAL_H */
|