On SoCs running with a non-Gunyah-based hypervisor, Linux must take
responsibility for creating the SHM bridge both for metadata (before
calling qcom_scm_pas_init_image()) and for remoteproc memory (before
calling qcom_scm_pas_auth_and_reset()). We have taken care the things
required for qcom_scm_pas_auth_and_reset().
Lets put these awareness of above conditions into
qcom_scm_pas_init_image() and qcom_scm_pas_metadata_release().
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index aabdef295492..9d3e45ec73ac 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -625,6 +625,33 @@ static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys, void *me
return ret;
}
+static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_context *ctx,
+ const void *metadata, size_t size)
+{
+ struct qcom_scm_pas_metadata *mdt_ctx;
+ struct qcom_scm_res res;
+ phys_addr_t mdata_phys;
+ void *mdata_buf;
+ int ret;
+
+ mdata_buf = qcom_tzmem_alloc(__scm->mempool, size, GFP_KERNEL);
+ if (!mdata_buf)
+ return -ENOMEM;
+
+ memcpy(mdata_buf, metadata, size);
+ mdata_phys = qcom_tzmem_to_phys(mdata_buf);
+
+ ret = __qcom_scm_pas_init_image(ctx->pas_id, mdata_phys, mdata_buf, size, &res);
+ if (ret < 0) {
+ qcom_tzmem_free(mdata_buf);
+ } else {
+ mdt_ctx = ctx->metadata;
+ mdt_ctx->ptr = mdata_buf;
+ }
+
+ return ret ? : res.result[0];
+}
+
/**
* qcom_scm_pas_init_image() - Initialize peripheral authentication service
* state machine for a given peripheral, using the
@@ -651,6 +678,9 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
void *mdata_buf;
int ret;
+ if (ctx && ctx->has_iommu)
+ return qcom_scm_pas_prep_and_init_image(ctx, metadata, size);
+
/*
* During the scm call memory protection will be enabled for the meta
* data blob, so make sure it's physically contiguous, 4K aligned and
@@ -696,7 +726,10 @@ void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
if (!mdt_ctx->ptr)
return;
- dma_free_coherent(__scm->dev, mdt_ctx->size, mdt_ctx->ptr, mdt_ctx->phys);
+ if (ctx->has_iommu)
+ qcom_tzmem_free(mdt_ctx->ptr);
+ else
+ dma_free_coherent(__scm->dev, mdt_ctx->size, mdt_ctx->ptr, mdt_ctx->phys);
mdt_ctx->ptr = NULL;
}
--
2.50.1