Skip to content

Commit

Permalink
kexec: implementation of new syscall kexec_file_load
Browse files Browse the repository at this point in the history
Previous patch provided the interface definition and this patch prvides
implementation of new syscall.

Previously segment list was prepared in user space.  Now user space just
passes kernel fd, initrd fd and command line and kernel will create a
segment list internally.

This patch contains generic part of the code.  Actual segment preparation
and loading is done by arch and image specific loader.  Which comes in
next patch.

[[email protected]: coding-style fixes]
Signed-off-by: Vivek Goyal <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Michael Kerrisk <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Eric Biederman <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Dave Young <[email protected]>
Cc: WANG Chao <[email protected]>
Cc: Baoquan He <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
rhvgoyal authored and torvalds committed Aug 8, 2014
1 parent f089568 commit cb10525
Show file tree
Hide file tree
Showing 4 changed files with 587 additions and 5 deletions.
45 changes: 45 additions & 0 deletions arch/x86/kernel/machine_kexec_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#include <asm/mmu_context.h>
#include <asm/debugreg.h>

static struct kexec_file_ops *kexec_file_loaders[] = {
NULL,
};

static void free_transition_pgtable(struct kimage *image)
{
free_page((unsigned long)image->arch.pud);
Expand Down Expand Up @@ -283,3 +287,44 @@ void arch_crash_save_vmcoreinfo(void)
(unsigned long)&_text - __START_KERNEL);
}

/* arch-dependent functionality related to kexec file-based syscall */

int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
unsigned long buf_len)
{
int i, ret = -ENOEXEC;
struct kexec_file_ops *fops;

for (i = 0; i < ARRAY_SIZE(kexec_file_loaders); i++) {
fops = kexec_file_loaders[i];
if (!fops || !fops->probe)
continue;

ret = fops->probe(buf, buf_len);
if (!ret) {
image->fops = fops;
return ret;
}
}

return ret;
}

void *arch_kexec_kernel_image_load(struct kimage *image)
{
if (!image->fops || !image->fops->load)
return ERR_PTR(-ENOEXEC);

return image->fops->load(image, image->kernel_buf,
image->kernel_buf_len, image->initrd_buf,
image->initrd_buf_len, image->cmdline_buf,
image->cmdline_buf_len);
}

int arch_kimage_file_post_load_cleanup(struct kimage *image)
{
if (!image->fops || !image->fops->cleanup)
return 0;

return image->fops->cleanup(image);
}
53 changes: 53 additions & 0 deletions include/linux/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,57 @@ struct kimage {
#define KEXEC_TYPE_DEFAULT 0
#define KEXEC_TYPE_CRASH 1
unsigned int preserve_context : 1;
/* If set, we are using file mode kexec syscall */
unsigned int file_mode:1;

#ifdef ARCH_HAS_KIMAGE_ARCH
struct kimage_arch arch;
#endif

/* Additional fields for file based kexec syscall */
void *kernel_buf;
unsigned long kernel_buf_len;

void *initrd_buf;
unsigned long initrd_buf_len;

char *cmdline_buf;
unsigned long cmdline_buf_len;

/* File operations provided by image loader */
struct kexec_file_ops *fops;

/* Image loader handling the kernel can store a pointer here */
void *image_loader_data;
};

/*
* Keeps track of buffer parameters as provided by caller for requesting
* memory placement of buffer.
*/
struct kexec_buf {
struct kimage *image;
char *buffer;
unsigned long bufsz;
unsigned long memsz;
unsigned long buf_align;
unsigned long buf_min;
unsigned long buf_max;
bool top_down; /* allocate from top of memory hole */
};

typedef int (kexec_probe_t)(const char *kernel_buf, unsigned long kernel_size);
typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf,
unsigned long kernel_len, char *initrd,
unsigned long initrd_len, char *cmdline,
unsigned long cmdline_len);
typedef int (kexec_cleanup_t)(struct kimage *image);

struct kexec_file_ops {
kexec_probe_t *probe;
kexec_load_t *load;
kexec_cleanup_t *cleanup;
};

/* kexec interface functions */
extern void machine_kexec(struct kimage *image);
Expand All @@ -138,6 +182,11 @@ extern asmlinkage long sys_kexec_load(unsigned long entry,
struct kexec_segment __user *segments,
unsigned long flags);
extern int kernel_kexec(void);
extern int kexec_add_buffer(struct kimage *image, char *buffer,
unsigned long bufsz, unsigned long memsz,
unsigned long buf_align, unsigned long buf_min,
unsigned long buf_max, bool top_down,
unsigned long *load_addr);
extern struct page *kimage_alloc_control_pages(struct kimage *image,
unsigned int order);
extern void crash_kexec(struct pt_regs *);
Expand Down Expand Up @@ -188,6 +237,10 @@ extern int kexec_load_disabled;
#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT)
#endif

/* List of defined/legal kexec file flags */
#define KEXEC_FILE_FLAGS (KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
KEXEC_FILE_NO_INITRAMFS)

#define VMCOREINFO_BYTES (4096)
#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
Expand Down
11 changes: 11 additions & 0 deletions include/uapi/linux/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
#define KEXEC_PRESERVE_CONTEXT 0x00000002
#define KEXEC_ARCH_MASK 0xffff0000

/*
* Kexec file load interface flags.
* KEXEC_FILE_UNLOAD : Unload already loaded kexec/kdump image.
* KEXEC_FILE_ON_CRASH : Load/unload operation belongs to kdump image.
* KEXEC_FILE_NO_INITRAMFS : No initramfs is being loaded. Ignore the initrd
* fd field.
*/
#define KEXEC_FILE_UNLOAD 0x00000001
#define KEXEC_FILE_ON_CRASH 0x00000002
#define KEXEC_FILE_NO_INITRAMFS 0x00000004

/* These values match the ELF architecture values.
* Unless there is a good reason that should continue to be the case.
*/
Expand Down
Loading

0 comments on commit cb10525

Please sign in to comment.