diff options
author | Philipp Rudo <prudo@linux.vnet.ibm.com> | 2017-09-05 12:55:23 +0300 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-04-16 10:10:22 +0300 |
commit | ee337f5469fd67f22d231e520ec4189ce0589d92 (patch) | |
tree | 7b2d0e72573aaca14b54520ffa2c59fbcfaac81a /arch/s390/kernel | |
parent | e49bb0a27fa3c6ec45cc13e2102a6ec13c4ae697 (diff) | |
download | linux-ee337f5469fd67f22d231e520ec4189ce0589d92.tar.xz |
s390/kexec_file: Add crash support to image loader
Add support to load a crash kernel to the image loader. This requires
extending the purgatory.
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')
-rw-r--r-- | arch/s390/kernel/kexec_image.c | 6 | ||||
-rw-r--r-- | arch/s390/kernel/machine_kexec_file.c | 45 |
2 files changed, 46 insertions, 5 deletions
diff --git a/arch/s390/kernel/kexec_image.c b/arch/s390/kernel/kexec_image.c index 7f5021e6c242..3800852595e8 100644 --- a/arch/s390/kernel/kexec_image.c +++ b/arch/s390/kernel/kexec_image.c @@ -25,6 +25,8 @@ static int kexec_file_add_image_kernel(struct kimage *image, buf.bufsz = kernel_len - STARTUP_NORMAL_OFFSET; buf.mem = STARTUP_NORMAL_OFFSET; + if (image->type == KEXEC_TYPE_CRASH) + buf.mem += crashk_res.start; buf.memsz = buf.bufsz; ret = kexec_add_buffer(&buf); @@ -43,10 +45,6 @@ static void *s390_image_load(struct kimage *image, struct s390_load_data data = {0}; int ret; - /* We don't support crash kernels yet. */ - if (image->type == KEXEC_TYPE_CRASH) - return ERR_PTR(-ENOTSUPP); - ret = kexec_file_add_image_kernel(image, &data, kernel, kernel_len); if (ret) return ERR_PTR(ret); diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index 2a2ceece77b0..75aea2c1d823 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -28,6 +28,14 @@ int *kexec_file_update_kernel(struct kimage *image, memcpy(data->kernel_buf + COMMAND_LINE_OFFSET, image->cmdline_buf, image->cmdline_buf_len); + if (image->type == KEXEC_TYPE_CRASH) { + loc = (unsigned long *)(data->kernel_buf + OLDMEM_BASE_OFFSET); + *loc = crashk_res.start; + + loc = (unsigned long *)(data->kernel_buf + OLDMEM_SIZE_OFFSET); + *loc = crashk_res.end - crashk_res.start + 1; + } + if (image->initrd_buf) { loc = (unsigned long *)(data->kernel_buf + INITRD_START_OFFSET); *loc = data->initrd_load_addr; @@ -44,9 +52,40 @@ static int kexec_file_update_purgatory(struct kimage *image) u64 entry, type; int ret; - entry = STARTUP_NORMAL_OFFSET; + if (image->type == KEXEC_TYPE_CRASH) { + entry = STARTUP_KDUMP_OFFSET; + type = KEXEC_TYPE_CRASH; + } else { + entry = STARTUP_NORMAL_OFFSET; + type = KEXEC_TYPE_DEFAULT; + } + ret = kexec_purgatory_get_set_symbol(image, "kernel_entry", &entry, sizeof(entry), false); + if (ret) + return ret; + + ret = kexec_purgatory_get_set_symbol(image, "kernel_type", &type, + sizeof(type), false); + if (ret) + return ret; + + if (image->type == KEXEC_TYPE_CRASH) { + u64 crash_size; + + ret = kexec_purgatory_get_set_symbol(image, "crash_start", + &crashk_res.start, + sizeof(crashk_res.start), + false); + if (ret) + return ret; + + crash_size = crashk_res.end - crashk_res.start + 1; + ret = kexec_purgatory_get_set_symbol(image, "crash_size", + &crash_size, + sizeof(crash_size), + false); + } return ret; } @@ -59,6 +98,8 @@ int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data) data->memsz = ALIGN(data->memsz, PAGE_SIZE); buf.mem = data->memsz; + if (image->type == KEXEC_TYPE_CRASH) + buf.mem += crashk_res.start; ret = kexec_load_purgatory(image, &buf); if (ret) @@ -81,6 +122,8 @@ int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data, data->memsz = ALIGN(data->memsz, PAGE_SIZE); buf.mem = data->memsz; + if (image->type == KEXEC_TYPE_CRASH) + buf.mem += crashk_res.start; buf.memsz = buf.bufsz; data->initrd_load_addr = buf.mem; |