diff options
author | Philipp Rudo <prudo@linux.vnet.ibm.com> | 2017-08-30 14:03:38 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-04-16 09:10:22 +0200 |
commit | e49bb0a27fa3c6ec45cc13e2102a6ec13c4ae697 (patch) | |
tree | d4365a12b7eb3e8cf8bd811c4075771ec2e20320 /arch/s390/kernel/machine_kexec_file.c | |
parent | 71406883fd35794d573b3085433c41d0a3bf6c21 (diff) | |
download | linux-stable-e49bb0a27fa3c6ec45cc13e2102a6ec13c4ae697.tar.gz linux-stable-e49bb0a27fa3c6ec45cc13e2102a6ec13c4ae697.tar.bz2 linux-stable-e49bb0a27fa3c6ec45cc13e2102a6ec13c4ae697.zip |
s390/kexec_file: Add image loader
Add an image loader for kexec_file_load. For simplicity first skip crash
support. The functions defined in machine_kexec_file will later be shared
with the ELF loader.
Signed-off-by: Philipp Rudo <prudo@linux.vnet.ibm.com>
Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/machine_kexec_file.c')
-rw-r--r-- | arch/s390/kernel/machine_kexec_file.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index d9b4f9d23e9f..2a2ceece77b0 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -12,9 +12,84 @@ #include <asm/setup.h> const struct kexec_file_ops * const kexec_file_loaders[] = { + &s390_kexec_image_ops, NULL, }; +int *kexec_file_update_kernel(struct kimage *image, + struct s390_load_data *data) +{ + unsigned long *loc; + + if (image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE) + return ERR_PTR(-EINVAL); + + if (image->cmdline_buf_len) + memcpy(data->kernel_buf + COMMAND_LINE_OFFSET, + image->cmdline_buf, image->cmdline_buf_len); + + if (image->initrd_buf) { + loc = (unsigned long *)(data->kernel_buf + INITRD_START_OFFSET); + *loc = data->initrd_load_addr; + + loc = (unsigned long *)(data->kernel_buf + INITRD_SIZE_OFFSET); + *loc = image->initrd_buf_len; + } + + return NULL; +} + +static int kexec_file_update_purgatory(struct kimage *image) +{ + u64 entry, type; + int ret; + + entry = STARTUP_NORMAL_OFFSET; + ret = kexec_purgatory_get_set_symbol(image, "kernel_entry", &entry, + sizeof(entry), false); + return ret; +} + +int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data) +{ + struct kexec_buf buf; + int ret; + + buf.image = image; + + data->memsz = ALIGN(data->memsz, PAGE_SIZE); + buf.mem = data->memsz; + + ret = kexec_load_purgatory(image, &buf); + if (ret) + return ret; + + ret = kexec_file_update_purgatory(image); + return ret; +} + +int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data, + char *initrd, unsigned long initrd_len) +{ + struct kexec_buf buf; + int ret; + + buf.image = image; + + buf.buffer = initrd; + buf.bufsz = initrd_len; + + data->memsz = ALIGN(data->memsz, PAGE_SIZE); + buf.mem = data->memsz; + buf.memsz = buf.bufsz; + + data->initrd_load_addr = buf.mem; + data->memsz += buf.memsz; + + ret = kexec_add_buffer(&buf); + return ret; +} + /* * The kernel is loaded to a fixed location. Turn off kexec_locate_mem_hole * and provide kbuf->mem by hand. |