[PATCH v6 10/14] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE

Mukesh Ojha posted 14 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH v6 10/14] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE
Posted by Mukesh Ojha 1 month, 2 weeks ago
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
Re: [PATCH v6 10/14] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE
Posted by Konrad Dybcio 1 month, 1 week ago
On 11/4/25 8:35 AM, Mukesh Ojha wrote:
> 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;

I'm still a little sour about this function having to be separate just
because we use a different allocator..

Did we conclude that using set_dma_ops(some_tzmem_ops) was not going to
work?

Konrad
Re: [PATCH v6 10/14] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE
Posted by Mukesh Ojha 1 month, 1 week ago
On Fri, Nov 07, 2025 at 11:17:23AM +0100, Konrad Dybcio wrote:
> On 11/4/25 8:35 AM, Mukesh Ojha wrote:
> > 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;
> 
> I'm still a little sour about this function having to be separate just
> because we use a different allocator..
> 
> Did we conclude that using set_dma_ops(some_tzmem_ops) was not going to
> work?

I think, you asked here [1], and we discussed on this. It is not
something plain that we can hook every DMA api to tzmem. This SMC function
or any such buffer which is passed to TZ when QHEE is present, is a
special case as QHEE makes shmbridge and Linux need to do when it is absent. 

are you saying set_dma_ops() every case or just when ctx->has_iommu = true ?
If it is for every case, we will observe crash during call of this
function when we will run with QHEE.

And doing it only for non-gunyah does not make sense..

or let me know if I did not understand your question ?


[1]
http://shc-kerarch-hyd:8080/kernel_archive/ed0b8ec3-035f-4ea4-83ba-8f2aba9ea623@oss.qualcomm.com/


> 
> Konrad

-- 
-Mukesh Ojha