Commit a7ed5e57 authored by Sibi Sankar's avatar Sibi Sankar Committed by Bjorn Andersson
Browse files

remoteproc: qcom_q6v5_mss: map/unmap MBA region before/after use



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: default avatarSibi 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: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 04ff5d19
Loading
Loading
Loading
Loading
+22 −15
Original line number Diff line number Diff line
@@ -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;

@@ -408,7 +407,7 @@ 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;

@@ -416,7 +415,7 @@ static void q6v5_debug_policy_load(struct q6v5 *qproc)
		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;
	}

@@ -426,6 +425,7 @@ 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) {
@@ -433,8 +433,16 @@ static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
		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;
}
@@ -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;
@@ -549,13 +558,17 @@ 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);
	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)
{
@@ -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,