Skip to content

Commit

Permalink
remoteproc: qcom_q6v5_mss: map/unmap mpss segments before/after use
Browse files Browse the repository at this point in the history
The application processor accessing the mpss region when the Q6 modem is
running will lead to an XPU violation. Fix this by un-mapping the mpss
segments post copy during mpss authentication and coredumps.

Tested-by: Evan Green <evgreen@chromium.org>
Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
Link: https://lore.kernel.org/r/20200415071619.6052-1-sibis@codeaurora.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
  • Loading branch information
Sibi Sankar authored and Bjorn Andersson committed May 12, 2020
1 parent a9fdc79 commit be050a3
Showing 1 changed file with 20 additions and 11 deletions.
31 changes: 20 additions & 11 deletions drivers/remoteproc/qcom_q6v5_mss.c
Original file line number Diff line number Diff line change
@@ -1116,7 +1116,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
goto release_firmware;
}

ptr = qproc->mpss_region + offset;
ptr = ioremap_wc(qproc->mpss_phys + offset, phdr->p_memsz);
if (!ptr) {
dev_err(qproc->dev,
"unable to map memory region: %pa+%zx-%x\n",
&qproc->mpss_phys, offset, phdr->p_memsz);
goto release_firmware;
}

if (phdr->p_filesz && phdr->p_offset < fw->size) {
/* Firmware is large enough to be non-split */
@@ -1125,6 +1131,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
"failed to load segment %d from truncated file %s\n",
i, fw_name);
ret = -EINVAL;
iounmap(ptr);
goto release_firmware;
}

@@ -1135,6 +1142,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
ret = request_firmware(&seg_fw, fw_name, qproc->dev);
if (ret) {
dev_err(qproc->dev, "failed to load %s\n", fw_name);
iounmap(ptr);
goto release_firmware;
}

@@ -1147,6 +1155,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
memset(ptr + phdr->p_filesz, 0,
phdr->p_memsz - phdr->p_filesz);
}
iounmap(ptr);
size += phdr->p_memsz;

code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
@@ -1196,7 +1205,8 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
int ret = 0;
struct q6v5 *qproc = rproc->priv;
unsigned long mask = BIT((unsigned long)segment->priv);
void *ptr = rproc_da_to_va(rproc, segment->da, segment->size);
int offset = segment->da - qproc->mpss_reloc;
void *ptr = NULL;

/* Unlock mba before copying segments */
if (!qproc->dump_mba_loaded) {
@@ -1210,10 +1220,15 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
}
}

if (!ptr || ret)
memset(dest, 0xff, segment->size);
else
if (!ret)
ptr = ioremap_wc(qproc->mpss_phys + offset, segment->size);

if (ptr) {
memcpy(dest, ptr, segment->size);
iounmap(ptr);
} else {
memset(dest, 0xff, segment->size);
}

qproc->dump_segment_mask |= mask;

@@ -1548,12 +1563,6 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)

qproc->mpss_phys = qproc->mpss_reloc = r.start;
qproc->mpss_size = resource_size(&r);
qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size);
if (!qproc->mpss_region) {
dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
&r.start, qproc->mpss_size);
return -EBUSY;
}

return 0;
}

0 comments on commit be050a3

Please sign in to comment.