* [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
@ 2025-10-13 10:03 Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 01/13] dt-bindings: remoteproc: qcom,pas: Add iommus property Mukesh Ojha
` (13 more replies)
0 siblings, 14 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
A few months ago, we discussed the challenges at Linaro Connect 2025 [1]
related to Secure PAS remoteproc enablement when Linux is running at EL2.
[1] https://resources.linaro.org/en/resource/sF8jXifdb9V1mUefdbfafa
Below, is the summary of the discussion.
Qualcomm is working to enable remote processors on the SA8775p SoC with
a Linux host running at EL2. In doing so, it has encountered several
challenges related to how the remoteproc framework is handled when Linux
runs at EL1.
One of the main challenges arises from differences in how IOMMU
translation is currently managed on SoCs running the Qualcomm EL2
hypervisor (QHEE), where IOMMU translation for any device is entirely
owned by the hypervisor. Additionally, the firmware for remote
processors does not contain a resource table, which would typically
include the necessary IOMMU configuration settings.
Qualcomm SoCs running with QHEE (EL2) have been utilizing the Peripheral
Authentication Service (PAS) from TrustZone (TZ) firmware to securely
authenticate and reset remote processors via a single SMC call,
_auth_and_reset_. This call is first trapped by QHEE, which then invokes
TZ for authentication. Once authentication is complete, the call returns
to QHEE, which sets up the IOMMU translation scheme for the remote
processors and subsequently brings them out of reset. The design of the
Qualcomm EL2 hypervisor dictates that the Linux host OS running at EL1
is not permitted to configure IOMMU translation for remote processors,
and only a single-stage translation is configured.
To make the remote processor bring-up (PAS) sequence
hypervisor-independent, the auth_and_reset SMC call is now handled
entirely by TZ. However, the issue of IOMMU configuration remains
unresolved, for example a scenario, when KVM host at EL2 has no
knowledge of the remote processors’ IOMMU settings. This is being
addressed by overlaying the IOMMU properties when the SoC runs a Linux
host at EL2. SMC call is being provided from the TrustZone firmware to
retrieve the resource table for a given subsystem.
There are also remote processors such as those for video, camera, and
graphics that do not use the remoteproc framework to manage their
lifecycle. Instead, they rely on the Qualcomm PAS service to
authenticate their firmware. These processors also need to be brought
out of reset when Linux is running at EL2. The client drivers for these
processors use the MDT loader function to load and authenticate
firmware. Similar to the Qualcomm remoteproc PAS driver, they also need
to retrieve the resource table, create a shared memory bridge
(shmbridge), and map the resources before bringing the processors out of
reset.
It is based on next-20251010 and tested on SA8775p which is now called
Lemans IOT platform and does not addresses DMA problem discussed at
[1] which is future scope of the series.
Note that there is a regression on booting KVM on Qualcomm SoCs after
commit efad60e46057 ("KVM: arm64: Initialize PMSCR_EL1 when in VHE").
A fix has been purposed here
https://lore.kernel.org/lkml/20251010174707.1684200-1-mukesh.ojha@oss.qualcomm.com/
Changes in v5: https://lore.kernel.org/lkml/20251007-kvm_rprocv4_next-20251007-v4-0-de841623af3c@oss.qualcomm.com/
- Replaced minitems with maxitems.
- Addressed comments made by Bryan, Mani and Konrad.
- Fixed some of highlighted issues in v4.
- Added a new patch which removes qcom_mdt_pas_init() from exported
symbol list.
- Slight change in v4's 5/12, so that it does use qcom_mdt_pas_load()
directly while it should use in the commit where it gets introduced.
Hence, reordered the patches a bit like v4 5/12 comes early before
4/12.
Changes in v4: https://lore.kernel.org/lkml/20250921-kvm_rproc_pas-v3-0-458f09647920@oss.qualcomm.com/
- Fixed kernel robot warning/errors.
- Reworded some of the commit log, code comment as per suggestion from Bryan.
- Added support of gpdsp0 and gpdsp1 and disabled iris node.
- Add R-b tag to some of the reviewed patches.
- Rename struct qcom_scm_pas_cxt to qcom_scm_pas_context.
Changes in v3: https://lore.kernel.org/lkml/20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com/
- Dropped video subsystem enablement for now, could add it in future
or on a separate series.
- Addressed most of the suggestion from Stephen and Bryan like some
remoteproc code checking resource table presence or right error
code propagation above the layer.
- Added leman-el2 overlay file.
- Added missed iommus binding which was missed last series.
- Separated qcom_mdt_pas_load() patch and its usage.
- Patch numbering got changed compared to last version
Changes in v2: https://lore.kernel.org/lkml/20241004212359.2263502-1-quic_mojha@quicinc.com/
- A lot has changed from the V1 and a fresh look would be preferred.
- Removed approach where device tree contain devmem resources in
remoteproc node.
- SHMbridge need to created for both carveout and metadata memory
shared to TZ in a new way.
- Now, resource table would be given by SMC call which need to mapped
along with carveout before triggering _auth_and_reset_.
- IOMMU properties need to be added to firmware devices tree node when Linux
control IOMMU.
---
Mukesh Ojha (13):
dt-bindings: remoteproc: qcom,pas: Add iommus property
firmware: qcom_scm: Rename peripheral as pas_id
firmware: qcom_scm: Introduce PAS context initialization helper function
remoteproc: pas: Replace metadata context with PAS context structure
soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function
soc: qcom: mdtloader: Remove qcom_mdt_pas_init() from exported symbols
firmware: qcom_scm: Add a prep version of auth_and_reset function
firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE
firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
remoteproc: pas: Extend parse_fw callback to fetch resources via SMC call
remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
arm64: dts: qcom: Add EL2 overlay for Lemans
.../bindings/remoteproc/qcom,pas-common.yaml | 3 +
arch/arm64/boot/dts/qcom/Makefile | 8 +
arch/arm64/boot/dts/qcom/lemans-el2.dtso | 41 +++
drivers/firmware/qcom/qcom_scm.c | 394 ++++++++++++++++++---
drivers/firmware/qcom/qcom_scm.h | 1 +
drivers/remoteproc/qcom_q6v5_pas.c | 165 +++++++--
drivers/soc/qcom/mdt_loader.c | 42 ++-
include/linux/firmware/qcom/qcom_scm.h | 35 +-
include/linux/soc/qcom/mdt_loader.h | 22 +-
9 files changed, 598 insertions(+), 113 deletions(-)
---
base-commit: 2b763d4652393c90eaa771a5164502ec9dd965ae
change-id: 20251013-kvm_rprocv5-d24c1407a7c9
Best regards,
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v5 01/13] dt-bindings: remoteproc: qcom,pas: Add iommus property
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 02/13] firmware: qcom_scm: Rename peripheral as pas_id Mukesh Ojha
` (12 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
Most Qualcomm platforms feature Gunyah hypervisor which handles IOMMU
configuration for remote processor and when it is not present, the
operating system must perform these configurations instead and for that
firmware stream should be presented to the operating system. Hence, add
iommus property as optional property for PAS supported devices.
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
index 63a82e7a8bf8..68c17bf18987 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
@@ -44,6 +44,9 @@ properties:
- const: stop-ack
- const: shutdown-ack
+ iommus:
+ maxItems: 1
+
power-domains:
minItems: 1
maxItems: 3
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 02/13] firmware: qcom_scm: Rename peripheral as pas_id
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 01/13] dt-bindings: remoteproc: qcom,pas: Add iommus property Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 03/13] firmware: qcom_scm: Introduce PAS context initialization helper function Mukesh Ojha
` (11 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
Peripheral and pas_id refers to unique id for a subsystem and used only
when peripheral authentication service from secure world is utilized.
Lets rename peripheral to pas_id to reflect closer to its meaning.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 30 +++++++++++++++---------------
include/linux/firmware/qcom/qcom_scm.h | 10 +++++-----
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index e777b7cb9b12..3379607eaf94 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -562,7 +562,7 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
* qcom_scm_pas_init_image() - Initialize peripheral authentication service
* state machine for a given peripheral, using the
* metadata
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
* @metadata: pointer to memory containing ELF header, program header table
* and optional blob of data used for authenticating the metadata
* and the rest of the firmware
@@ -575,7 +575,7 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
* track the metadata allocation, this needs to be released by invoking
* qcom_scm_pas_metadata_release() by the caller.
*/
-int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
struct qcom_scm_pas_metadata *ctx)
{
dma_addr_t mdata_phys;
@@ -585,7 +585,7 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE,
.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
@@ -658,20 +658,20 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
/**
* qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
* for firmware loading
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
* @addr: start address of memory area to prepare
* @size: size of the memory area to prepare
*
* Returns 0 on success.
*/
-int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
+int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_MEM_SETUP,
.arginfo = QCOM_SCM_ARGS(3),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.args[1] = addr,
.args[2] = size,
.owner = ARM_SMCCC_OWNER_SIP,
@@ -699,18 +699,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup);
/**
* qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
* and reset the remote processor
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
*
* Return 0 on success.
*/
-int qcom_scm_pas_auth_and_reset(u32 peripheral)
+int qcom_scm_pas_auth_and_reset(u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET,
.arginfo = QCOM_SCM_ARGS(1),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
@@ -735,18 +735,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset);
/**
* qcom_scm_pas_shutdown() - Shut down the remote processor
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
*
* Returns 0 on success.
*/
-int qcom_scm_pas_shutdown(u32 peripheral)
+int qcom_scm_pas_shutdown(u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_SHUTDOWN,
.arginfo = QCOM_SCM_ARGS(1),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
@@ -772,18 +772,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown);
/**
* qcom_scm_pas_supported() - Check if the peripheral authentication service is
* available for the given peripherial
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
*
* Returns true if PAS is supported for this peripheral, otherwise false.
*/
-bool qcom_scm_pas_supported(u32 peripheral)
+bool qcom_scm_pas_supported(u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED,
.arginfo = QCOM_SCM_ARGS(1),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index a55ca771286b..a13f703b16cd 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -72,13 +72,13 @@ struct qcom_scm_pas_metadata {
ssize_t size;
};
-int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
struct qcom_scm_pas_metadata *ctx);
void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
-int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
-int qcom_scm_pas_auth_and_reset(u32 peripheral);
-int qcom_scm_pas_shutdown(u32 peripheral);
-bool qcom_scm_pas_supported(u32 peripheral);
+int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
+int qcom_scm_pas_auth_and_reset(u32 pas_id);
+int qcom_scm_pas_shutdown(u32 pas_id);
+bool qcom_scm_pas_supported(u32 pas_id);
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 03/13] firmware: qcom_scm: Introduce PAS context initialization helper function
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 01/13] dt-bindings: remoteproc: qcom,pas: Add iommus property Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 02/13] firmware: qcom_scm: Rename peripheral as pas_id Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 04/13] remoteproc: pas: Replace metadata context with PAS context structure Mukesh Ojha
` (10 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
When the Peripheral Authentication Service (PAS) method runs on a SoC
where Linux operates at EL2 (i.e., without the Gunyah hypervisor), the
reset sequences are handled by TrustZone. In such cases, Linux must
perform additional steps before invoking PAS SMC calls, such as creating
a SHM bridge. Therefore, PAS SMC calls require awareness and handling of
these additional steps when Linux runs at EL2.
To support this, there is a need for a data structure that can be
initialized prior to invoking any SMC or MDT functions. This structure
allows those functions to determine whether they are operating in the
presence or absence of the Gunyah hypervisor and behave accordingly.
Currently, remoteproc and non-remoteproc subsystems use different
variants of the MDT loader helper API, primarily due to differences in
metadata context handling. Remoteproc subsystems retain the metadata
context until authentication and reset are completed, while
non-remoteproc subsystems (e.g., video, graphics, IPA, etc.) do not
retain the metadata context and can free it within the
qcom_scm_pas_init() call by passing a NULL context parameter and due to
these differences, it is not possible to extend metadata context
handling to support remoteproc and non remoteproc subsystem use PAS
operations, when Linux operates at EL2.
Add PAS context data structure and initialization helper function.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 33 +++++++++++++++++++++++++++++++++
include/linux/firmware/qcom/qcom_scm.h | 10 ++++++++++
2 files changed, 43 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 3379607eaf94..6d22b2ac7880 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -558,6 +558,39 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
}
+/**
+ * qcom_scm_pas_context_init() - Initialize peripheral authentication service
+ * context for a given peripheral
+ *
+ * @dev: PAS firmware device
+ * @pas_id: peripheral authentication service id
+ * @mem_phys: Subsystem reserve memory start address
+ * @mem_size: Subsystem reserve memory size
+ *
+ * Upon successful, returns the PAS context or ERR_PTR() of the error otherwise.
+ */
+void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t mem_phys,
+ size_t mem_size)
+{
+ struct qcom_scm_pas_context *ctx;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return ERR_PTR(-ENOMEM);
+
+ ctx->dev = dev;
+ ctx->pas_id = pas_id;
+ ctx->mem_phys = mem_phys;
+ ctx->mem_size = mem_size;
+
+ ctx->metadata = devm_kzalloc(dev, sizeof(*ctx->metadata), GFP_KERNEL);
+ if (!ctx->metadata)
+ return ERR_PTR(-ENOMEM);
+
+ return ctx;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
+
/**
* qcom_scm_pas_init_image() - Initialize peripheral authentication service
* state machine for a given peripheral, using the
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index a13f703b16cd..75dec515c5d2 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -72,6 +72,16 @@ struct qcom_scm_pas_metadata {
ssize_t size;
};
+struct qcom_scm_pas_context {
+ struct device *dev;
+ u32 pas_id;
+ phys_addr_t mem_phys;
+ size_t mem_size;
+ struct qcom_scm_pas_metadata *metadata;
+};
+
+void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t mem_phys,
+ size_t mem_size);
int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
struct qcom_scm_pas_metadata *ctx);
void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 04/13] remoteproc: pas: Replace metadata context with PAS context structure
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (2 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 03/13] firmware: qcom_scm: Introduce PAS context initialization helper function Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-14 8:24 ` Bryan O'Donoghue
2025-10-13 10:03 ` [PATCH v5 05/13] soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function Mukesh Ojha
` (9 subsequent siblings)
13 siblings, 1 reply; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
As a superset of the existing metadata context, the PAS context
structure enables both remoteproc and non-remoteproc subsystems to
better support scenarios where the SoC runs with or without the Gunyah
hypervisor. To reflect this, relevant SCM and metadata functions are
updated to incorporate PAS context awareness.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 32 ++++++++++++++++-------------
drivers/remoteproc/qcom_q6v5_pas.c | 37 ++++++++++++++++++++++++----------
drivers/soc/qcom/mdt_loader.c | 4 ++--
include/linux/firmware/qcom/qcom_scm.h | 4 ++--
include/linux/soc/qcom/mdt_loader.h | 6 +++---
5 files changed, 51 insertions(+), 32 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 6d22b2ac7880..b11a21797d46 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -600,7 +600,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
* and optional blob of data used for authenticating the metadata
* and the rest of the firmware
* @size: size of the metadata
- * @ctx: optional metadata context
+ * @ctx: optional pas context
*
* Return: 0 on success.
*
@@ -609,8 +609,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
* qcom_scm_pas_metadata_release() by the caller.
*/
int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_metadata *ctx)
+ struct qcom_scm_pas_context *ctx)
{
+ struct qcom_scm_pas_metadata *mdt_ctx;
dma_addr_t mdata_phys;
void *mdata_buf;
int ret;
@@ -661,10 +662,11 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
out:
if (ret < 0 || !ctx) {
dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
- } else if (ctx) {
- ctx->ptr = mdata_buf;
- ctx->phys = mdata_phys;
- ctx->size = size;
+ } else if (ctx && ctx->metadata) {
+ mdt_ctx = ctx->metadata;
+ mdt_ctx->ptr = mdata_buf;
+ mdt_ctx->phys = mdata_phys;
+ mdt_ctx->size = size;
}
return ret ? : res.result[0];
@@ -673,18 +675,20 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
/**
* qcom_scm_pas_metadata_release() - release metadata context
- * @ctx: metadata context
+ * @ctx: pas context
*/
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx)
+void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
{
- if (!ctx->ptr)
- return;
+ struct qcom_scm_pas_metadata *mdt_ctx;
- dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
+ mdt_ctx = ctx->metadata;
+ if (!mdt_ctx->ptr)
+ return;
- ctx->ptr = NULL;
- ctx->phys = 0;
- ctx->size = 0;
+ dma_free_coherent(__scm->dev, mdt_ctx->size, mdt_ctx->ptr, mdt_ctx->phys);
+ mdt_ctx->ptr = NULL;
+ mdt_ctx->phys = 0;
+ mdt_ctx->size = 0;
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 158bcd6cc85c..e9dcab94ea0c 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -117,8 +117,8 @@ struct qcom_pas {
struct qcom_rproc_ssr ssr_subdev;
struct qcom_sysmon *sysmon;
- struct qcom_scm_pas_metadata pas_metadata;
- struct qcom_scm_pas_metadata dtb_pas_metadata;
+ struct qcom_scm_pas_context *pas_ctx;
+ struct qcom_scm_pas_context *dtb_pas_ctx;
};
static void qcom_pas_segment_dump(struct rproc *rproc,
@@ -211,9 +211,9 @@ static int qcom_pas_unprepare(struct rproc *rproc)
* auth_and_reset() was successful, but in other cases clean it up
* here.
*/
- qcom_scm_pas_metadata_release(&pas->pas_metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
return 0;
}
@@ -241,7 +241,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
pas->dtb_pas_id, pas->dtb_mem_phys,
- &pas->dtb_pas_metadata);
+ pas->dtb_pas_ctx);
if (ret)
goto release_dtb_firmware;
@@ -255,7 +255,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
return 0;
release_dtb_metadata:
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
release_dtb_firmware:
release_firmware(pas->dtb_firmware);
@@ -306,7 +306,7 @@ static int qcom_pas_start(struct rproc *rproc)
}
ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
- pas->mem_phys, &pas->pas_metadata);
+ pas->mem_phys, pas->pas_ctx);
if (ret)
goto disable_px_supply;
@@ -332,9 +332,9 @@ static int qcom_pas_start(struct rproc *rproc)
goto release_pas_metadata;
}
- qcom_scm_pas_metadata_release(&pas->pas_metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
/* firmware is used to pass reference from qcom_pas_start(), drop it now */
pas->firmware = NULL;
@@ -342,9 +342,9 @@ static int qcom_pas_start(struct rproc *rproc)
return 0;
release_pas_metadata:
- qcom_scm_pas_metadata_release(&pas->pas_metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
disable_px_supply:
if (pas->px_supply)
regulator_disable(pas->px_supply);
@@ -779,6 +779,21 @@ static int qcom_pas_probe(struct platform_device *pdev)
}
qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name);
+
+ pas->pas_ctx = qcom_scm_pas_context_init(pas->dev, pas->pas_id, pas->mem_phys,
+ pas->mem_size);
+ if (IS_ERR(pas->pas_ctx)) {
+ ret = PTR_ERR(pas->pas_ctx);
+ goto remove_ssr_sysmon;
+ }
+
+ pas->dtb_pas_ctx = qcom_scm_pas_context_init(pas->dev, pas->dtb_pas_id,
+ pas->dtb_mem_phys, pas->dtb_mem_size);
+ if (IS_ERR(pas->dtb_pas_ctx)) {
+ ret = PTR_ERR(pas->dtb_pas_ctx);
+ goto remove_ssr_sysmon;
+ }
+
ret = rproc_add(rproc);
if (ret)
goto remove_ssr_sysmon;
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index a5c80d4fcc36..fe35038c5342 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -234,13 +234,13 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
* @fw_name: name of the firmware, for construction of segment file names
* @pas_id: PAS identifier
* @mem_phys: physical address of allocated memory region
- * @ctx: PAS metadata context, to be released by caller
+ * @ctx: PAS context, ctx->metadata to be released by caller
*
* Returns 0 on success, negative errno otherwise.
*/
int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *ctx)
+ struct qcom_scm_pas_context *ctx)
{
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 75dec515c5d2..7c58d26ede24 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -83,8 +83,8 @@ struct qcom_scm_pas_context {
void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t mem_phys,
size_t mem_size);
int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_metadata *ctx);
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
+ struct qcom_scm_pas_context *ctx);
+void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx);
int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
int qcom_scm_pas_auth_and_reset(u32 pas_id);
int qcom_scm_pas_shutdown(u32 pas_id);
diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
index 8ea8230579a2..07c278841816 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -10,14 +10,14 @@
struct device;
struct firmware;
-struct qcom_scm_pas_metadata;
+struct qcom_scm_pas_context;
#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
ssize_t qcom_mdt_get_size(const struct firmware *fw);
int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *pas_metadata_ctx);
+ struct qcom_scm_pas_context *pas_ctx);
int qcom_mdt_load(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, void *mem_region,
phys_addr_t mem_phys, size_t mem_size,
@@ -39,7 +39,7 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw)
static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *pas_metadata_ctx)
+ struct qcom_scm_pas_context *pas_ctx)
{
return -ENODEV;
}
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 05/13] soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (3 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 04/13] remoteproc: pas: Replace metadata context with PAS context structure Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 12:56 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 06/13] soc: qcom: mdtloader: Remove qcom_mdt_pas_init() from exported symbols Mukesh Ojha
` (8 subsequent siblings)
13 siblings, 1 reply; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
Introduce a new PAS context-aware function, qcom_mdt_pas_load(), for
remote processor drivers. This function utilizes the PAS context
pointer returned from qcom_scm_pas_ctx_init() to perform firmware
metadata verification and memory setup via SMC calls.
The qcom_mdt_pas_load() and qcom_mdt_load() functions are largely
similar, but the former is designed for clients using the PAS
context-based data structure. Over time, all users of qcom_mdt_load()
can be migrated to use qcom_mdt_pas_load() for consistency and
improved abstraction.
As the remoteproc PAS driver (qcom_q6v5_pas) has already adopted the
PAS context-based approach, update it to use qcom_mdt_pas_load().
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/remoteproc/qcom_q6v5_pas.c | 24 +++++-------------------
drivers/soc/qcom/mdt_loader.c | 32 ++++++++++++++++++++++++++++++++
include/linux/soc/qcom/mdt_loader.h | 10 ++++++++++
3 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index e9dcab94ea0c..ee0ea35803c6 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -239,15 +239,9 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
return ret;
}
- ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
- pas->dtb_pas_id, pas->dtb_mem_phys,
- pas->dtb_pas_ctx);
- if (ret)
- goto release_dtb_firmware;
-
- ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
- pas->dtb_mem_region, pas->dtb_mem_phys,
- pas->dtb_mem_size, &pas->dtb_mem_reloc);
+ ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware,
+ pas->dtb_firmware_name, pas->dtb_mem_region,
+ &pas->dtb_mem_reloc);
if (ret)
goto release_dtb_metadata;
}
@@ -256,8 +250,6 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
release_dtb_metadata:
qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
-
-release_dtb_firmware:
release_firmware(pas->dtb_firmware);
return ret;
@@ -305,14 +297,8 @@ static int qcom_pas_start(struct rproc *rproc)
}
}
- ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
- pas->mem_phys, pas->pas_ctx);
- if (ret)
- goto disable_px_supply;
-
- ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware,
- pas->mem_region, pas->mem_phys, pas->mem_size,
- &pas->mem_reloc);
+ ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware,
+ pas->mem_region, &pas->mem_reloc);
if (ret)
goto release_pas_metadata;
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index fe35038c5342..52de8adcc4f2 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -486,5 +486,37 @@ int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
}
EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init);
+/**
+ * qcom_mdt_pas_load - Loads and authenticates the metadata of the firmware
+ * (typically contained in the .mdt file), followed by loading the actual
+ * firmware segments (e.g., .bXX files). Authentication of the segments done
+ * by a separate call.
+ *
+ * The PAS context must be initialized using qcom_scm_pas_context_init()
+ * prior to invoking this function.
+ *
+ * @ctx: Pointer to the PAS (Peripheral Authentication Service) context
+ * @fw: Firmware object representing the .mdt file
+ * @firmware: Name of the firmware used to construct segment file names
+ * @mem_region: Memory region allocated for loading the firmware
+ * @reloc_base: Physical address adjusted after relocation
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw,
+ const char *firmware, void *mem_region, phys_addr_t *reloc_base)
+{
+ int ret;
+
+ ret = qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys,
+ ctx->metadata);
+ if (ret)
+ return ret;
+
+ return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx->mem_phys,
+ ctx->mem_size, reloc_base);
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_pas_load);
+
MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format");
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
index 07c278841816..7d57746fbbfa 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -23,6 +23,9 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
phys_addr_t mem_phys, size_t mem_size,
phys_addr_t *reloc_base);
+int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw,
+ const char *firmware, void *mem_region, phys_addr_t *reloc_base);
+
int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
const char *fw_name, void *mem_region,
phys_addr_t mem_phys, size_t mem_size,
@@ -52,6 +55,13 @@ static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
return -ENODEV;
}
+static inline int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx,
+ const struct firmware *fw, const char *firmware,
+ void *mem_region, phys_addr_t *reloc_base)
+{
+ return -ENODEV;
+}
+
static inline int qcom_mdt_load_no_init(struct device *dev,
const struct firmware *fw,
const char *fw_name, void *mem_region,
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 06/13] soc: qcom: mdtloader: Remove qcom_mdt_pas_init() from exported symbols
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (4 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 05/13] soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 07/13] firmware: qcom_scm: Add a prep version of auth_and_reset function Mukesh Ojha
` (7 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
qcom_mdt_pas_init() was previously used only by the remoteproc driver
(drivers/remoteproc/qcom_q6v5_pas.c). Since that driver has now
transitioned to using PAS context-based qcom_mdt_pas_load() function,
making qcom_mdt_pas_init() obsolete for external use.
Removes qcom_mdt_pas_init() from the list of exported symbols and make
it static to limit its scope to internal use within mdtloader.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/soc/qcom/mdt_loader.c | 12 +++++-------
include/linux/soc/qcom/mdt_loader.h | 10 ----------
2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index 52de8adcc4f2..97e6d11b8926 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -238,9 +238,9 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
*
* Returns 0 on success, negative errno otherwise.
*/
-int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
- const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_context *ctx)
+static int __qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
+ const char *fw_name, int pas_id, phys_addr_t mem_phys,
+ struct qcom_scm_pas_context *ctx)
{
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
@@ -302,7 +302,6 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
out:
return ret;
}
-EXPORT_SYMBOL_GPL(qcom_mdt_pas_init);
static bool qcom_mdt_bins_are_split(const struct firmware *fw)
{
@@ -456,7 +455,7 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
{
int ret;
- ret = qcom_mdt_pas_init(dev, fw, firmware, pas_id, mem_phys, NULL);
+ ret = __qcom_mdt_pas_init(dev, fw, firmware, pas_id, mem_phys, NULL);
if (ret)
return ret;
@@ -508,8 +507,7 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *f
{
int ret;
- ret = qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys,
- ctx->metadata);
+ ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys, ctx);
if (ret)
return ret;
diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
index 7d57746fbbfa..82372e0db0a1 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -15,9 +15,6 @@ struct qcom_scm_pas_context;
#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
ssize_t qcom_mdt_get_size(const struct firmware *fw);
-int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
- const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_context *pas_ctx);
int qcom_mdt_load(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, void *mem_region,
phys_addr_t mem_phys, size_t mem_size,
@@ -40,13 +37,6 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw)
return -ENODEV;
}
-static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
- const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_context *pas_ctx)
-{
- return -ENODEV;
-}
-
static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id,
void *mem_region, phys_addr_t mem_phys,
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 07/13] firmware: qcom_scm: Add a prep version of auth_and_reset function
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (5 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 06/13] soc: qcom: mdtloader: Remove qcom_mdt_pas_init() from exported symbols Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 08/13] firmware: qcom_scm: Simplify qcom_scm_pas_init_image() Mukesh Ojha
` (6 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
For memory passed to TrustZone (TZ), it must either be part of a pool
registered with TZ or explicitly registered via SHMbridge SMC calls.
When Gunyah hypervisor is present, PAS SMC calls from Linux running at
EL1 are trapped by Gunyah running @ EL2, which handles SHMbridge
creation for both metadata and remoteproc carveout memory before
invoking the calls to TZ.
On SoCs running with a non-Gunyah-based hypervisor, Linux must take
responsibility for creating the SHM bridge before invoking PAS SMC
calls. For the auth_and_reset() call, the remoteproc carveout memory
must first be registered with TZ via a SHMbridge SMC call and once
authentication and reset are complete, the SHMbridge memory can be
deregistered.
Introduce qcom_scm_pas_prepare_and_auth_reset(), which sets up the SHM
bridge over the remoteproc carveout memory when Linux operates at EL2.
This behavior is indicated by a new field added to the PAS context data
structure. The function then invokes the auth_and_reset SMC call.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 48 ++++++++++++++++++++++++++++++++++
include/linux/firmware/qcom/qcom_scm.h | 2 ++
2 files changed, 50 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index b11a21797d46..a66e782fdb68 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -770,6 +770,54 @@ int qcom_scm_pas_auth_and_reset(u32 pas_id)
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset);
+/**
+ * qcom_scm_pas_prepare_and_auth_reset() - Prepare, authenticate, and reset the
+ * remote processor
+ *
+ * @ctx: Context saved during call to qcom_scm_pas_context_init()
+ *
+ * This function performs the necessary steps to prepare a PAS subsystem,
+ * authenticate it using the provided metadata, and initiate a reset sequence.
+ *
+ * It should be used when Linux is in control setting up the IOMMU hardware
+ * for remote subsystem during secure firmware loading processes. The preparation
+ * step sets up a shmbridge over the firmware memory before TrustZone accesses the
+ * firmware memory region for authentication. The authentication step verifies
+ * the integrity and authenticity of the firmware or configuration using secure
+ * metadata. Finally, the reset step ensures the subsystem starts in a clean and
+ * sane state.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
+{
+ u64 handle;
+ int ret;
+
+ if (!ctx->has_iommu)
+ return qcom_scm_pas_auth_and_reset(ctx->pas_id);
+
+ /*
+ * When Linux running @ EL1, Gunyah hypervisor running @ EL2 traps the
+ * auth_and_reset call and create an shmbridge on the remote subsystem
+ * memory region and then invokes a call to TrustZone to authenticate.
+ * When Linux runs @ EL2 Linux must create the shmbridge itself and then
+ * subsequently call TrustZone for authenticate and reset.
+ */
+ ret = qcom_tzmem_shm_bridge_create(ctx->mem_phys, ctx->mem_size, &handle);
+ if (ret) {
+ dev_err(__scm->dev, "Failed to create shmbridge for PAS ID (%u): %d\n",
+ ctx->pas_id, ret);
+ return ret;
+ }
+
+ ret = qcom_scm_pas_auth_and_reset(ctx->pas_id);
+ qcom_tzmem_shm_bridge_delete(handle);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset);
+
/**
* qcom_scm_pas_shutdown() - Shut down the remote processor
* @pas_id: peripheral authentication service id
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 7c58d26ede24..e1de3cf73451 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -78,6 +78,7 @@ struct qcom_scm_pas_context {
phys_addr_t mem_phys;
size_t mem_size;
struct qcom_scm_pas_metadata *metadata;
+ bool has_iommu;
};
void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t mem_phys,
@@ -89,6 +90,7 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
int qcom_scm_pas_auth_and_reset(u32 pas_id);
int qcom_scm_pas_shutdown(u32 pas_id);
bool qcom_scm_pas_supported(u32 pas_id);
+int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx);
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 08/13] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (6 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 07/13] firmware: qcom_scm: Add a prep version of auth_and_reset function Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 09/13] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE Mukesh Ojha
` (5 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
Simplify qcom_scm_pas_init_image() by making the memory allocation,
copy and free operations done in a separate function than the actual
SMC call.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 58 +++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 25 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index a66e782fdb68..eb79fceda92b 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -591,6 +591,37 @@ void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t mem_
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
+static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys, void *metadata,
+ size_t size, struct qcom_scm_res *res)
+{
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_SVC_PIL,
+ .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE,
+ .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW),
+ .args[0] = pas_id,
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+ int ret;
+
+ ret = qcom_scm_clk_enable();
+ if (ret)
+ return ret;
+
+ ret = qcom_scm_bw_enable();
+ if (ret)
+ goto disable_clk;
+
+ desc.args[1] = mdata_phys;
+
+ ret = qcom_scm_call(__scm->dev, &desc, res);
+ qcom_scm_bw_disable();
+
+disable_clk:
+ qcom_scm_clk_disable();
+
+ return ret;
+}
+
/**
* qcom_scm_pas_init_image() - Initialize peripheral authentication service
* state machine for a given peripheral, using the
@@ -612,17 +643,10 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
struct qcom_scm_pas_context *ctx)
{
struct qcom_scm_pas_metadata *mdt_ctx;
+ struct qcom_scm_res res;
dma_addr_t mdata_phys;
void *mdata_buf;
int ret;
- struct qcom_scm_desc desc = {
- .svc = QCOM_SCM_SVC_PIL,
- .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE,
- .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW),
- .args[0] = pas_id,
- .owner = ARM_SMCCC_OWNER_SIP,
- };
- struct qcom_scm_res res;
/*
* During the scm call memory protection will be enabled for the meta
@@ -643,23 +667,7 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
memcpy(mdata_buf, metadata, size);
- ret = qcom_scm_clk_enable();
- if (ret)
- goto out;
-
- ret = qcom_scm_bw_enable();
- if (ret)
- goto disable_clk;
-
- desc.args[1] = mdata_phys;
-
- ret = qcom_scm_call(__scm->dev, &desc, &res);
- qcom_scm_bw_disable();
-
-disable_clk:
- qcom_scm_clk_disable();
-
-out:
+ ret = __qcom_scm_pas_init_image(pas_id, mdata_phys, mdata_buf, size, &res);
if (ret < 0 || !ctx) {
dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
} else if (ctx && ctx->metadata) {
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 09/13] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (7 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 08/13] firmware: qcom_scm: Simplify qcom_scm_pas_init_image() Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 10/13] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Mukesh Ojha
` (4 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
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 | 44 +++++++++++++++++++++++++++++++---
include/linux/firmware/qcom/qcom_scm.h | 5 +++-
2 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index eb79fceda92b..c545f7114237 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -622,6 +622,35 @@ 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;
+
+ mdt_ctx = ctx->metadata;
+ 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 || !mdt_ctx) {
+ qcom_tzmem_free(mdata_buf);
+ } else if (mdt_ctx) {
+ mdt_ctx->ptr = mdata_buf;
+ mdt_ctx->addr.phys_addr = mdata_phys;
+ mdt_ctx->size = size;
+ }
+
+ return ret ? : res.result[0];
+}
+
/**
* qcom_scm_pas_init_image() - Initialize peripheral authentication service
* state machine for a given peripheral, using the
@@ -648,6 +677,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
@@ -673,7 +705,7 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
} else if (ctx && ctx->metadata) {
mdt_ctx = ctx->metadata;
mdt_ctx->ptr = mdata_buf;
- mdt_ctx->phys = mdata_phys;
+ mdt_ctx->addr.dma_addr = mdata_phys;
mdt_ctx->size = size;
}
@@ -693,9 +725,15 @@ 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);
+ mdt_ctx->addr.phys_addr = 0;
+ } else {
+ dma_free_coherent(__scm->dev, mdt_ctx->size, mdt_ctx->ptr,
+ mdt_ctx->addr.dma_addr);
+ mdt_ctx->addr.dma_addr = 0;
+ }
mdt_ctx->ptr = NULL;
- mdt_ctx->phys = 0;
mdt_ctx->size = 0;
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index e1de3cf73451..583490bcd38b 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -68,7 +68,10 @@ int qcom_scm_set_remote_state(u32 state, u32 id);
struct qcom_scm_pas_metadata {
void *ptr;
- dma_addr_t phys;
+ union {
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+ } addr;
ssize_t size;
};
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 10/13] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (8 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 09/13] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 11/13] remoteproc: pas: Extend parse_fw callback to fetch resources via SMC call Mukesh Ojha
` (3 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
Qualcomm remote processor may rely on Static and Dynamic resources for
it to be functional. Static resources are fixed like for example,
memory-mapped addresses required by the subsystem and dynamic
resources, such as shared memory in DDR etc., are determined at
runtime during the boot process.
For most of the Qualcomm SoCs, when run with Gunyah or older QHEE
hypervisor, all the resources whether it is static or dynamic, is
managed by the hypervisor. Dynamic resources if it is present for a
remote processor will always be coming from secure world via SMC call
while static resources may be present in remote processor firmware
binary or it may be coming qcom_scm_pas_get_rsc_table() SMC call along
with dynamic resources.
Some of the remote processor drivers, such as video, GPU, IPA, etc., do
not check whether resources are present in their remote processor
firmware binary. In such cases, the caller of this function should set
input_rt and input_rt_size as NULL and zero respectively. Remoteproc
framework has method to check whether firmware binary contain resources
or not and they should be pass resource table pointer to input_rt and
resource table size to input_rt_size and this will be forwarded to
TrustZone for authentication. TrustZone will then append the dynamic
resources and return the complete resource table in output_rt
More about documentation on resource table format can be found in
include/linux/remoteproc.h
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 157 +++++++++++++++++++++++++++++++++
drivers/firmware/qcom/qcom_scm.h | 1 +
include/linux/firmware/qcom/qcom_scm.h | 4 +
3 files changed, 162 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index c545f7114237..3c554f3e8536 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -27,6 +27,7 @@
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
+#include <linux/remoteproc.h>
#include <linux/sizes.h>
#include <linux/types.h>
@@ -111,6 +112,10 @@ enum qcom_scm_qseecom_tz_cmd_info {
QSEECOM_TZ_CMD_INFO_VERSION = 3,
};
+enum qcom_scm_rsctable_resp_type {
+ RSCTABLE_BUFFER_NOT_SUFFICIENT = 20,
+};
+
#define QSEECOM_MAX_APP_NAME_SIZE 64
#define SHMBRIDGE_RESULT_NOTSUPP 4
@@ -779,6 +784,158 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup);
+static int __qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt, size_t input_rt_size,
+ void **output_rt, size_t *output_rt_size)
+{
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_SVC_PIL,
+ .cmd = QCOM_SCM_PIL_PAS_GET_RSCTABLE,
+ .arginfo = QCOM_SCM_ARGS(5, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL,
+ QCOM_SCM_RW, QCOM_SCM_VAL),
+ .args[0] = pas_id,
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+ void *input_rt_buf, *output_rt_buf;
+ struct resource_table *rsc;
+ struct qcom_scm_res res;
+ int ret;
+
+ ret = qcom_scm_clk_enable();
+ if (ret)
+ return ret;
+
+ ret = qcom_scm_bw_enable();
+ if (ret)
+ goto disable_clk;
+
+ /*
+ * TrustZone can not accept buffer as NULL value as argument Hence,
+ * we need to pass a input buffer indicating that subsystem firmware
+ * does not have resource table by filling resource table structure.
+ */
+ if (!input_rt)
+ input_rt_size = sizeof(*rsc);
+
+ input_rt_buf = qcom_tzmem_alloc(__scm->mempool, input_rt_size, GFP_KERNEL);
+ if (!input_rt_buf) {
+ ret = -ENOMEM;
+ goto disable_scm_bw;
+ }
+
+ if (!input_rt) {
+ rsc = input_rt_buf;
+ rsc->num = 0;
+ } else {
+ memcpy(input_rt_buf, input_rt, input_rt_size);
+ }
+
+ output_rt_buf = qcom_tzmem_alloc(__scm->mempool, *output_rt_size, GFP_KERNEL);
+ if (!output_rt_buf) {
+ ret = -ENOMEM;
+ goto free_input_rt_buf;
+ }
+
+ desc.args[1] = qcom_tzmem_to_phys(input_rt_buf);
+ desc.args[2] = input_rt_size;
+ desc.args[3] = qcom_tzmem_to_phys(output_rt_buf);
+ desc.args[4] = *output_rt_size;
+
+ /*
+ * Whether SMC fail or pass, res.result[2] will hold actual resource table
+ * size.
+ *
+ * if passed 'output_rt_size' buffer size is not sufficient to hold the
+ * resource table TrustZone sends, response code in res.result[1] as
+ * RSCTABLE_BUFFER_NOT_SUFFICIENT so that caller can retry this SMC call with
+ * output_rt buffer with res.result[2] size.
+ */
+ ret = qcom_scm_call(__scm->dev, &desc, &res);
+ *output_rt_size = res.result[2];
+ if (!ret)
+ memcpy(*output_rt, output_rt_buf, *output_rt_size);
+
+ if (ret && res.result[1] == RSCTABLE_BUFFER_NOT_SUFFICIENT)
+ ret = -EAGAIN;
+
+ qcom_tzmem_free(output_rt_buf);
+
+free_input_rt_buf:
+ qcom_tzmem_free(input_rt_buf);
+
+disable_scm_bw:
+ qcom_scm_bw_disable();
+
+disable_clk:
+ qcom_scm_clk_disable();
+
+ return ret ? : res.result[0];
+}
+
+/**
+ * qcom_scm_pas_get_rsc_table() - Retrieve the resource table in passed output buffer
+ * for a given peripheral.
+ *
+ * Qualcomm remote processor may rely on both static and dynamic resources for
+ * its functionality. Static resources typically refer to memory-mapped addresses
+ * required by the subsystem and are often embedded within the firmware binary
+ * and dynamic resources, such as shared memory in DDR etc., are determined at
+ * runtime during the boot process.
+ *
+ * On Qualcomm Technologies devices, it's possible that static resources are not
+ * embedded in the firmware binary and instead are provided by TrustZone However,
+ * dynamic resources are always expected to come from TrustZone. This indicates
+ * that for Qualcomm devices, all resources (static and dynamic) will be provided
+ * by TrustZone via the SMC call.
+ *
+ * If the remote processor firmware binary does contain static resources, they
+ * should be passed in input_rt. These will be forwarded to TrustZone for
+ * authentication. TrustZone will then append the dynamic resources and return
+ * the complete resource table in output_rt.
+ *
+ * If the remote processor firmware binary does not include a resource table,
+ * the caller of this function should set input_rt as NULL and input_rt_size
+ * as zero respectively.
+ *
+ * More about documentation on resource table data structures can be found in
+ * include/linux/rsc_table.h
+ *
+ * @ctx: PAS context
+ * @pas_id: peripheral authentication service id
+ * @input_rt: resource table buffer which is present in firmware binary
+ * @input_rt_size: size of the resource table present in firmware binary
+ * @output_rt: buffer to which the both static and dynamic resources will
+ * be returned.
+ * @output_rt_size: TrustZone expects caller should pass worst case size for
+ * the output_rt.
+ *
+ * Return: 0 on success and nonzero on failure.
+ *
+ * Upon successful return, output_rt will have the resource table and output_rt_size
+ * will have actual resource table size,
+ */
+int qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx, void *input_rt,
+ size_t input_rt_size, void **output_rt,
+ size_t *output_rt_size)
+{
+ int ret;
+
+ do {
+ *output_rt = devm_kzalloc(ctx->dev, *output_rt_size, GFP_KERNEL);
+ if (!*output_rt)
+ return -ENOMEM;
+
+ ret = __qcom_scm_pas_get_rsc_table(ctx->pas_id, input_rt,
+ input_rt_size, output_rt,
+ output_rt_size);
+ if (ret)
+ devm_kfree(ctx->dev, *output_rt);
+
+ } while (ret == -EAGAIN);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table);
+
/**
* qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
* and reset the remote processor
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index a56c8212cc0c..50d87c628d78 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -105,6 +105,7 @@ int qcom_scm_shm_bridge_enable(struct device *scm_dev);
#define QCOM_SCM_PIL_PAS_SHUTDOWN 0x06
#define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x07
#define QCOM_SCM_PIL_PAS_MSS_RESET 0x0a
+#define QCOM_SCM_PIL_PAS_GET_RSCTABLE 0x21
#define QCOM_SCM_SVC_IO 0x05
#define QCOM_SCM_IO_READ 0x01
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 583490bcd38b..5cd9b2553cad 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -93,6 +93,10 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
int qcom_scm_pas_auth_and_reset(u32 pas_id);
int qcom_scm_pas_shutdown(u32 pas_id);
bool qcom_scm_pas_supported(u32 pas_id);
+int qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx, void *input_rt,
+ size_t input_rt_size, void **output_rt,
+ size_t *output_rt_size);
+
int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx);
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 11/13] remoteproc: pas: Extend parse_fw callback to fetch resources via SMC call
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (9 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 10/13] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 12/13] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Mukesh Ojha
` (2 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
Qualcomm remote processor may rely on static and dynamic resources for
it to be functional. For most of the Qualcomm SoCs, when run with Gunyah
or older QHEE hypervisor, all the resources whether it is static or
dynamic, is managed by the hypervisor. Dynamic resources if it is
present for a remote processor will always be coming from secure world
via SMC call while static resources may be present in remote processor
firmware binary or it may be coming from SMC call along with dynamic
resources.
Remoteproc already has method like rproc_elf_load_rsc_table() to check
firmware binary has resources or not and if it is not having then we
pass NULL and zero as input resource table and its size argument
respectively to qcom_scm_pas_get_rsc_table() and while it has resource
present then it should pass the present resources to Trustzone(TZ) so that
it could authenticate the present resources and append dynamic resource
to return in output_rt argument along with authenticated resources.
Extend parse_fw callback to include SMC call to get resources from
Trustzone and to leverage resource table parsing and mapping and
unmapping code from the remoteproc framework.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/remoteproc/qcom_q6v5_pas.c | 60 ++++++++++++++++++++++++++++++++++++--
1 file changed, 58 insertions(+), 2 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index ee0ea35803c6..1944df49893f 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -34,6 +34,7 @@
#define QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS 100
#define MAX_ASSIGN_COUNT 3
+#define MAX_RSCTABLE_SIZE SZ_16K
struct qcom_pas_data {
int crash_reason_smem;
@@ -413,6 +414,61 @@ static void *qcom_pas_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is
return pas->mem_region + offset;
}
+static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware *fw)
+{
+ size_t output_rt_size = MAX_RSCTABLE_SIZE;
+ struct qcom_pas *pas = rproc->priv;
+ struct resource_table *table = NULL;
+ void *output_rt;
+ size_t table_sz;
+ int ret;
+
+ ret = qcom_register_dump_segments(rproc, fw);
+ if (ret) {
+ dev_err(pas->dev, "Error in registering dump segments\n");
+ return ret;
+ }
+
+ if (!rproc->has_iommu)
+ return ret;
+
+ ret = rproc_elf_load_rsc_table(rproc, fw);
+ if (ret)
+ dev_info(&rproc->dev, "Error in loading resource table from firmware\n");
+
+ table = rproc->table_ptr;
+ table_sz = rproc->table_sz;
+
+ /*
+ * Qualcomm remote processor may rely on static and dynamic resources for
+ * it to be functional. For most of the Qualcomm SoCs, when run with Gunyah
+ * or older QHEE hypervisor, all the resources whether it is static or dynamic,
+ * is managed by present hypervisor. Dynamic resources if it is present for
+ * a remote processor will always be coming from secure world via SMC call
+ * while static resources may be present in remote processor firmware binary
+ * or it may be coming from SMC call along with dynamic resources.
+ *
+ * Here, we call rproc_elf_load_rsc_table() to check firmware binary has resources
+ * or not and if it is not having then we pass NULL and zero as input resource
+ * table pointer and size respectively to the argument of qcom_scm_pas_get_rsc_table()
+ * and this is even true for Qualcomm remote processor who does follow remoteproc
+ * framework.
+ */
+ ret = qcom_scm_pas_get_rsc_table(pas->pas_ctx, table, table_sz, &output_rt,
+ &output_rt_size);
+ if (ret) {
+ dev_err(pas->dev, "Error in getting resource table: %d\n", ret);
+ return ret;
+ }
+
+ kfree(rproc->cached_table);
+ rproc->cached_table = output_rt;
+ rproc->table_ptr = rproc->cached_table;
+ rproc->table_sz = output_rt_size;
+
+ return ret;
+}
+
static unsigned long qcom_pas_panic(struct rproc *rproc)
{
struct qcom_pas *pas = rproc->priv;
@@ -425,7 +481,7 @@ static const struct rproc_ops qcom_pas_ops = {
.start = qcom_pas_start,
.stop = qcom_pas_stop,
.da_to_va = qcom_pas_da_to_va,
- .parse_fw = qcom_register_dump_segments,
+ .parse_fw = qcom_pas_parse_firmware,
.load = qcom_pas_load,
.panic = qcom_pas_panic,
};
@@ -435,7 +491,7 @@ static const struct rproc_ops qcom_pas_minidump_ops = {
.start = qcom_pas_start,
.stop = qcom_pas_stop,
.da_to_va = qcom_pas_da_to_va,
- .parse_fw = qcom_register_dump_segments,
+ .parse_fw = qcom_pas_parse_firmware,
.load = qcom_pas_load,
.panic = qcom_pas_panic,
.coredump = qcom_pas_minidump,
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 12/13] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (10 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 11/13] remoteproc: pas: Extend parse_fw callback to fetch resources via SMC call Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 13/13] arm64: dts: qcom: Add EL2 overlay for Lemans Mukesh Ojha
2025-10-22 10:03 ` [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
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 1944df49893f..8c44987733ca 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);
@@ -836,6 +872,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
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v5 13/13] arm64: dts: qcom: Add EL2 overlay for Lemans
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (11 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 12/13] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Mukesh Ojha
@ 2025-10-13 10:03 ` Mukesh Ojha
2025-10-22 10:03 ` [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 10:03 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Mukesh Ojha
All the Lemans IOT variants boards are using Gunyah hypervisor which
means that, so far, Linux-based OS could only boot in EL1 on those
devices. However, it is possible for us to boot Linux at EL2 on these
devices [1].
When running under Gunyah, remote processor firmware IOMMU streams is
controlled by the Gunyah however when Linux take ownership of it in EL2,
It need to configure it properly to use remote processor.
Add a EL2-specific DT overlay and apply it to Lemans IOT variant
devices to create -el2.dtb for each of them alongside "normal" dtb.
[1]
https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-4/boot-developer-touchpoints.html#uefi
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 8 +++++++
arch/arm64/boot/dts/qcom/lemans-el2.dtso | 41 ++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 296688f7cb26..e0791f987ff9 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -33,8 +33,10 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb
dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb
lemans-evk-camera-csi1-imx577-dtbs := lemans-evk.dtb lemans-evk-camera-csi1-imx577.dtbo
+lemans-evk-el2-dtbs := lemans-evk.dtb lemans-el2.dtbo
dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-camera-csi1-imx577.dtb
+dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-el2.dtb
dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.dtb
@@ -137,6 +139,12 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb
+
+qcs9100-ride-el2-dtbs := qcs9100-ride.dtb lemans-el2.dtbo
+qcs9100-ride-r3-el2-dtbs := qcs9100-ride-r3.dtb lemans-el2.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-el2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3-el2.dtb
dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb
dtb-$(CONFIG_ARCH_QCOM) += qrb2210-rb1.dtb
dtb-$(CONFIG_ARCH_QCOM) += qrb4210-rb2.dtb
diff --git a/arch/arm64/boot/dts/qcom/lemans-el2.dtso b/arch/arm64/boot/dts/qcom/lemans-el2.dtso
new file mode 100644
index 000000000000..af35039946e3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/lemans-el2.dtso
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/*
+ * Lemans specific modifications required to boot in EL2.
+ */
+
+/dts-v1/;
+/plugin/;
+
+&iris {
+ /* More driver work is needed */
+ status = "disabled";
+};
+
+/*
+ * When running under Gunyah, remote processor firmware IOMMU streams is
+ * controlled by the Gunyah however when we take ownership of it in EL2,
+ * we need to configure it properly to use remote processor.
+ */
+&remoteproc_adsp {
+ iommus = <&apps_smmu 0x3000 0x0>;
+};
+
+&remoteproc_cdsp0 {
+ iommus = <&apps_smmu 0x21c0 0x0400>;
+};
+
+&remoteproc_cdsp1 {
+ iommus = <&apps_smmu 0x29c0 0x0400>;
+};
+
+&remoteproc_gpdsp0 {
+ iommus = <&apps_smmu 0x38a0 0x0>;
+};
+
+&remoteproc_gpdsp1 {
+ iommus = <&apps_smmu 0x38c0 0x0>;
+};
--
2.50.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v5 05/13] soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function
2025-10-13 10:03 ` [PATCH v5 05/13] soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function Mukesh Ojha
@ 2025-10-13 12:56 ` Mukesh Ojha
0 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-13 12:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Mathieu Poirier,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel
On Mon, Oct 13, 2025 at 03:33:09PM +0530, Mukesh Ojha wrote:
> Introduce a new PAS context-aware function, qcom_mdt_pas_load(), for
> remote processor drivers. This function utilizes the PAS context
> pointer returned from qcom_scm_pas_ctx_init() to perform firmware
> metadata verification and memory setup via SMC calls.
>
> The qcom_mdt_pas_load() and qcom_mdt_load() functions are largely
> similar, but the former is designed for clients using the PAS
> context-based data structure. Over time, all users of qcom_mdt_load()
> can be migrated to use qcom_mdt_pas_load() for consistency and
> improved abstraction.
>
> As the remoteproc PAS driver (qcom_q6v5_pas) has already adopted the
> PAS context-based approach, update it to use qcom_mdt_pas_load().
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/remoteproc/qcom_q6v5_pas.c | 24 +++++-------------------
> drivers/soc/qcom/mdt_loader.c | 32 ++++++++++++++++++++++++++++++++
> include/linux/soc/qcom/mdt_loader.h | 10 ++++++++++
> 3 files changed, 47 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index e9dcab94ea0c..ee0ea35803c6 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> @@ -239,15 +239,9 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
> return ret;
> }
>
> - ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
> - pas->dtb_pas_id, pas->dtb_mem_phys,
> - pas->dtb_pas_ctx);
> - if (ret)
> - goto release_dtb_firmware;
> -
> - ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
> - pas->dtb_mem_region, pas->dtb_mem_phys,
> - pas->dtb_mem_size, &pas->dtb_mem_reloc);
> + ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware,
> + pas->dtb_firmware_name, pas->dtb_mem_region,
> + &pas->dtb_mem_reloc);
> if (ret)
> goto release_dtb_metadata;
> }
> @@ -256,8 +250,6 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
>
> release_dtb_metadata:
> qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> -
> -release_dtb_firmware:
> release_firmware(pas->dtb_firmware);
>
> return ret;
> @@ -305,14 +297,8 @@ static int qcom_pas_start(struct rproc *rproc)
> }
> }
>
> - ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
> - pas->mem_phys, pas->pas_ctx);
> - if (ret)
> - goto disable_px_supply;
> -
> - ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware,
> - pas->mem_region, pas->mem_phys, pas->mem_size,
> - &pas->mem_reloc);
> + ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware,
> + pas->mem_region, &pas->mem_reloc);
> if (ret)
> goto release_pas_metadata;
>
> diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> index fe35038c5342..52de8adcc4f2 100644
> --- a/drivers/soc/qcom/mdt_loader.c
> +++ b/drivers/soc/qcom/mdt_loader.c
> @@ -486,5 +486,37 @@ int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
> }
> EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init);
>
> +/**
> + * qcom_mdt_pas_load - Loads and authenticates the metadata of the firmware
> + * (typically contained in the .mdt file), followed by loading the actual
> + * firmware segments (e.g., .bXX files). Authentication of the segments done
> + * by a separate call.
> + *
> + * The PAS context must be initialized using qcom_scm_pas_context_init()
> + * prior to invoking this function.
> + *
> + * @ctx: Pointer to the PAS (Peripheral Authentication Service) context
> + * @fw: Firmware object representing the .mdt file
> + * @firmware: Name of the firmware used to construct segment file names
> + * @mem_region: Memory region allocated for loading the firmware
> + * @reloc_base: Physical address adjusted after relocation
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw,
> + const char *firmware, void *mem_region, phys_addr_t *reloc_base)
> +{
> + int ret;
> +
> + ret = qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->pas_id, ctx->mem_phys,
> + ctx->metadata);
s/ctx->metadata/ctx
This has been done 6/13, missed here in patch reordering.
> + if (ret)
> + return ret;
> +
> + return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx->mem_phys,
> + ctx->mem_size, reloc_base);
> +}
> +EXPORT_SYMBOL_GPL(qcom_mdt_pas_load);
> +
> MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format");
> MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
> index 07c278841816..7d57746fbbfa 100644
> --- a/include/linux/soc/qcom/mdt_loader.h
> +++ b/include/linux/soc/qcom/mdt_loader.h
> @@ -23,6 +23,9 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
> phys_addr_t mem_phys, size_t mem_size,
> phys_addr_t *reloc_base);
>
> +int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw,
> + const char *firmware, void *mem_region, phys_addr_t *reloc_base);
> +
> int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
> const char *fw_name, void *mem_region,
> phys_addr_t mem_phys, size_t mem_size,
> @@ -52,6 +55,13 @@ static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
> return -ENODEV;
> }
>
> +static inline int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx,
> + const struct firmware *fw, const char *firmware,
> + void *mem_region, phys_addr_t *reloc_base)
> +{
> + return -ENODEV;
> +}
> +
> static inline int qcom_mdt_load_no_init(struct device *dev,
> const struct firmware *fw,
> const char *fw_name, void *mem_region,
>
> --
> 2.50.1
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 04/13] remoteproc: pas: Replace metadata context with PAS context structure
2025-10-13 10:03 ` [PATCH v5 04/13] remoteproc: pas: Replace metadata context with PAS context structure Mukesh Ojha
@ 2025-10-14 8:24 ` Bryan O'Donoghue
2025-10-15 7:25 ` Mukesh Ojha
0 siblings, 1 reply; 18+ messages in thread
From: Bryan O'Donoghue @ 2025-10-14 8:24 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Manivannan Sadhasivam,
Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel
On 13/10/2025 11:03, Mukesh Ojha wrote:
> As a superset of the existing metadata context, the PAS context
> structure enables both remoteproc and non-remoteproc subsystems to
> better support scenarios where the SoC runs with or without the Gunyah
> hypervisor. To reflect this, relevant SCM and metadata functions are
> updated to incorporate PAS context awareness.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/firmware/qcom/qcom_scm.c | 32 ++++++++++++++++-------------
> drivers/remoteproc/qcom_q6v5_pas.c | 37 ++++++++++++++++++++++++----------
> drivers/soc/qcom/mdt_loader.c | 4 ++--
> include/linux/firmware/qcom/qcom_scm.h | 4 ++--
> include/linux/soc/qcom/mdt_loader.h | 6 +++---
> 5 files changed, 51 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 6d22b2ac7880..b11a21797d46 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -600,7 +600,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
> * and optional blob of data used for authenticating the metadata
> * and the rest of the firmware
> * @size: size of the metadata
> - * @ctx: optional metadata context
> + * @ctx: optional pas context
> *
> * Return: 0 on success.
> *
> @@ -609,8 +609,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
> * qcom_scm_pas_metadata_release() by the caller.
> */
> int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> - struct qcom_scm_pas_metadata *ctx)
> + struct qcom_scm_pas_context *ctx)
> {
> + struct qcom_scm_pas_metadata *mdt_ctx;
> dma_addr_t mdata_phys;
> void *mdata_buf;
> int ret;
> @@ -661,10 +662,11 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> out:
> if (ret < 0 || !ctx) {
> dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
> - } else if (ctx) {
> - ctx->ptr = mdata_buf;
> - ctx->phys = mdata_phys;
> - ctx->size = size;
> + } else if (ctx && ctx->metadata) {
> + mdt_ctx = ctx->metadata;
> + mdt_ctx->ptr = mdata_buf;
> + mdt_ctx->phys = mdata_phys;
> + mdt_ctx->size = size;
Suspicious looking code..
The second check for ctx is redundant as it cannot ever be false. You have
if (ret < 0 || !ctx) {
} else if (ctx && ctx->mdatadata) {
}
The old code was wrong but, that's no reason to continue to be wrong.
Is it currently possible for ctx to be true but ctx->metadata to be false..
void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id,
phys_addr_t mem_phys,
size_t mem_size)
{
struct qcom_scm_pas_context *ctx;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return ERR_PTR(-ENOMEM);
ctx->dev = dev;
ctx->pas_id = pas_id;
ctx->mem_phys = mem_phys;
ctx->mem_size = mem_size;
ctx->metadata = devm_kzalloc(dev, sizeof(*ctx->metadata),
GFP_KERNEL);
if (!ctx->metadata)
return ERR_PTR(-ENOMEM);
return ctx;
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
No.
Lets fix the ctx checking logic in this code as we modify the patch.
> }
>
> return ret ? : res.result[0];
> @@ -673,18 +675,20 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
>
> /**
> * qcom_scm_pas_metadata_release() - release metadata context
> - * @ctx: metadata context
> + * @ctx: pas context
> */
> -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx)
> +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
> {
> - if (!ctx->ptr)
> - return;
> + struct qcom_scm_pas_metadata *mdt_ctx;
>
> - dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
> + mdt_ctx = ctx->metadata;
> + if (!mdt_ctx->ptr)
> + return;
>
> - ctx->ptr = NULL;
> - ctx->phys = 0;
> - ctx->size = 0;
> + dma_free_coherent(__scm->dev, mdt_ctx->size, mdt_ctx->ptr, mdt_ctx->phys);
> + mdt_ctx->ptr = NULL;
> + mdt_ctx->phys = 0;
> + mdt_ctx->size = 0;
> }
If we have established that mdt_ctx->ptr is the fulcurm of truth for
this data then setting ->phys and ->size to anything after setting ->ptr
= NULL are wasted bus cycles.
> EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
>
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index 158bcd6cc85c..e9dcab94ea0c 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> @@ -117,8 +117,8 @@ struct qcom_pas {
> struct qcom_rproc_ssr ssr_subdev;
> struct qcom_sysmon *sysmon;
>
> - struct qcom_scm_pas_metadata pas_metadata;
> - struct qcom_scm_pas_metadata dtb_pas_metadata;
> + struct qcom_scm_pas_context *pas_ctx;
> + struct qcom_scm_pas_context *dtb_pas_ctx;
> };
>
> static void qcom_pas_segment_dump(struct rproc *rproc,
> @@ -211,9 +211,9 @@ static int qcom_pas_unprepare(struct rproc *rproc)
> * auth_and_reset() was successful, but in other cases clean it up
> * here.
> */
> - qcom_scm_pas_metadata_release(&pas->pas_metadata);
> + qcom_scm_pas_metadata_release(pas->pas_ctx);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
>
> return 0;
> }
> @@ -241,7 +241,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
>
> ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
> pas->dtb_pas_id, pas->dtb_mem_phys,
> - &pas->dtb_pas_metadata);
> + pas->dtb_pas_ctx);
> if (ret)
> goto release_dtb_firmware;
>
> @@ -255,7 +255,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
> return 0;
>
> release_dtb_metadata:
> - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
>
> release_dtb_firmware:
> release_firmware(pas->dtb_firmware);
> @@ -306,7 +306,7 @@ static int qcom_pas_start(struct rproc *rproc)
> }
>
> ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
> - pas->mem_phys, &pas->pas_metadata);
> + pas->mem_phys, pas->pas_ctx);
> if (ret)
> goto disable_px_supply;
>
> @@ -332,9 +332,9 @@ static int qcom_pas_start(struct rproc *rproc)
> goto release_pas_metadata;
> }
>
> - qcom_scm_pas_metadata_release(&pas->pas_metadata);
> + qcom_scm_pas_metadata_release(pas->pas_ctx);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
>
> /* firmware is used to pass reference from qcom_pas_start(), drop it now */
> pas->firmware = NULL;
> @@ -342,9 +342,9 @@ static int qcom_pas_start(struct rproc *rproc)
> return 0;
>
> release_pas_metadata:
> - qcom_scm_pas_metadata_release(&pas->pas_metadata);
> + qcom_scm_pas_metadata_release(pas->pas_ctx);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> disable_px_supply:
> if (pas->px_supply)
> regulator_disable(pas->px_supply);
> @@ -779,6 +779,21 @@ static int qcom_pas_probe(struct platform_device *pdev)
> }
>
> qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name);
> +
> + pas->pas_ctx = qcom_scm_pas_context_init(pas->dev, pas->pas_id, pas->mem_phys,
> + pas->mem_size);
> + if (IS_ERR(pas->pas_ctx)) {
> + ret = PTR_ERR(pas->pas_ctx);
> + goto remove_ssr_sysmon;
> + }
> +
> + pas->dtb_pas_ctx = qcom_scm_pas_context_init(pas->dev, pas->dtb_pas_id,
> + pas->dtb_mem_phys, pas->dtb_mem_size);
> + if (IS_ERR(pas->dtb_pas_ctx)) {
> + ret = PTR_ERR(pas->dtb_pas_ctx);
> + goto remove_ssr_sysmon;
> + }
> +
> ret = rproc_add(rproc);
> if (ret)
> goto remove_ssr_sysmon;
> diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> index a5c80d4fcc36..fe35038c5342 100644
> --- a/drivers/soc/qcom/mdt_loader.c
> +++ b/drivers/soc/qcom/mdt_loader.c
> @@ -234,13 +234,13 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
> * @fw_name: name of the firmware, for construction of segment file names
> * @pas_id: PAS identifier
> * @mem_phys: physical address of allocated memory region
> - * @ctx: PAS metadata context, to be released by caller
> + * @ctx: PAS context, ctx->metadata to be released by caller
> *
> * Returns 0 on success, negative errno otherwise.
> */
> int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
> const char *fw_name, int pas_id, phys_addr_t mem_phys,
> - struct qcom_scm_pas_metadata *ctx)
> + struct qcom_scm_pas_context *ctx)
> {
> const struct elf32_phdr *phdrs;
> const struct elf32_phdr *phdr;
> diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> index 75dec515c5d2..7c58d26ede24 100644
> --- a/include/linux/firmware/qcom/qcom_scm.h
> +++ b/include/linux/firmware/qcom/qcom_scm.h
> @@ -83,8 +83,8 @@ struct qcom_scm_pas_context {
> void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t mem_phys,
> size_t mem_size);
> int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> - struct qcom_scm_pas_metadata *ctx);
> -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
> + struct qcom_scm_pas_context *ctx);
> +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx);
> int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
> int qcom_scm_pas_auth_and_reset(u32 pas_id);
> int qcom_scm_pas_shutdown(u32 pas_id);
> diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
> index 8ea8230579a2..07c278841816 100644
> --- a/include/linux/soc/qcom/mdt_loader.h
> +++ b/include/linux/soc/qcom/mdt_loader.h
> @@ -10,14 +10,14 @@
>
> struct device;
> struct firmware;
> -struct qcom_scm_pas_metadata;
> +struct qcom_scm_pas_context;
>
> #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
>
> ssize_t qcom_mdt_get_size(const struct firmware *fw);
> int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
> const char *fw_name, int pas_id, phys_addr_t mem_phys,
> - struct qcom_scm_pas_metadata *pas_metadata_ctx);
> + struct qcom_scm_pas_context *pas_ctx);
> int qcom_mdt_load(struct device *dev, const struct firmware *fw,
> const char *fw_name, int pas_id, void *mem_region,
> phys_addr_t mem_phys, size_t mem_size,
> @@ -39,7 +39,7 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw)
>
> static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
> const char *fw_name, int pas_id, phys_addr_t mem_phys,
> - struct qcom_scm_pas_metadata *pas_metadata_ctx)
> + struct qcom_scm_pas_context *pas_ctx)
> {
> return -ENODEV;
> }
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 04/13] remoteproc: pas: Replace metadata context with PAS context structure
2025-10-14 8:24 ` Bryan O'Donoghue
@ 2025-10-15 7:25 ` Mukesh Ojha
0 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-15 7:25 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Manivannan Sadhasivam,
Konrad Dybcio, linux-arm-msm, linux-remoteproc, devicetree,
linux-kernel
On Tue, Oct 14, 2025 at 09:24:27AM +0100, Bryan O'Donoghue wrote:
> On 13/10/2025 11:03, Mukesh Ojha wrote:
> > As a superset of the existing metadata context, the PAS context
> > structure enables both remoteproc and non-remoteproc subsystems to
> > better support scenarios where the SoC runs with or without the Gunyah
> > hypervisor. To reflect this, relevant SCM and metadata functions are
> > updated to incorporate PAS context awareness.
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/qcom_scm.c | 32 ++++++++++++++++-------------
> > drivers/remoteproc/qcom_q6v5_pas.c | 37 ++++++++++++++++++++++++----------
> > drivers/soc/qcom/mdt_loader.c | 4 ++--
> > include/linux/firmware/qcom/qcom_scm.h | 4 ++--
> > include/linux/soc/qcom/mdt_loader.h | 6 +++---
> > 5 files changed, 51 insertions(+), 32 deletions(-)
> >
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 6d22b2ac7880..b11a21797d46 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -600,7 +600,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
> > * and optional blob of data used for authenticating the metadata
> > * and the rest of the firmware
> > * @size: size of the metadata
> > - * @ctx: optional metadata context
> > + * @ctx: optional pas context
> > *
> > * Return: 0 on success.
> > *
> > @@ -609,8 +609,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
> > * qcom_scm_pas_metadata_release() by the caller.
> > */
> > int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > - struct qcom_scm_pas_metadata *ctx)
> > + struct qcom_scm_pas_context *ctx)
> > {
> > + struct qcom_scm_pas_metadata *mdt_ctx;
> > dma_addr_t mdata_phys;
> > void *mdata_buf;
> > int ret;
> > @@ -661,10 +662,11 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > out:
> > if (ret < 0 || !ctx) {
> > dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
> > - } else if (ctx) {
> > - ctx->ptr = mdata_buf;
> > - ctx->phys = mdata_phys;
> > - ctx->size = size;
`> > + } else if (ctx && ctx->metadata) {
> > + mdt_ctx = ctx->metadata;
> > + mdt_ctx->ptr = mdata_buf;
> > + mdt_ctx->phys = mdata_phys;
> > + mdt_ctx->size = size;
>
> Suspicious looking code..
>
> The second check for ctx is redundant as it cannot ever be false. You have
>
> if (ret < 0 || !ctx) {
> } else if (ctx && ctx->mdatadata) {
> }
>
> The old code was wrong but, that's no reason to continue to be wrong.
>
> Is it currently possible for ctx to be true but ctx->metadata to be false..
>
> void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t
> mem_phys,
> size_t mem_size)
> {
> struct qcom_scm_pas_context *ctx;
>
> ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> if (!ctx)
> return ERR_PTR(-ENOMEM);
>
> ctx->dev = dev;
> ctx->pas_id = pas_id;
> ctx->mem_phys = mem_phys;
> ctx->mem_size = mem_size;
>
> ctx->metadata = devm_kzalloc(dev, sizeof(*ctx->metadata),
> GFP_KERNEL);
> if (!ctx->metadata)
> return ERR_PTR(-ENOMEM);
>
> return ctx;
> }
> EXPORT_SYMBOL_GPL(qcom_scm_pas_context_init);
>
> No.
>
> Lets fix the ctx checking logic in this code as we modify the patch.
Old code was correct, I see your point this could be same as before
for ctx check and metadata check could be dropped as we still have user
from qcom_mdt_load() which could pass ctx as NULL.
> > }
> > return ret ? : res.result[0];
> > @@ -673,18 +675,20 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
> > /**
> > * qcom_scm_pas_metadata_release() - release metadata context
> > - * @ctx: metadata context
> > + * @ctx: pas context
> > */
> > -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx)
> > +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
> > {
> > - if (!ctx->ptr)
> > - return;
> > + struct qcom_scm_pas_metadata *mdt_ctx;
> > - dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
> > + mdt_ctx = ctx->metadata;
> > + if (!mdt_ctx->ptr)
> > + return;
> > - ctx->ptr = NULL;
> > - ctx->phys = 0;
> > - ctx->size = 0;
> > + dma_free_coherent(__scm->dev, mdt_ctx->size, mdt_ctx->ptr, mdt_ctx->phys);
> > + mdt_ctx->ptr = NULL;
> > + mdt_ctx->phys = 0;
> > + mdt_ctx->size = 0;
> > }
>
> If we have established that mdt_ctx->ptr is the fulcurm of truth for this
> data then setting ->phys and ->size to anything after setting ->ptr = NULL
> are wasted bus cycles.
You want me to clean the older code, I will do this.
>
> > EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
> > diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> > index 158bcd6cc85c..e9dcab94ea0c 100644
> > --- a/drivers/remoteproc/qcom_q6v5_pas.c
> > +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> > @@ -117,8 +117,8 @@ struct qcom_pas {
> > struct qcom_rproc_ssr ssr_subdev;
> > struct qcom_sysmon *sysmon;
> > - struct qcom_scm_pas_metadata pas_metadata;
> > - struct qcom_scm_pas_metadata dtb_pas_metadata;
> > + struct qcom_scm_pas_context *pas_ctx;
> > + struct qcom_scm_pas_context *dtb_pas_ctx;
> > };
> > static void qcom_pas_segment_dump(struct rproc *rproc,
> > @@ -211,9 +211,9 @@ static int qcom_pas_unprepare(struct rproc *rproc)
> > * auth_and_reset() was successful, but in other cases clean it up
> > * here.
> > */
> > - qcom_scm_pas_metadata_release(&pas->pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > return 0;
> > }
> > @@ -241,7 +241,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
> > ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
> > pas->dtb_pas_id, pas->dtb_mem_phys,
> > - &pas->dtb_pas_metadata);
> > + pas->dtb_pas_ctx);
> > if (ret)
> > goto release_dtb_firmware;
> > @@ -255,7 +255,7 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
> > return 0;
> > release_dtb_metadata:
> > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > release_dtb_firmware:
> > release_firmware(pas->dtb_firmware);
> > @@ -306,7 +306,7 @@ static int qcom_pas_start(struct rproc *rproc)
> > }
> > ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
> > - pas->mem_phys, &pas->pas_metadata);
> > + pas->mem_phys, pas->pas_ctx);
> > if (ret)
> > goto disable_px_supply;
> > @@ -332,9 +332,9 @@ static int qcom_pas_start(struct rproc *rproc)
> > goto release_pas_metadata;
> > }
> > - qcom_scm_pas_metadata_release(&pas->pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > /* firmware is used to pass reference from qcom_pas_start(), drop it now */
> > pas->firmware = NULL;
> > @@ -342,9 +342,9 @@ static int qcom_pas_start(struct rproc *rproc)
> > return 0;
> > release_pas_metadata:
> > - qcom_scm_pas_metadata_release(&pas->pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > disable_px_supply:
> > if (pas->px_supply)
> > regulator_disable(pas->px_supply);
> > @@ -779,6 +779,21 @@ static int qcom_pas_probe(struct platform_device *pdev)
> > }
> > qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name);
> > +
> > + pas->pas_ctx = qcom_scm_pas_context_init(pas->dev, pas->pas_id, pas->mem_phys,
> > + pas->mem_size);
> > + if (IS_ERR(pas->pas_ctx)) {
> > + ret = PTR_ERR(pas->pas_ctx);
> > + goto remove_ssr_sysmon;
> > + }
> > +
> > + pas->dtb_pas_ctx = qcom_scm_pas_context_init(pas->dev, pas->dtb_pas_id,
> > + pas->dtb_mem_phys, pas->dtb_mem_size);
> > + if (IS_ERR(pas->dtb_pas_ctx)) {
> > + ret = PTR_ERR(pas->dtb_pas_ctx);
> > + goto remove_ssr_sysmon;
> > + }
> > +
> > ret = rproc_add(rproc);
> > if (ret)
> > goto remove_ssr_sysmon;
> > diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> > index a5c80d4fcc36..fe35038c5342 100644
> > --- a/drivers/soc/qcom/mdt_loader.c
> > +++ b/drivers/soc/qcom/mdt_loader.c
> > @@ -234,13 +234,13 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
> > * @fw_name: name of the firmware, for construction of segment file names
> > * @pas_id: PAS identifier
> > * @mem_phys: physical address of allocated memory region
> > - * @ctx: PAS metadata context, to be released by caller
> > + * @ctx: PAS context, ctx->metadata to be released by caller
> > *
> > * Returns 0 on success, negative errno otherwise.
> > */
> > int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
> > const char *fw_name, int pas_id, phys_addr_t mem_phys,
> > - struct qcom_scm_pas_metadata *ctx)
> > + struct qcom_scm_pas_context *ctx)
> > {
> > const struct elf32_phdr *phdrs;
> > const struct elf32_phdr *phdr;
> > diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> > index 75dec515c5d2..7c58d26ede24 100644
> > --- a/include/linux/firmware/qcom/qcom_scm.h
> > +++ b/include/linux/firmware/qcom/qcom_scm.h
> > @@ -83,8 +83,8 @@ struct qcom_scm_pas_context {
> > void *qcom_scm_pas_context_init(struct device *dev, u32 pas_id, phys_addr_t mem_phys,
> > size_t mem_size);
> > int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > - struct qcom_scm_pas_metadata *ctx);
> > -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
> > + struct qcom_scm_pas_context *ctx);
> > +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx);
> > int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
> > int qcom_scm_pas_auth_and_reset(u32 pas_id);
> > int qcom_scm_pas_shutdown(u32 pas_id);
> > diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
> > index 8ea8230579a2..07c278841816 100644
> > --- a/include/linux/soc/qcom/mdt_loader.h
> > +++ b/include/linux/soc/qcom/mdt_loader.h
> > @@ -10,14 +10,14 @@
> > struct device;
> > struct firmware;
> > -struct qcom_scm_pas_metadata;
> > +struct qcom_scm_pas_context;
> > #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
> > ssize_t qcom_mdt_get_size(const struct firmware *fw);
> > int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
> > const char *fw_name, int pas_id, phys_addr_t mem_phys,
> > - struct qcom_scm_pas_metadata *pas_metadata_ctx);
> > + struct qcom_scm_pas_context *pas_ctx);
> > int qcom_mdt_load(struct device *dev, const struct firmware *fw,
> > const char *fw_name, int pas_id, void *mem_region,
> > phys_addr_t mem_phys, size_t mem_size,
> > @@ -39,7 +39,7 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw)
> > static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
> > const char *fw_name, int pas_id, phys_addr_t mem_phys,
> > - struct qcom_scm_pas_metadata *pas_metadata_ctx)
> > + struct qcom_scm_pas_context *pas_ctx)
> > {
> > return -ENODEV;
> > }
> >
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (12 preceding siblings ...)
2025-10-13 10:03 ` [PATCH v5 13/13] arm64: dts: qcom: Add EL2 overlay for Lemans Mukesh Ojha
@ 2025-10-22 10:03 ` Mukesh Ojha
13 siblings, 0 replies; 18+ messages in thread
From: Mukesh Ojha @ 2025-10-22 10:03 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Bryan O'Donoghue, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Manivannan Sadhasivam
Hi Bjorn, Konrad,
Its been a while since I have sent the series on the subjected topic in
the mailing list and has gone few revision addressing most of the review
comments (Thanks to all the reviewers which has helped me to improve the
series) and these patches will also help Glymur in its remoteproc bring up.
Let me know your comments which I can take care along with already
present before I send next revision.
-Mukesh
On Mon, Oct 13, 2025 at 03:33:04PM +0530, Mukesh Ojha wrote:
> A few months ago, we discussed the challenges at Linaro Connect 2025 [1]
> related to Secure PAS remoteproc enablement when Linux is running at EL2.
>
> [1] https://resources.linaro.org/en/resource/sF8jXifdb9V1mUefdbfafa
>
> Below, is the summary of the discussion.
>
> Qualcomm is working to enable remote processors on the SA8775p SoC with
> a Linux host running at EL2. In doing so, it has encountered several
> challenges related to how the remoteproc framework is handled when Linux
> runs at EL1.
>
> One of the main challenges arises from differences in how IOMMU
> translation is currently managed on SoCs running the Qualcomm EL2
> hypervisor (QHEE), where IOMMU translation for any device is entirely
> owned by the hypervisor. Additionally, the firmware for remote
> processors does not contain a resource table, which would typically
> include the necessary IOMMU configuration settings.
>
> Qualcomm SoCs running with QHEE (EL2) have been utilizing the Peripheral
> Authentication Service (PAS) from TrustZone (TZ) firmware to securely
> authenticate and reset remote processors via a single SMC call,
> _auth_and_reset_. This call is first trapped by QHEE, which then invokes
> TZ for authentication. Once authentication is complete, the call returns
> to QHEE, which sets up the IOMMU translation scheme for the remote
> processors and subsequently brings them out of reset. The design of the
> Qualcomm EL2 hypervisor dictates that the Linux host OS running at EL1
> is not permitted to configure IOMMU translation for remote processors,
> and only a single-stage translation is configured.
>
> To make the remote processor bring-up (PAS) sequence
> hypervisor-independent, the auth_and_reset SMC call is now handled
> entirely by TZ. However, the issue of IOMMU configuration remains
> unresolved, for example a scenario, when KVM host at EL2 has no
> knowledge of the remote processors’ IOMMU settings. This is being
> addressed by overlaying the IOMMU properties when the SoC runs a Linux
> host at EL2. SMC call is being provided from the TrustZone firmware to
> retrieve the resource table for a given subsystem.
>
> There are also remote processors such as those for video, camera, and
> graphics that do not use the remoteproc framework to manage their
> lifecycle. Instead, they rely on the Qualcomm PAS service to
> authenticate their firmware. These processors also need to be brought
> out of reset when Linux is running at EL2. The client drivers for these
> processors use the MDT loader function to load and authenticate
> firmware. Similar to the Qualcomm remoteproc PAS driver, they also need
> to retrieve the resource table, create a shared memory bridge
> (shmbridge), and map the resources before bringing the processors out of
> reset.
>
> It is based on next-20251010 and tested on SA8775p which is now called
> Lemans IOT platform and does not addresses DMA problem discussed at
> [1] which is future scope of the series.
>
> Note that there is a regression on booting KVM on Qualcomm SoCs after
> commit efad60e46057 ("KVM: arm64: Initialize PMSCR_EL1 when in VHE").
> A fix has been purposed here
> https://lore.kernel.org/lkml/20251010174707.1684200-1-mukesh.ojha@oss.qualcomm.com/
>
> Changes in v5: https://lore.kernel.org/lkml/20251007-kvm_rprocv4_next-20251007-v4-0-de841623af3c@oss.qualcomm.com/
> - Replaced minitems with maxitems.
> - Addressed comments made by Bryan, Mani and Konrad.
> - Fixed some of highlighted issues in v4.
> - Added a new patch which removes qcom_mdt_pas_init() from exported
> symbol list.
> - Slight change in v4's 5/12, so that it does use qcom_mdt_pas_load()
> directly while it should use in the commit where it gets introduced.
> Hence, reordered the patches a bit like v4 5/12 comes early before
> 4/12.
>
> Changes in v4: https://lore.kernel.org/lkml/20250921-kvm_rproc_pas-v3-0-458f09647920@oss.qualcomm.com/
> - Fixed kernel robot warning/errors.
> - Reworded some of the commit log, code comment as per suggestion from Bryan.
> - Added support of gpdsp0 and gpdsp1 and disabled iris node.
> - Add R-b tag to some of the reviewed patches.
> - Rename struct qcom_scm_pas_cxt to qcom_scm_pas_context.
>
> Changes in v3: https://lore.kernel.org/lkml/20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com/
> - Dropped video subsystem enablement for now, could add it in future
> or on a separate series.
> - Addressed most of the suggestion from Stephen and Bryan like some
> remoteproc code checking resource table presence or right error
> code propagation above the layer.
> - Added leman-el2 overlay file.
> - Added missed iommus binding which was missed last series.
> - Separated qcom_mdt_pas_load() patch and its usage.
> - Patch numbering got changed compared to last version
>
> Changes in v2: https://lore.kernel.org/lkml/20241004212359.2263502-1-quic_mojha@quicinc.com/
> - A lot has changed from the V1 and a fresh look would be preferred.
> - Removed approach where device tree contain devmem resources in
> remoteproc node.
> - SHMbridge need to created for both carveout and metadata memory
> shared to TZ in a new way.
> - Now, resource table would be given by SMC call which need to mapped
> along with carveout before triggering _auth_and_reset_.
> - IOMMU properties need to be added to firmware devices tree node when Linux
> control IOMMU.
>
> ---
> Mukesh Ojha (13):
> dt-bindings: remoteproc: qcom,pas: Add iommus property
> firmware: qcom_scm: Rename peripheral as pas_id
> firmware: qcom_scm: Introduce PAS context initialization helper function
> remoteproc: pas: Replace metadata context with PAS context structure
> soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function
> soc: qcom: mdtloader: Remove qcom_mdt_pas_init() from exported symbols
> firmware: qcom_scm: Add a prep version of auth_and_reset function
> firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
> firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE
> firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
> remoteproc: pas: Extend parse_fw callback to fetch resources via SMC call
> remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
> arm64: dts: qcom: Add EL2 overlay for Lemans
>
> .../bindings/remoteproc/qcom,pas-common.yaml | 3 +
> arch/arm64/boot/dts/qcom/Makefile | 8 +
> arch/arm64/boot/dts/qcom/lemans-el2.dtso | 41 +++
> drivers/firmware/qcom/qcom_scm.c | 394 ++++++++++++++++++---
> drivers/firmware/qcom/qcom_scm.h | 1 +
> drivers/remoteproc/qcom_q6v5_pas.c | 165 +++++++--
> drivers/soc/qcom/mdt_loader.c | 42 ++-
> include/linux/firmware/qcom/qcom_scm.h | 35 +-
> include/linux/soc/qcom/mdt_loader.h | 22 +-
> 9 files changed, 598 insertions(+), 113 deletions(-)
> ---
> base-commit: 2b763d4652393c90eaa771a5164502ec9dd965ae
> change-id: 20251013-kvm_rprocv5-d24c1407a7c9
>
> Best regards,
> --
> -Mukesh Ojha
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-10-22 10:03 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-13 10:03 [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 01/13] dt-bindings: remoteproc: qcom,pas: Add iommus property Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 02/13] firmware: qcom_scm: Rename peripheral as pas_id Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 03/13] firmware: qcom_scm: Introduce PAS context initialization helper function Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 04/13] remoteproc: pas: Replace metadata context with PAS context structure Mukesh Ojha
2025-10-14 8:24 ` Bryan O'Donoghue
2025-10-15 7:25 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 05/13] soc: qcom: mdtloader: Add PAS context aware qcom_mdt_pas_load() function Mukesh Ojha
2025-10-13 12:56 ` Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 06/13] soc: qcom: mdtloader: Remove qcom_mdt_pas_init() from exported symbols Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 07/13] firmware: qcom_scm: Add a prep version of auth_and_reset function Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 08/13] firmware: qcom_scm: Simplify qcom_scm_pas_init_image() Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 09/13] firmware: qcom_scm: Add SHM bridge handling for PAS when running without QHEE Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 10/13] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 11/13] remoteproc: pas: Extend parse_fw callback to fetch resources via SMC call Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 12/13] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Mukesh Ojha
2025-10-13 10:03 ` [PATCH v5 13/13] arm64: dts: qcom: Add EL2 overlay for Lemans Mukesh Ojha
2025-10-22 10:03 ` [PATCH v5 00/13] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).