]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE
authorMukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Mon, 5 Jan 2026 13:22:58 +0000 (18:52 +0530)
committerBjorn Andersson <andersson@kernel.org>
Tue, 13 Jan 2026 18:14:34 +0000 (12:14 -0600)
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().

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-10-022e96815380@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
drivers/firmware/qcom/qcom_scm.c

index bc3b8dc7d3e48fcf3107b66ff7bb016be53d76bb..4ce892d8fb2516d7840284f61e441e02897f0ac5 100644 (file)
@@ -623,6 +623,30 @@ disable_clk:
        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_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, &res);
+       if (ret < 0)
+               qcom_tzmem_free(mdata_buf);
+       else
+               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
@@ -648,6 +672,9 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
        void *mdata_buf;
        int ret;
 
+       if (ctx && ctx->use_tzmem)
+               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
@@ -689,7 +716,10 @@ void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
        if (!ctx->ptr)
                return;
 
-       dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
+       if (ctx->use_tzmem)
+               qcom_tzmem_free(ctx->ptr);
+       else
+               dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
 
        ctx->ptr = NULL;
 }