linux/include/linux/kexec.h

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LINUX_KEXEC_H
#define LINUX_KEXEC_H

#define IND_DESTINATION_BIT
#define IND_INDIRECTION_BIT
#define IND_DONE_BIT
#define IND_SOURCE_BIT

#define IND_DESTINATION
#define IND_INDIRECTION
#define IND_DONE
#define IND_SOURCE
#define IND_FLAGS

#if !defined(__ASSEMBLY__)

#include <linux/vmcore_info.h>
#include <linux/crash_reserve.h>
#include <asm/io.h>
#include <linux/range.h>

#include <uapi/linux/kexec.h>
#include <linux/verification.h>

extern note_buf_t __percpu *crash_notes;

#ifdef CONFIG_KEXEC_CORE
#include <linux/list.h>
#include <linux/compat.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/highmem.h>
#include <asm/kexec.h>
#include <linux/crash_core.h>

/* Verify architecture specific macros are defined */

#ifndef KEXEC_SOURCE_MEMORY_LIMIT
#error KEXEC_SOURCE_MEMORY_LIMIT not defined
#endif

#ifndef KEXEC_DESTINATION_MEMORY_LIMIT
#error KEXEC_DESTINATION_MEMORY_LIMIT not defined
#endif

#ifndef KEXEC_CONTROL_MEMORY_LIMIT
#error KEXEC_CONTROL_MEMORY_LIMIT not defined
#endif

#ifndef KEXEC_CONTROL_MEMORY_GFP
#define KEXEC_CONTROL_MEMORY_GFP
#endif

#ifndef KEXEC_CONTROL_PAGE_SIZE
#error KEXEC_CONTROL_PAGE_SIZE not defined
#endif

#ifndef KEXEC_ARCH
#error KEXEC_ARCH not defined
#endif

#ifndef KEXEC_CRASH_CONTROL_MEMORY_LIMIT
#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT
#endif

#ifndef KEXEC_CRASH_MEM_ALIGN
#define KEXEC_CRASH_MEM_ALIGN
#endif

#define KEXEC_CORE_NOTE_NAME

/*
 * This structure is used to hold the arguments that are used when loading
 * kernel binaries.
 */

kimage_entry_t;

struct kexec_segment {};

#ifdef CONFIG_COMPAT
struct compat_kexec_segment {};
#endif

#ifdef CONFIG_KEXEC_FILE
struct purgatory_info {};

struct kimage;

kexec_probe_t;
kexec_load_t;
kexec_cleanup_t;

#ifdef CONFIG_KEXEC_SIG
kexec_verify_sig_t;
#endif

struct kexec_file_ops {};

extern const struct kexec_file_ops * const kexec_file_loaders[];

int kexec_image_probe_default(struct kimage *image, void *buf,
			      unsigned long buf_len);
int kexec_image_post_load_cleanup_default(struct kimage *image);

/*
 * If kexec_buf.mem is set to this value, kexec_locate_mem_hole()
 * will try to allocate free memory. Arch may overwrite it.
 */
#ifndef KEXEC_BUF_MEM_UNKNOWN
#define KEXEC_BUF_MEM_UNKNOWN
#endif

/**
 * struct kexec_buf - parameters for finding a place for a buffer in memory
 * @image:	kexec image in which memory to search.
 * @buffer:	Contents which will be copied to the allocated memory.
 * @bufsz:	Size of @buffer.
 * @mem:	On return will have address of the buffer in memory.
 * @memsz:	Size for the buffer in memory.
 * @buf_align:	Minimum alignment needed.
 * @buf_min:	The buffer can't be placed below this address.
 * @buf_max:	The buffer can't be placed above this address.
 * @top_down:	Allocate from top of memory.
 */
struct kexec_buf {};

int kexec_load_purgatory(struct kimage *image, struct kexec_buf *kbuf);
int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
				   void *buf, unsigned int size,
				   bool get_value);
void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name);

#ifndef arch_kexec_kernel_image_probe
static inline int
arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len)
{}
#endif

#ifndef arch_kimage_file_post_load_cleanup
static inline int arch_kimage_file_post_load_cleanup(struct kimage *image)
{
	return kexec_image_post_load_cleanup_default(image);
}
#endif

#ifdef CONFIG_KEXEC_SIG
#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION
int kexec_kernel_verify_pe_sig(const char *kernel, unsigned long kernel_len);
#endif
#endif

extern int kexec_add_buffer(struct kexec_buf *kbuf);
int kexec_locate_mem_hole(struct kexec_buf *kbuf);

#ifndef arch_kexec_locate_mem_hole
/**
 * arch_kexec_locate_mem_hole - Find free memory to place the segments.
 * @kbuf:                       Parameters for the memory search.
 *
 * On success, kbuf->mem will have the start address of the memory region found.
 *
 * Return: 0 on success, negative errno on error.
 */
static inline int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf)
{}
#endif

#ifndef arch_kexec_apply_relocations_add
/*
 * arch_kexec_apply_relocations_add - apply relocations of type RELA
 * @pi:		Purgatory to be relocated.
 * @section:	Section relocations applying to.
 * @relsec:	Section containing RELAs.
 * @symtab:	Corresponding symtab.
 *
 * Return: 0 on success, negative errno on error.
 */
static inline int
arch_kexec_apply_relocations_add(struct purgatory_info *pi, Elf_Shdr *section,
				 const Elf_Shdr *relsec, const Elf_Shdr *symtab)
{
	pr_err("RELA relocation unsupported.\n");
	return -ENOEXEC;
}
#endif

#ifndef arch_kexec_apply_relocations
/*
 * arch_kexec_apply_relocations - apply relocations of type REL
 * @pi:		Purgatory to be relocated.
 * @section:	Section relocations applying to.
 * @relsec:	Section containing RELs.
 * @symtab:	Corresponding symtab.
 *
 * Return: 0 on success, negative errno on error.
 */
static inline int
arch_kexec_apply_relocations(struct purgatory_info *pi, Elf_Shdr *section,
			     const Elf_Shdr *relsec, const Elf_Shdr *symtab)
{}
#endif
#endif /* CONFIG_KEXEC_FILE */

#ifdef CONFIG_KEXEC_ELF
struct kexec_elf_info {
	/*
	 * Where the ELF binary contents are kept.
	 * Memory managed by the user of the struct.
	 */
	const char *buffer;

	const struct elfhdr *ehdr;
	const struct elf_phdr *proghdrs;
};

int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
			       struct kexec_elf_info *elf_info);

int kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
			 struct kexec_elf_info *elf_info,
			 struct kexec_buf *kbuf,
			 unsigned long *lowest_load_addr);

void kexec_free_elf_info(struct kexec_elf_info *elf_info);
int kexec_elf_probe(const char *buf, unsigned long len);
#endif
struct kimage {};

/* kexec interface functions */
extern void machine_kexec(struct kimage *image);
extern int machine_kexec_prepare(struct kimage *image);
extern void machine_kexec_cleanup(struct kimage *image);
extern int kernel_kexec(void);
extern struct page *kimage_alloc_control_pages(struct kimage *image,
						unsigned int order);

#ifndef machine_kexec_post_load
static inline int machine_kexec_post_load(struct kimage *image) {}
#endif

extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;

bool kexec_load_permitted(int kexec_image_type);

#ifndef kexec_flush_icache_page
#define kexec_flush_icache_page(page)
#endif

/* List of defined/legal kexec flags */
#ifndef CONFIG_KEXEC_JUMP
#define KEXEC_FLAGS
#else
#define KEXEC_FLAGS
#endif

/* List of defined/legal kexec file flags */
#define KEXEC_FILE_FLAGS

/* flag to track if kexec reboot is in progress */
extern bool kexec_in_progress;

#ifndef page_to_boot_pfn
static inline unsigned long page_to_boot_pfn(struct page *page)
{}
#endif

#ifndef boot_pfn_to_page
static inline struct page *boot_pfn_to_page(unsigned long boot_pfn)
{}
#endif

#ifndef phys_to_boot_phys
static inline unsigned long phys_to_boot_phys(phys_addr_t phys)
{}
#endif

#ifndef boot_phys_to_phys
static inline phys_addr_t boot_phys_to_phys(unsigned long boot_phys)
{}
#endif

#ifndef crash_free_reserved_phys_range
static inline void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
{}
#endif

static inline unsigned long virt_to_boot_phys(void *addr)
{}

static inline void *boot_phys_to_virt(unsigned long entry)
{}

#ifndef arch_kexec_post_alloc_pages
static inline int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp) { return 0; }
#endif

#ifndef arch_kexec_pre_free_pages
static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { }
#endif

extern bool kexec_file_dbg_print;

#define kexec_dprintk(fmt, arg...)

#else /* !CONFIG_KEXEC_CORE */
struct pt_regs;
struct task_struct;
static inline void __crash_kexec(struct pt_regs *regs) { }
static inline void crash_kexec(struct pt_regs *regs) { }
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
static inline int kexec_crash_loaded(void) { return 0; }
#define kexec_in_progress
#endif /* CONFIG_KEXEC_CORE */

#ifdef CONFIG_KEXEC_SIG
void set_kexec_sig_enforced(void);
#else
static inline void set_kexec_sig_enforced(void) {}
#endif

#endif /* !defined(__ASSEBMLY__) */

#endif /* LINUX_KEXEC_H */