Skip to content

Commit

Permalink
remoteproc: qcom_q6v5_mss: map/unmap MBA region before/after use
Browse files Browse the repository at this point in the history
The application processor accessing the MBA region after assigning it to
the remote Q6 would lead to an XPU violation. Fix this by un-mapping the
MBA region post firmware copy and MBA text log dumps.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
Link: https://lore.kernel.org/r/1604473422-29639-2-git-send-email-sibis@codeaurora.org
[bjorn: Renamed "ptr" to "mba_region"]
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
  • Loading branch information
Sibi Sankar authored and Bjorn Andersson committed Nov 24, 2020
1 parent 04ff5d1 commit a7ed5e5
Showing 1 changed file with 22 additions and 15 deletions.
37 changes: 22 additions & 15 deletions drivers/remoteproc/qcom_q6v5_mss.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ struct q6v5 {
size_t total_dump_size;

phys_addr_t mba_phys;
void *mba_region;
size_t mba_size;
size_t dp_size;

Expand Down Expand Up @@ -408,15 +407,15 @@ static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm,
current_perm, next, perms);
}

static void q6v5_debug_policy_load(struct q6v5 *qproc)
static void q6v5_debug_policy_load(struct q6v5 *qproc, void *mba_region)
{
const struct firmware *dp_fw;

if (request_firmware_direct(&dp_fw, "msadp", qproc->dev))
return;

if (SZ_1M + dp_fw->size <= qproc->mba_size) {
memcpy(qproc->mba_region + SZ_1M, dp_fw->data, dp_fw->size);
memcpy(mba_region + SZ_1M, dp_fw->data, dp_fw->size);
qproc->dp_size = dp_fw->size;
}

Expand All @@ -426,15 +425,24 @@ static void q6v5_debug_policy_load(struct q6v5 *qproc)
static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
{
struct q6v5 *qproc = rproc->priv;
void *mba_region;

/* MBA is restricted to a maximum size of 1M */
if (fw->size > qproc->mba_size || fw->size > SZ_1M) {
dev_err(qproc->dev, "MBA firmware load failed\n");
return -EINVAL;
}

memcpy(qproc->mba_region, fw->data, fw->size);
q6v5_debug_policy_load(qproc);
mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC);
if (!mba_region) {
dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
&qproc->mba_phys, qproc->mba_size);
return -EBUSY;
}

memcpy(mba_region, fw->data, fw->size);
q6v5_debug_policy_load(qproc, mba_region);
memunmap(mba_region);

return 0;
}
Expand Down Expand Up @@ -541,6 +549,7 @@ static void q6v5_dump_mba_logs(struct q6v5 *qproc)
{
struct rproc *rproc = qproc->rproc;
void *data;
void *mba_region;

if (!qproc->has_mba_logs)
return;
Expand All @@ -549,12 +558,16 @@ static void q6v5_dump_mba_logs(struct q6v5 *qproc)
qproc->mba_size))
return;

data = vmalloc(MBA_LOG_SIZE);
if (!data)
mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC);
if (!mba_region)
return;

memcpy(data, qproc->mba_region, MBA_LOG_SIZE);
dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL);
data = vmalloc(MBA_LOG_SIZE);
if (data) {
memcpy(data, mba_region, MBA_LOG_SIZE);
dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL);
}
memunmap(mba_region);
}

static int q6v5proc_reset(struct q6v5 *qproc)
Expand Down Expand Up @@ -1605,12 +1618,6 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)

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

if (!child) {
node = of_parse_phandle(qproc->dev->of_node,
Expand Down

0 comments on commit a7ed5e5

Please sign in to comment.