remoteproc: add rproc_coredump_set_elf_info
authorClement Leger <cleger@kalray.eu>
Fri, 10 Apr 2020 10:24:32 +0000 (12:24 +0200)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Mon, 20 Apr 2020 05:53:02 +0000 (22:53 -0700)
This function allows drivers to correctly setup the coredump output
elf information.

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Clement Leger <cleger@kalray.eu>
Link: https://lore.kernel.org/r/20200410102433.2672-2-cleger@kalray.eu
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/remoteproc/remoteproc_core.c
drivers/remoteproc/remoteproc_elf_loader.c
include/linux/remoteproc.h

index 9899467..d9e6949 100644 (file)
@@ -1565,6 +1565,28 @@ int rproc_coredump_add_custom_segment(struct rproc *rproc,
 }
 EXPORT_SYMBOL(rproc_coredump_add_custom_segment);
 
+/**
+ * rproc_coredump_set_elf_info() - set coredump elf information
+ * @rproc:     handle of a remote processor
+ * @class:     elf class for coredump elf file
+ * @machine:   elf machine for coredump elf file
+ *
+ * Set elf information which will be used for coredump elf file.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int rproc_coredump_set_elf_info(struct rproc *rproc, u8 class, u16 machine)
+{
+       if (class != ELFCLASS64 && class != ELFCLASS32)
+               return -EINVAL;
+
+       rproc->elf_class = class;
+       rproc->elf_machine = machine;
+
+       return 0;
+}
+EXPORT_SYMBOL(rproc_coredump_set_elf_info);
+
 /**
  * rproc_coredump() - perform coredump
  * @rproc:     rproc handle
@@ -1587,6 +1609,11 @@ static void rproc_coredump(struct rproc *rproc)
        if (list_empty(&rproc->dump_segments))
                return;
 
+       if (class == ELFCLASSNONE) {
+               dev_err(&rproc->dev, "Elf class is not set\n");
+               return;
+       }
+
        data_size = elf_size_of_hdr(class);
        list_for_each_entry(segment, &rproc->dump_segments, node) {
                data_size += elf_size_of_phdr(class) + segment->size;
@@ -1605,7 +1632,7 @@ static void rproc_coredump(struct rproc *rproc)
        elf_hdr_init_ident(ehdr, class);
 
        elf_hdr_set_e_type(class, ehdr, ET_CORE);
-       elf_hdr_set_e_machine(class, ehdr, EM_NONE);
+       elf_hdr_set_e_machine(class, ehdr, rproc->elf_machine);
        elf_hdr_set_e_version(class, ehdr, EV_CURRENT);
        elf_hdr_set_e_entry(class, ehdr, rproc->bootaddr);
        elf_hdr_set_e_phoff(class, ehdr, elf_size_of_hdr(class));
@@ -2047,7 +2074,8 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
        rproc->name = name;
        rproc->priv = &rproc[1];
        rproc->auto_boot = true;
-       rproc->elf_class = ELFCLASS32;
+       rproc->elf_class = ELFCLASSNONE;
+       rproc->elf_machine = EM_NONE;
 
        device_initialize(&rproc->dev);
        rproc->dev.parent = dev;
index 16e2c49..4869fb7 100644 (file)
@@ -248,9 +248,6 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
                        memset(ptr + filesz, 0, memsz - filesz);
        }
 
-       if (ret == 0)
-               rproc->elf_class = class;
-
        return ret;
 }
 EXPORT_SYMBOL(rproc_elf_load_segments);
index 9c07d79..0547676 100644 (file)
@@ -518,6 +518,7 @@ struct rproc {
        struct list_head dump_segments;
        int nb_vdev;
        u8 elf_class;
+       u16 elf_machine;
 };
 
 /**
@@ -622,6 +623,7 @@ int rproc_coredump_add_custom_segment(struct rproc *rproc,
                                                     struct rproc_dump_segment *segment,
                                                     void *dest),
                                      void *priv);
+int rproc_coredump_set_elf_info(struct rproc *rproc, u8 class, u16 machine);
 
 static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
 {