[PATCH v8 13/14] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux

Mukesh Ojha posted 14 patches 1 week, 3 days ago
[PATCH v8 13/14] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
Posted by Mukesh Ojha 1 week, 3 days ago
Most Qualcomm platforms feature Gunyah hypervisor, which typically
handles IOMMU configuration. This includes mapping memory regions and
device memory resources for remote processors by intercepting
qcom_scm_pas_auth_and_reset() calls. These mappings are later removed
during teardown. Additionally, SHM bridge setup is required to enable
memory protection for both remoteproc metadata and its memory regions.
When the aforementioned hypervisor is absent, the operating system must
perform these configurations instead.

When Linux runs as the hypervisor (@ EL2) on a SoC, it will have its
own device tree overlay file that specifies the firmware stream ID now
managed by Linux for a particular remote processor. If the iommus
property is specified in the remoteproc device tree node, it indicates
that IOMMU configuration must be handled by Linux. In this case, the
has_iommu flag is set for the remote processor, which ensures that the
resource table, carveouts, and SHM bridge are properly configured before
memory is passed to TrustZone for authentication. Otherwise, the
has_iommu flag remains unset, which indicates default behavior.

Enables Secure PAS support for remote processors when IOMMU configuration
is managed by Linux.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/remoteproc/qcom_q6v5_pas.c | 48 ++++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 186a90d6c83a..2df3b06f8157 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/interrupt.h>
+#include <linux/iommu.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -256,6 +257,22 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
 	return ret;
 }
 
+static void qcom_pas_unmap_carveout(struct rproc *rproc, phys_addr_t mem_phys, size_t size)
+{
+	if (rproc->has_iommu)
+		iommu_unmap(rproc->domain, mem_phys, size);
+}
+
+static int qcom_pas_map_carveout(struct rproc *rproc, phys_addr_t mem_phys, size_t size)
+{
+	int ret = 0;
+
+	if (rproc->has_iommu)
+		ret = iommu_map(rproc->domain, mem_phys, mem_phys, size,
+				IOMMU_READ | IOMMU_WRITE, GFP_KERNEL);
+	return ret;
+}
+
 static int qcom_pas_start(struct rproc *rproc)
 {
 	struct qcom_pas *pas = rproc->priv;
@@ -290,11 +307,15 @@ static int qcom_pas_start(struct rproc *rproc)
 	}
 
 	if (pas->dtb_pas_id) {
-		ret = qcom_scm_pas_auth_and_reset(pas->dtb_pas_id);
+		ret = qcom_pas_map_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size);
+		if (ret)
+			goto disable_px_supply;
+
+		ret = qcom_scm_pas_prepare_and_auth_reset(pas->dtb_pas_ctx);
 		if (ret) {
 			dev_err(pas->dev,
 				"failed to authenticate dtb image and release reset\n");
-			goto disable_px_supply;
+			goto unmap_dtb_carveout;
 		}
 	}
 
@@ -305,18 +326,22 @@ static int qcom_pas_start(struct rproc *rproc)
 
 	qcom_pil_info_store(pas->info_name, pas->mem_phys, pas->mem_size);
 
-	ret = qcom_scm_pas_auth_and_reset(pas->pas_id);
+	ret = qcom_pas_map_carveout(rproc, pas->mem_phys, pas->mem_size);
+	if (ret)
+		goto release_pas_metadata;
+
+	ret = qcom_scm_pas_prepare_and_auth_reset(pas->pas_ctx);
 	if (ret) {
 		dev_err(pas->dev,
 			"failed to authenticate image and release reset\n");
-		goto release_pas_metadata;
+		goto unmap_carveout;
 	}
 
 	ret = qcom_q6v5_wait_for_start(&pas->q6v5, msecs_to_jiffies(5000));
 	if (ret == -ETIMEDOUT) {
 		dev_err(pas->dev, "start timed out\n");
 		qcom_scm_pas_shutdown(pas->pas_id);
-		goto release_pas_metadata;
+		goto unmap_carveout;
 	}
 
 	qcom_scm_pas_metadata_release(pas->pas_ctx);
@@ -328,10 +353,16 @@ static int qcom_pas_start(struct rproc *rproc)
 
 	return 0;
 
+unmap_carveout:
+	qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size);
 release_pas_metadata:
 	qcom_scm_pas_metadata_release(pas->pas_ctx);
 	if (pas->dtb_pas_id)
 		qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
+
+unmap_dtb_carveout:
+	if (pas->dtb_pas_id)
+		qcom_pas_unmap_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size);
 disable_px_supply:
 	if (pas->px_supply)
 		regulator_disable(pas->px_supply);
@@ -387,8 +418,12 @@ static int qcom_pas_stop(struct rproc *rproc)
 		ret = qcom_scm_pas_shutdown(pas->dtb_pas_id);
 		if (ret)
 			dev_err(pas->dev, "failed to shutdown dtb: %d\n", ret);
+
+		qcom_pas_unmap_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size);
 	}
 
+	qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size);
+
 	handover = qcom_q6v5_unprepare(&pas->q6v5);
 	if (handover)
 		qcom_pas_handover(&pas->q6v5);
@@ -758,6 +793,7 @@ static int qcom_pas_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	rproc->has_iommu = of_property_present(pdev->dev.of_node, "iommus");
 	rproc->auto_boot = desc->auto_boot;
 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
 
@@ -837,6 +873,8 @@ static int qcom_pas_probe(struct platform_device *pdev)
 		goto remove_ssr_sysmon;
 	}
 
+	pas->pas_ctx->has_iommu = rproc->has_iommu;
+	pas->dtb_pas_ctx->has_iommu = rproc->has_iommu;
 	ret = rproc_add(rproc);
 	if (ret)
 		goto remove_ssr_sysmon;

-- 
2.50.1
Re: [PATCH v8 13/14] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
Posted by Konrad Dybcio 1 week ago
On 11/21/25 12:01 PM, Mukesh Ojha wrote:
> Most Qualcomm platforms feature Gunyah hypervisor, which typically
> handles IOMMU configuration. This includes mapping memory regions and
> device memory resources for remote processors by intercepting
> qcom_scm_pas_auth_and_reset() calls. These mappings are later removed
> during teardown. Additionally, SHM bridge setup is required to enable
> memory protection for both remoteproc metadata and its memory regions.
> When the aforementioned hypervisor is absent, the operating system must
> perform these configurations instead.
> 
> When Linux runs as the hypervisor (@ EL2) on a SoC, it will have its
> own device tree overlay file that specifies the firmware stream ID now
> managed by Linux for a particular remote processor. If the iommus
> property is specified in the remoteproc device tree node, it indicates
> that IOMMU configuration must be handled by Linux. In this case, the
> has_iommu flag is set for the remote processor, which ensures that the
> resource table, carveouts, and SHM bridge are properly configured before
> memory is passed to TrustZone for authentication. Otherwise, the
> has_iommu flag remains unset, which indicates default behavior.
> 
> Enables Secure PAS support for remote processors when IOMMU configuration
> is managed by Linux.
> 
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---

[...]

> +	pas->pas_ctx->has_iommu = rproc->has_iommu;
> +	pas->dtb_pas_ctx->has_iommu = rproc->has_iommu;

Sorry if we've been there before, but I see that IOMMU-mapping happens
before ctx initialization.. can we drop this parameter and just use
device_iommu_mapped(ctx->dev) in qcom_scm_pas_prepare_and_auth_reset()?
Re: [PATCH v8 13/14] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
Posted by Mukesh Ojha 1 week ago
On Mon, Nov 24, 2025 at 12:31:47PM +0100, Konrad Dybcio wrote:
> On 11/21/25 12:01 PM, Mukesh Ojha wrote:
> > Most Qualcomm platforms feature Gunyah hypervisor, which typically
> > handles IOMMU configuration. This includes mapping memory regions and
> > device memory resources for remote processors by intercepting
> > qcom_scm_pas_auth_and_reset() calls. These mappings are later removed
> > during teardown. Additionally, SHM bridge setup is required to enable
> > memory protection for both remoteproc metadata and its memory regions.
> > When the aforementioned hypervisor is absent, the operating system must
> > perform these configurations instead.
> > 
> > When Linux runs as the hypervisor (@ EL2) on a SoC, it will have its
> > own device tree overlay file that specifies the firmware stream ID now
> > managed by Linux for a particular remote processor. If the iommus
> > property is specified in the remoteproc device tree node, it indicates
> > that IOMMU configuration must be handled by Linux. In this case, the
> > has_iommu flag is set for the remote processor, which ensures that the
> > resource table, carveouts, and SHM bridge are properly configured before
> > memory is passed to TrustZone for authentication. Otherwise, the
> > has_iommu flag remains unset, which indicates default behavior.
> > 
> > Enables Secure PAS support for remote processors when IOMMU configuration
> > is managed by Linux.
> > 
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> 
> [...]
> 
> > +	pas->pas_ctx->has_iommu = rproc->has_iommu;
> > +	pas->dtb_pas_ctx->has_iommu = rproc->has_iommu;
> 
> Sorry if we've been there before, but I see that IOMMU-mapping happens
> before ctx initialization.. can we drop this parameter and just use
> device_iommu_mapped(ctx->dev) in qcom_scm_pas_prepare_and_auth_reset()?

You are right and I am not against it, rproc already has variable `has_iommu`
which we use in framework and vendor driver too, but what I thought,
since this thing we have to do even for Iris or other drivers who are
effected, they already have device which are behind IOMMU and if wrong
device is passed in device_iommu_mapped() instead of firmware device which
could have returned true even when Gunyah is present.

If you feel, has_iommu is not correct name, I could rename it to fw_iommu ?

-- 
-Mukesh Ojha
Re: [PATCH v8 13/14] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
Posted by Bjorn Andersson 5 days, 8 hours ago
On Mon, Nov 24, 2025 at 05:33:18PM +0530, Mukesh Ojha wrote:
> On Mon, Nov 24, 2025 at 12:31:47PM +0100, Konrad Dybcio wrote:
> > On 11/21/25 12:01 PM, Mukesh Ojha wrote:
> > > Most Qualcomm platforms feature Gunyah hypervisor, which typically
> > > handles IOMMU configuration. This includes mapping memory regions and
> > > device memory resources for remote processors by intercepting
> > > qcom_scm_pas_auth_and_reset() calls. These mappings are later removed
> > > during teardown. Additionally, SHM bridge setup is required to enable
> > > memory protection for both remoteproc metadata and its memory regions.
> > > When the aforementioned hypervisor is absent, the operating system must
> > > perform these configurations instead.
> > > 
> > > When Linux runs as the hypervisor (@ EL2) on a SoC, it will have its
> > > own device tree overlay file that specifies the firmware stream ID now
> > > managed by Linux for a particular remote processor. If the iommus
> > > property is specified in the remoteproc device tree node, it indicates
> > > that IOMMU configuration must be handled by Linux. In this case, the
> > > has_iommu flag is set for the remote processor, which ensures that the
> > > resource table, carveouts, and SHM bridge are properly configured before
> > > memory is passed to TrustZone for authentication. Otherwise, the
> > > has_iommu flag remains unset, which indicates default behavior.
> > > 
> > > Enables Secure PAS support for remote processors when IOMMU configuration
> > > is managed by Linux.
> > > 
> > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > > ---
> > 
> > [...]
> > 
> > > +	pas->pas_ctx->has_iommu = rproc->has_iommu;
> > > +	pas->dtb_pas_ctx->has_iommu = rproc->has_iommu;
> > 
> > Sorry if we've been there before, but I see that IOMMU-mapping happens
> > before ctx initialization.. can we drop this parameter and just use
> > device_iommu_mapped(ctx->dev) in qcom_scm_pas_prepare_and_auth_reset()?
> 
> You are right and I am not against it, rproc already has variable `has_iommu`
> which we use in framework and vendor driver too, but what I thought,
> since this thing we have to do even for Iris or other drivers who are
> effected, they already have device which are behind IOMMU and if wrong
> device is passed in device_iommu_mapped() instead of firmware device which
> could have returned true even when Gunyah is present.
> 
> If you feel, has_iommu is not correct name, I could rename it to fw_iommu ?
> 

While this does relate to "has_iommu" and/or "fw_iommu" when it comes to
the current PAS context, the "feature flag" is "should we use tzmem or
not".

Further, in the case of the modem, we don't have an IOMMU, but we still
need to set this flag on the ctx in order to get the metadata into TZ.

So, I think this should be detached from the "iommu". How about naming
the "has_iommu" in the context to "use_tzmem"?

Regards,
Bjorn

> -- 
> -Mukesh Ojha
Re: [PATCH v8 13/14] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
Posted by Mukesh Ojha 4 days, 18 hours ago
On Wed, Nov 26, 2025 at 10:40:51AM -0600, Bjorn Andersson wrote:
> On Mon, Nov 24, 2025 at 05:33:18PM +0530, Mukesh Ojha wrote:
> > On Mon, Nov 24, 2025 at 12:31:47PM +0100, Konrad Dybcio wrote:
> > > On 11/21/25 12:01 PM, Mukesh Ojha wrote:
> > > > Most Qualcomm platforms feature Gunyah hypervisor, which typically
> > > > handles IOMMU configuration. This includes mapping memory regions and
> > > > device memory resources for remote processors by intercepting
> > > > qcom_scm_pas_auth_and_reset() calls. These mappings are later removed
> > > > during teardown. Additionally, SHM bridge setup is required to enable
> > > > memory protection for both remoteproc metadata and its memory regions.
> > > > When the aforementioned hypervisor is absent, the operating system must
> > > > perform these configurations instead.
> > > > 
> > > > When Linux runs as the hypervisor (@ EL2) on a SoC, it will have its
> > > > own device tree overlay file that specifies the firmware stream ID now
> > > > managed by Linux for a particular remote processor. If the iommus
> > > > property is specified in the remoteproc device tree node, it indicates
> > > > that IOMMU configuration must be handled by Linux. In this case, the
> > > > has_iommu flag is set for the remote processor, which ensures that the
> > > > resource table, carveouts, and SHM bridge are properly configured before
> > > > memory is passed to TrustZone for authentication. Otherwise, the
> > > > has_iommu flag remains unset, which indicates default behavior.
> > > > 
> > > > Enables Secure PAS support for remote processors when IOMMU configuration
> > > > is managed by Linux.
> > > > 
> > > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > > > ---
> > > 
> > > [...]
> > > 
> > > > +	pas->pas_ctx->has_iommu = rproc->has_iommu;
> > > > +	pas->dtb_pas_ctx->has_iommu = rproc->has_iommu;
> > > 
> > > Sorry if we've been there before, but I see that IOMMU-mapping happens
> > > before ctx initialization.. can we drop this parameter and just use
> > > device_iommu_mapped(ctx->dev) in qcom_scm_pas_prepare_and_auth_reset()?
> > 
> > You are right and I am not against it, rproc already has variable `has_iommu`
> > which we use in framework and vendor driver too, but what I thought,
> > since this thing we have to do even for Iris or other drivers who are
> > effected, they already have device which are behind IOMMU and if wrong
> > device is passed in device_iommu_mapped() instead of firmware device which
> > could have returned true even when Gunyah is present.
> > 
> > If you feel, has_iommu is not correct name, I could rename it to fw_iommu ?
> > 
> 
> While this does relate to "has_iommu" and/or "fw_iommu" when it comes to
> the current PAS context, the "feature flag" is "should we use tzmem or
> not".
> 
> Further, in the case of the modem, we don't have an IOMMU, but we still
> need to set this flag on the ctx in order to get the metadata into TZ.
> 
> So, I think this should be detached from the "iommu". How about naming
> the "has_iommu" in the context to "use_tzmem"?

Sure, this way it gets attached to tzmem alloc/create API to be used or
not for PIL SMC calls.

> 
> Regards,
> Bjorn
> 
> > -- 
> > -Mukesh Ojha

-- 
-Mukesh Ojha