2019-01-21 07:36:15

by Pi-Hsun Shih

[permalink] [raw]
Subject: [PATCH 1/2] remoteproc: Add __iomem to return of rproc_da_to_va.

The return value of rproc_da_to_va would probably be device memory. Add
__iomem annotation to it.

Signed-off-by: Pi-Hsun Shih <[email protected]>
---
I feel that there might be more things that need to be changed
(especially for the carveouts things). I didn't change them since I
don't know how to test that part. Comments needed.
---
drivers/remoteproc/remoteproc_core.c | 4 ++--
drivers/remoteproc/remoteproc_internal.h | 2 +-
include/linux/remoteproc.h | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 54ec38fc5dca62..7cb8393e1b39f6 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -190,10 +190,10 @@ static phys_addr_t rproc_va_to_pa(void *cpu_addr)
* here the output of the DMA API for the carveouts, which should be more
* correct.
*/
-void *rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+void __iomem *rproc_da_to_va(struct rproc *rproc, u64 da, int len)
{
struct rproc_mem_entry *carveout;
- void *ptr = NULL;
+ void __iomem *ptr = NULL;

if (rproc->ops->da_to_va) {
ptr = rproc->ops->da_to_va(rproc, da, len);
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index f6cad243d7cac9..df7abe049cdef2 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -51,7 +51,7 @@ void rproc_exit_sysfs(void);
void rproc_free_vring(struct rproc_vring *rvring);
int rproc_alloc_vring(struct rproc_vdev *rvdev, int i);

-void *rproc_da_to_va(struct rproc *rproc, u64 da, int len);
+void __iomem *rproc_da_to_va(struct rproc *rproc, u64 da, int len);
int rproc_trigger_recovery(struct rproc *rproc);

int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 68e72f33c705e1..065a68a5e6e577 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -356,7 +356,7 @@ struct rproc_ops {
int (*start)(struct rproc *rproc);
int (*stop)(struct rproc *rproc);
void (*kick)(struct rproc *rproc, int vqid);
- void * (*da_to_va)(struct rproc *rproc, u64 da, int len);
+ void __iomem *(*da_to_va)(struct rproc *rproc, u64 da, int len);
int (*parse_fw)(struct rproc *rproc, const struct firmware *fw);
struct resource_table *(*find_loaded_rsc_table)(
struct rproc *rproc, const struct firmware *fw);
--
2.20.1.321.g9e740568ce-goog



2019-01-21 07:35:44

by Pi-Hsun Shih

[permalink] [raw]
Subject: [PATCH 2/2] remoteproc: elf_loader: Use memset_io instead of memset.

Use memset_io and memcpy_toio instead of memset and memcpy in
rproc_elf_load_segments, since the target ptr may be device memory.

Signed-off-by: Pi-Hsun Shih <[email protected]>
---
This fix issue while trying to load ELF firmware based on
https://lore.kernel.org/patchwork/patch/1033804/, that the memset(...,
0) would use "dc zva" instruction on aarch64, which cause kernel crash
since the target is device memory.
---
drivers/remoteproc/remoteproc_elf_loader.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index b17d72ec8603bc..17f1815757dc54 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -159,7 +159,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
u32 memsz = phdr->p_memsz;
u32 filesz = phdr->p_filesz;
u32 offset = phdr->p_offset;
- void *ptr;
+ void __iomem *ptr;

if (phdr->p_type != PT_LOAD)
continue;
@@ -191,7 +191,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)

/* put the segment where the remote processor expects it */
if (phdr->p_filesz)
- memcpy(ptr, elf_data + phdr->p_offset, filesz);
+ memcpy_toio(ptr, elf_data + phdr->p_offset, filesz);

/*
* Zero out remaining memory for this segment.
@@ -201,7 +201,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
* this.
*/
if (memsz > filesz)
- memset(ptr + filesz, 0, memsz - filesz);
+ memset_io(ptr + filesz, 0, memsz - filesz);
}

return ret;
--
2.20.1.321.g9e740568ce-goog