#define pr_fmt(fmt) …
#include <linux/capability.h>
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/kexec.h>
#include <linux/memblock.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/fs.h>
#include <linux/ima.h>
#include <crypto/hash.h>
#include <crypto/sha2.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
#include <linux/kernel.h>
#include <linux/kernel_read_file.h>
#include <linux/syscalls.h>
#include <linux/vmalloc.h>
#include "kexec_internal.h"
#ifdef CONFIG_KEXEC_SIG
static bool sig_enforce = … IS_ENABLED(…);
void set_kexec_sig_enforced(void)
{ … }
#endif
static int kexec_calculate_store_digests(struct kimage *image);
#define KEXEC_FILE_SIZE_MAX …
int kexec_image_probe_default(struct kimage *image, void *buf,
unsigned long buf_len)
{ … }
static void *kexec_image_load_default(struct kimage *image)
{ … }
int kexec_image_post_load_cleanup_default(struct kimage *image)
{ … }
void kimage_file_post_load_cleanup(struct kimage *image)
{ … }
#ifdef CONFIG_KEXEC_SIG
#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION
int kexec_kernel_verify_pe_sig(const char *kernel, unsigned long kernel_len)
{ … }
#endif
static int kexec_image_verify_sig(struct kimage *image, void *buf,
unsigned long buf_len)
{ … }
static int
kimage_validate_signature(struct kimage *image)
{ … }
#endif
static int
kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
const char __user *cmdline_ptr,
unsigned long cmdline_len, unsigned flags)
{ … }
static int
kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
int initrd_fd, const char __user *cmdline_ptr,
unsigned long cmdline_len, unsigned long flags)
{ … }
SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
unsigned long, cmdline_len, const char __user *, cmdline_ptr,
unsigned long, flags)
{ … }
static int locate_mem_hole_top_down(unsigned long start, unsigned long end,
struct kexec_buf *kbuf)
{ … }
static int locate_mem_hole_bottom_up(unsigned long start, unsigned long end,
struct kexec_buf *kbuf)
{ … }
static int locate_mem_hole_callback(struct resource *res, void *arg)
{ … }
#ifdef CONFIG_ARCH_KEEP_MEMBLOCK
static int kexec_walk_memblock(struct kexec_buf *kbuf,
int (*func)(struct resource *, void *))
{
int ret = 0;
u64 i;
phys_addr_t mstart, mend;
struct resource res = { };
#ifdef CONFIG_CRASH_DUMP
if (kbuf->image->type == KEXEC_TYPE_CRASH)
return func(&crashk_res, kbuf);
#endif
if (kbuf->top_down) {
for_each_free_mem_range_reverse(i, NUMA_NO_NODE, MEMBLOCK_NONE,
&mstart, &mend, NULL) {
res.start = mstart;
res.end = mend - 1;
ret = func(&res, kbuf);
if (ret)
break;
}
} else {
for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE,
&mstart, &mend, NULL) {
res.start = mstart;
res.end = mend - 1;
ret = func(&res, kbuf);
if (ret)
break;
}
}
return ret;
}
#else
static int kexec_walk_memblock(struct kexec_buf *kbuf,
int (*func)(struct resource *, void *))
{ … }
#endif
static int kexec_walk_resources(struct kexec_buf *kbuf,
int (*func)(struct resource *, void *))
{ … }
int kexec_locate_mem_hole(struct kexec_buf *kbuf)
{ … }
int kexec_add_buffer(struct kexec_buf *kbuf)
{ … }
static int kexec_calculate_store_digests(struct kimage *image)
{ … }
#ifdef CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY
static int kexec_purgatory_setup_kbuf(struct purgatory_info *pi,
struct kexec_buf *kbuf)
{ … }
static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
struct kexec_buf *kbuf)
{ … }
static int kexec_apply_relocations(struct kimage *image)
{ … }
int kexec_load_purgatory(struct kimage *image, struct kexec_buf *kbuf)
{ … }
static const Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
const char *name)
{ … }
void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name)
{ … }
int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
void *buf, unsigned int size, bool get_value)
{ … }
#endif