s390/kexec_file: Unify loader code
authorPhilipp Rudo <prudo@linux.ibm.com>
Thu, 7 Mar 2019 11:48:03 +0000 (12:48 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 29 Apr 2019 08:43:59 +0000 (10:43 +0200)
s390_image_load and s390_elf_load have the same code to load the different
components. Combine this functionality in one shared function.

While at it move kexec_file_update_kernel into the new function as well.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/kexec.h
arch/s390/kernel/kexec_elf.c
arch/s390/kernel/kexec_image.c
arch/s390/kernel/machine_kexec_file.c

index 08dc2b7..a38a57e 100644 (file)
@@ -59,13 +59,9 @@ struct s390_load_data {
        size_t memsz;
 };
 
-int kexec_file_add_purgatory(struct kimage *image,
-                            struct s390_load_data *data);
-int kexec_file_add_initrd(struct kimage *image,
-                         struct s390_load_data *data,
-                         char *initrd, unsigned long initrd_len);
-int *kexec_file_update_kernel(struct kimage *iamge,
-                             struct s390_load_data *data);
+void *kexec_file_add_components(struct kimage *image,
+                               int (*add_kernel)(struct kimage *image,
+                                                 struct s390_load_data *data));
 
 extern const struct kexec_file_ops s390_kexec_image_ops;
 extern const struct kexec_file_ops s390_kexec_elf_ops;
index 1cdf907..c74ff6b 100644 (file)
 #include <linux/kexec.h>
 #include <asm/setup.h>
 
-static int kexec_file_add_elf_kernel(struct kimage *image,
-                                    struct s390_load_data *data,
-                                    char *kernel, unsigned long kernel_len)
+static int kexec_file_add_kernel_elf(struct kimage *image,
+                                    struct s390_load_data *data)
 {
        struct kexec_buf buf;
        const Elf_Ehdr *ehdr;
        const Elf_Phdr *phdr;
        Elf_Addr entry;
+       void *kernel;
        int i, ret;
 
+       kernel = image->kernel_buf;
        ehdr = (Elf_Ehdr *)kernel;
        buf.image = image;
        if (image->type == KEXEC_TYPE_CRASH)
@@ -62,7 +63,7 @@ static int kexec_file_add_elf_kernel(struct kimage *image,
                data->memsz = ALIGN(data->memsz, phdr->p_align) + buf.memsz;
        }
 
-       return 0;
+       return data->memsz ? 0 : -EINVAL;
 }
 
 static void *s390_elf_load(struct kimage *image,
@@ -70,11 +71,10 @@ static void *s390_elf_load(struct kimage *image,
                           char *initrd, unsigned long initrd_len,
                           char *cmdline, unsigned long cmdline_len)
 {
-       struct s390_load_data data = {0};
        const Elf_Ehdr *ehdr;
        const Elf_Phdr *phdr;
        size_t size;
-       int i, ret;
+       int i;
 
        /* image->fobs->probe already checked for valid ELF magic number. */
        ehdr = (Elf_Ehdr *)kernel;
@@ -107,24 +107,7 @@ static void *s390_elf_load(struct kimage *image,
        if (size > kernel_len)
                return ERR_PTR(-EINVAL);
 
-       ret = kexec_file_add_elf_kernel(image, &data, kernel, kernel_len);
-       if (ret)
-               return ERR_PTR(ret);
-
-       if (!data.memsz)
-               return ERR_PTR(-EINVAL);
-
-       if (initrd) {
-               ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
-               if (ret)
-                       return ERR_PTR(ret);
-       }
-
-       ret = kexec_file_add_purgatory(image, &data);
-       if (ret)
-               return ERR_PTR(ret);
-
-       return kexec_file_update_kernel(image, &data);
+       return kexec_file_add_components(image, kexec_file_add_kernel_elf);
 }
 
 static int s390_elf_probe(const char *buf, unsigned long len)
index d9025ad..d7e65ee 100644 (file)
 #include <linux/kexec.h>
 #include <asm/setup.h>
 
-static int kexec_file_add_image_kernel(struct kimage *image,
-                                      struct s390_load_data *data,
-                                      char *kernel, unsigned long kernel_len)
+static int kexec_file_add_kernel_image(struct kimage *image,
+                                      struct s390_load_data *data)
 {
        struct kexec_buf buf;
-       int ret;
 
        buf.image = image;
 
-       buf.buffer = kernel + STARTUP_NORMAL_OFFSET;
-       buf.bufsz = kernel_len - STARTUP_NORMAL_OFFSET;
+       buf.buffer = image->kernel_buf + STARTUP_NORMAL_OFFSET;
+       buf.bufsz = image->kernel_buf_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);
-
-       data->kernel_buf = kernel;
-       data->parm = (void *)kernel + PARMAREA;
+       data->kernel_buf = image->kernel_buf;
+       data->parm = image->kernel_buf + PARMAREA;
        data->memsz += buf.memsz + STARTUP_NORMAL_OFFSET;
 
-       return ret;
+       return kexec_add_buffer(&buf);
 }
 
 static void *s390_image_load(struct kimage *image,
@@ -43,24 +39,7 @@ static void *s390_image_load(struct kimage *image,
                             char *initrd, unsigned long initrd_len,
                             char *cmdline, unsigned long cmdline_len)
 {
-       struct s390_load_data data = {0};
-       int ret;
-
-       ret = kexec_file_add_image_kernel(image, &data, kernel, kernel_len);
-       if (ret)
-               return ERR_PTR(ret);
-
-       if (initrd) {
-               ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
-               if (ret)
-                       return ERR_PTR(ret);
-       }
-
-       ret = kexec_file_add_purgatory(image, &data);
-       if (ret)
-               return ERR_PTR(ret);
-
-       return kexec_file_update_kernel(image, &data);
+       return kexec_file_add_components(image, kexec_file_add_kernel_image);
 }
 
 static int s390_image_probe(const char *buf, unsigned long len)
index 8a85ecd..08409d6 100644 (file)
@@ -17,25 +17,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
        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);
-
-       memcpy(data->parm->command_line, image->cmdline_buf,
-              image->cmdline_buf_len);
-
-       if (image->type == KEXEC_TYPE_CRASH) {
-               data->parm->oldmem_base = crashk_res.start;
-               data->parm->oldmem_size = crashk_res.end - crashk_res.start + 1;
-       }
-
-       return NULL;
-}
-
 static int kexec_file_update_purgatory(struct kimage *image)
 {
        u64 entry, type;
@@ -78,7 +59,8 @@ static int kexec_file_update_purgatory(struct kimage *image)
        return ret;
 }
 
-int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data)
+static int kexec_file_add_purgatory(struct kimage *image,
+                                   struct s390_load_data *data)
 {
        struct kexec_buf buf;
        int ret;
@@ -98,16 +80,16 @@ int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data)
        return ret;
 }
 
-int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data,
-                         char *initrd, unsigned long initrd_len)
+static int kexec_file_add_initrd(struct kimage *image,
+                                struct s390_load_data *data)
 {
        struct kexec_buf buf;
        int ret;
 
        buf.image = image;
 
-       buf.buffer = initrd;
-       buf.bufsz = initrd_len;
+       buf.buffer = image->initrd_buf;
+       buf.bufsz = image->initrd_buf_len;
 
        data->memsz = ALIGN(data->memsz, PAGE_SIZE);
        buf.mem = data->memsz;
@@ -123,6 +105,40 @@ int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data,
        return ret;
 }
 
+void *kexec_file_add_components(struct kimage *image,
+                               int (*add_kernel)(struct kimage *image,
+                                                 struct s390_load_data *data))
+{
+       struct s390_load_data data = {0};
+       int ret;
+
+       ret = add_kernel(image, &data);
+       if (ret)
+               return ERR_PTR(ret);
+
+       if (image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE)
+               return ERR_PTR(-EINVAL);
+       memcpy(data.parm->command_line, image->cmdline_buf,
+              image->cmdline_buf_len);
+
+       if (image->type == KEXEC_TYPE_CRASH) {
+               data.parm->oldmem_base = crashk_res.start;
+               data.parm->oldmem_size = crashk_res.end - crashk_res.start + 1;
+       }
+
+       if (image->initrd_buf) {
+               ret = kexec_file_add_initrd(image, &data);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
+       ret = kexec_file_add_purgatory(image, &data);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return NULL;
+}
+
 int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
                                     Elf_Shdr *section,
                                     const Elf_Shdr *relsec,