* [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
@ 2025-08-19 16:54 Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper Mukesh Ojha
` (11 more replies)
0 siblings, 12 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
This is a further continuation with a new approach to the topic
discussed in [1] regarding the enablement of Secure Peripheral Image
Loader support on Qualcomm SoCs when Linux runs at EL2.
A few months ago, we also discussed the challenges at Linaro Connect
2025 [2] related to enabling remoteproc when Linux is running at EL2.
[1]
https://lore.kernel.org/lkml/20241004212359.2263502-1-quic_mojha@quicinc.com/
[2]
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.
This series has dependency on below patch for creating SHMbridge over
carveout memory.
https://lore.kernel.org/lkml/20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com/
Series is tested on SA8775p which is now called Lemans IOT platform and
the series does not addresses DMA problem discussed at [2] which is future
scope of the series.
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 (11):
firmware: qcom_scm: Introduce PAS context initialization helper
soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
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 shmbridge support to pas_init/release function
remoteproc: Move resource table data structure to its own header
firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource
table
soc: qcom: mdt_loader: Add helper functions to map and unmap resources
remoteproc: pas: Extend parse_fw callback to parse resource table
remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by
Linux
media: iris: Enable Secure PAS support with IOMMU managed by Linux
drivers/firmware/qcom/qcom_scm.c | 360 ++++++++++++++++--
drivers/firmware/qcom/qcom_scm.h | 1 +
drivers/media/platform/qcom/iris/iris_core.c | 9 +-
drivers/media/platform/qcom/iris/iris_core.h | 6 +
.../media/platform/qcom/iris/iris_firmware.c | 156 +++++++-
.../media/platform/qcom/iris/iris_firmware.h | 2 +
drivers/remoteproc/qcom_q6v5_pas.c | 147 +++++--
drivers/soc/qcom/mdt_loader.c | 199 +++++++++-
include/linux/firmware/qcom/qcom_scm.h | 27 +-
include/linux/remoteproc.h | 269 +------------
include/linux/rsc_table.h | 306 +++++++++++++++
include/linux/soc/qcom/mdt_loader.h | 41 +-
12 files changed, 1144 insertions(+), 379 deletions(-)
create mode 100644 include/linux/rsc_table.h
--
2.50.1
^ permalink raw reply [flat|nested] 74+ messages in thread
* [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-19 17:17 ` Pavan Kondeti
2025-08-20 11:40 ` Bryan O'Donoghue
2025-08-19 16:54 ` [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper Mukesh Ojha
` (10 subsequent siblings)
11 siblings, 2 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Currently, remoteproc and non-remoteproc subsystems use different
variants of the MDT loader helper API, primarily due to the handling of
the metadata context. Remoteproc subsystems retain this context until
authentication and reset, while non-remoteproc subsystems (e.g., video,
graphics) do not require it.
Unify the metadata loading process for both remoteproc and
non-remoteproc subsystems by introducing a dedicated PAS context
initialization function.
By introducing qcom_scm_pas_ctx_init(), we can standardize the API usage
across subsystems and reduce the number of parameters passed to MDT
loader functions, improving code clarity and maintainability.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 26 ++++++++++++++++++++++++++
include/linux/firmware/qcom/qcom_scm.h | 11 +++++++++++
2 files changed, 37 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 96d5cf40a74c..33187d4f4aef 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -558,6 +558,32 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
}
+void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
+ size_t mem_size, bool save_mdt_ctx)
+{
+ struct qcom_scm_pas_ctx *ctx;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ ctx->dev = dev;
+ ctx->peripheral = peripheral;
+ ctx->mem_phys = mem_phys;
+ ctx->mem_size = mem_size;
+ ctx->save_mdt_ctx = save_mdt_ctx;
+ ctx->metadata = NULL;
+
+ if (save_mdt_ctx) {
+ ctx->metadata = devm_kzalloc(dev, sizeof(*ctx->metadata), GFP_KERNEL);
+ if (!ctx->metadata)
+ return NULL;
+ }
+
+ return ctx;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_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 a55ca771286b..b7eb206561a9 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -72,6 +72,17 @@ struct qcom_scm_pas_metadata {
ssize_t size;
};
+struct qcom_scm_pas_ctx {
+ struct device *dev;
+ u32 peripheral;
+ phys_addr_t mem_phys;
+ size_t mem_size;
+ struct qcom_scm_pas_metadata *metadata;
+ bool save_mdt_ctx;
+};
+
+void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
+ size_t mem_size, bool save_mdt_ctx);
int qcom_scm_pas_init_image(u32 peripheral, 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] 74+ messages in thread
* [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-20 11:48 ` Bryan O'Donoghue
2025-09-03 15:03 ` Bryan O'Donoghue
2025-08-19 16:54 ` [PATCH v2 03/11] firmware: qcom_scm: Add a prep version of auth_and_reset function Mukesh Ojha
` (9 subsequent siblings)
11 siblings, 2 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Currently, remoteproc and non-remoteproc subsystems use different
variants of the MDT loader helper API, primarily due to the handling of
the metadata context. Remoteproc subsystems retain this context until
authentication and reset, while non-remoteproc subsystems (e.g., video,
graphics) do not require it.
Add context aware qcom_mdt_pas_load() function which uses context
returned from qcom_scm_pas_ctx_init() and use it till subsystems
is out of set. This will also help in unifying the API used by
remoteproc and non-remoteproc subsystems drivers.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
If this approach is preferred, will convert all subsystem drivers to use the
same set of API's using context and completely get away with qcom_mdt_load()
-Mukesh
drivers/remoteproc/qcom_q6v5_pas.c | 53 ++++++++++++++---------------
drivers/soc/qcom/mdt_loader.c | 26 ++++++++++----
include/linux/soc/qcom/mdt_loader.h | 22 ++++++------
3 files changed, 56 insertions(+), 45 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 55a7da801183..e376c0338576 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -115,8 +115,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_ctx *pas_ctx;
+ struct qcom_scm_pas_ctx *dtb_pas_ctx;
};
static void qcom_pas_segment_dump(struct rproc *rproc,
@@ -209,9 +209,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->metadata);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
return 0;
}
@@ -235,15 +235,8 @@ 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_metadata);
- 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;
}
@@ -251,9 +244,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);
-
-release_dtb_firmware:
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
release_firmware(pas->dtb_firmware);
return ret;
@@ -301,14 +292,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_metadata);
- 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->dtb_mem_reloc);
if (ret)
goto release_pas_metadata;
@@ -328,9 +313,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->metadata);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
/* firmware is used to pass reference from qcom_pas_start(), drop it now */
pas->firmware = NULL;
@@ -338,9 +323,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->metadata);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
disable_px_supply:
if (pas->px_supply)
regulator_disable(pas->px_supply);
@@ -774,6 +759,18 @@ 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_ctx_init(pas->dev, pas->pas_id, pas->mem_phys,
+ pas->mem_size, true);
+ if (!pas->pas_ctx)
+ goto remove_ssr_sysmon;
+
+ pas->dtb_pas_ctx = qcom_scm_pas_ctx_init(pas->dev, pas->dtb_pas_id,
+ pas->dtb_mem_phys, pas->dtb_mem_size,
+ true);
+ if (!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..509ff85d9bf6 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -228,7 +228,7 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
/**
- * qcom_mdt_pas_init() - initialize PAS region for firmware loading
+ * __qcom_mdt_pas_init() - initialize PAS region for firmware loading
* @dev: device handle to associate resources with
* @fw: firmware object for the mdt file
* @fw_name: name of the firmware, for construction of segment file names
@@ -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_metadata *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_metadata *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;
@@ -486,5 +485,20 @@ int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
}
EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init);
+int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *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->peripheral,
+ 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 8ea8230579a2..450fa0be2af0 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -10,19 +10,20 @@
struct device;
struct firmware;
-struct qcom_scm_pas_metadata;
+struct qcom_scm_pas_ctx;
#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);
+
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,
phys_addr_t *reloc_base);
+int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *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,
@@ -37,13 +38,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_metadata *pas_metadata_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,
@@ -52,6 +46,12 @@ static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
return -ENODEV;
}
+int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *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] 74+ messages in thread
* [PATCH v2 03/11] firmware: qcom_scm: Add a prep version of auth_and_reset function
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-20 12:03 ` Bryan O'Donoghue
2025-08-19 16:54 ` [PATCH v2 04/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image() Mukesh Ojha
` (8 subsequent siblings)
11 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Qualcomm SoCs running with QHEE (Qualcomm Hypervisor Execution
Environment—a library present in the Gunyah hypervisor) utilize the
Peripheral Authentication Service (PAS) from TrustZone (TZ) firmware to
securely authenticate and reset remote processors via a sequence of SMC
calls such as qcom_scm_pas_init_image(), qcom_scm_pas_mem_setup(), and
qcom_scm_pas_auth_and_reset().
For memory passed to Qualcomm TrustZone, it must either be part of a
pool registered with TZ or be directly registered via SHMbridge SMC
calls.
When QHEE is present, PAS SMC calls from Linux running at EL1 are
trapped by QHEE (running at EL2), which then creates or retrieves memory
from the SHMbridge for both metadata and remoteproc carveout memory
before passing them to TZ. However, when the SoC runs with a
non-QHEE-based hypervisor, Linux must create the SHM bridge for both
metadata (before it is passed to TZ in qcom_scm_pas_init_image()) and
for remoteproc memory (before the call is made to TZ in
qcom_scm_pas_auth_and_reset()).
For auth_and_reset() call, first it need to register remoteproc carveout
memory with TZ via SHMbridge SMC call and then it can trigger
auth_and_reset SMC call and once the call returns, remoteproc carveout
memory can be deregisterd with TZ.
Add qcom_scm_pas_prepare_and_auth_reset() function which does prepare
the SHMbridge over carveout memory and call auth_and_reset SMC call.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 46 ++++++++++++++++++++++++++
include/linux/firmware/qcom/qcom_scm.h | 2 ++
2 files changed, 48 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 33187d4f4aef..9a5b34f5bacb 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -759,6 +759,52 @@ int qcom_scm_pas_auth_and_reset(u32 peripheral)
}
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_ctx_init()
+ *
+ * This function performs the necessary steps to prepare a PAS subsystem,
+ * authenticate it using the provided metadata, and initiate a reset sequence.
+ *
+ * It is typically used when Linux is in control setting up the IOMMU hardware
+ * for remote subsystem during secure firmware loading processes. The preparation
+ * step sets up shmbridge over the firmware memory before TrustZone access 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_ctx *ctx)
+{
+ u64 handle;
+ int ret;
+
+ if (!ctx->has_iommu)
+ return qcom_scm_pas_auth_and_reset(ctx->peripheral);
+
+ /*
+ * When Linux running at EL1, Gunyah(EL2) traps auth_and_reset call and creates
+ * shmbridge on subsystem memory region before it passes the call to TrustZone
+ * to authenticate it while when Linux runs at EL2, it needs to create shmbridge
+ * before this call goes to TrustZone.
+ */
+ ret = qcom_tzmem_shm_bridge_create(ctx->mem_phys, ctx->mem_size, &handle);
+ if (ret) {
+ dev_err(__scm->dev, "Failed to create shmbridge ret=%d %u\n",
+ ret, ctx->peripheral);
+ return ret;
+ }
+
+ ret = qcom_scm_pas_auth_and_reset(ctx->peripheral);
+ 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
* @peripheral: peripheral id
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index b7eb206561a9..a31006fe49a9 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -79,6 +79,7 @@ struct qcom_scm_pas_ctx {
size_t mem_size;
struct qcom_scm_pas_metadata *metadata;
bool save_mdt_ctx;
+ bool has_iommu;
};
void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
@@ -87,6 +88,7 @@ int qcom_scm_pas_init_image(u32 peripheral, 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_prepare_and_auth_reset(struct qcom_scm_pas_ctx *ctx);
int qcom_scm_pas_auth_and_reset(u32 peripheral);
int qcom_scm_pas_shutdown(u32 peripheral);
bool qcom_scm_pas_supported(u32 peripheral);
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* [PATCH v2 04/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (2 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 03/11] firmware: qcom_scm: Add a prep version of auth_and_reset function Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-21 14:36 ` Bryan O'Donoghue
2025-08-19 16:54 ` [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function Mukesh Ojha
` (7 subsequent siblings)
11 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Simplify qcom_scm_pas_init_image() by making the memory
allocation, copy and free work in a separate function
then the actual SMC call.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 59 ++++++++++++++++++--------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 9a5b34f5bacb..7827699e277c 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -584,6 +584,38 @@ void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
+static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
+ void *metadata, size_t size,
+ struct qcom_scm_res *res)
+{
+ 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] = peripheral,
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+
+ 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
@@ -604,17 +636,10 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
struct qcom_scm_pas_metadata *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] = peripheral,
- .owner = ARM_SMCCC_OWNER_SIP,
- };
- struct qcom_scm_res res;
/*
* During the scm call memory protection will be enabled for the meta
@@ -635,23 +660,7 @@ int qcom_scm_pas_init_image(u32 peripheral, 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(peripheral, mdata_phys, mdata_buf, size, &res);
if (ret < 0 || !ctx) {
dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
} else if (ctx) {
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (3 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 04/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image() Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-21 15:23 ` Bryan O'Donoghue
2025-08-19 16:54 ` [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header Mukesh Ojha
` (6 subsequent siblings)
11 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Qualcomm SoCs running with QHEE (Qualcomm Hypervisor Execution
Environment—a library present in the Gunyah hypervisor) utilize the
Peripheral Authentication Service (PAS) from Qualcomm TrustZone (TZ)
also called QTEE(Qualcomm Trusted Execution Environment firmware)
to securely authenticate and reset remote processors via a sequence
of SMC calls such as qcom_scm_pas_init_image(), qcom_scm_pas_mem_setup(),
and qcom_scm_pas_auth_and_reset().
For memory passed to Qualcomm TrustZone, it must either be part of a
pool registered with TZ or be directly registered via SHMbridge SMC
calls.
When QHEE is present, PAS SMC calls from Linux running at EL1 are
trapped by QHEE (running at EL2), which then creates or retrieves memory
from the SHM bridge for both metadata and remoteproc carveout memory
before passing them to TZ. However, when the SoC runs with a
non-QHEE-based hypervisor, Linux must create the SHM bridge for both
metadata (before it is passed to TZ in qcom_scm_pas_init_image()) and
for remoteproc memory (before the call is made to TZ in
qcom_scm_pas_auth_and_reset()).
For the qcom_scm_pas_init_image() call, metadata content must be copied
to a buffer allocated from the SHM bridge before making the SMC call.
This buffer should be freed either immediately after the call or during
the qcom_scm_pas_metadata_release() function, depending on the context
parameter passed to qcom_scm_pas_init_image(). Convert the metadata
context parameter to use PAS context data structure so that it will also
be possible to decide whether to get memory from SHMbridge pool or not.
When QHEE is present, it manages the IOMMU translation context so, in
absence of it device driver will be aware through device tree that its
translation context is managed by Linux and it need to create SHMbridge
before passing any buffer to TZ, So, remote processor driver should
appropriately set ctx->has_iommu to let PAS SMC function to take care of
everything ready for the call to work.
Lets convert qcom_scm_pas_init_image() and qcom_scm_pas_metadata_release()
to have these awareness.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 71 +++++++++++++++++++++-----
drivers/remoteproc/qcom_q6v5_pas.c | 14 ++---
drivers/soc/qcom/mdt_loader.c | 4 +-
include/linux/firmware/qcom/qcom_scm.h | 9 ++--
4 files changed, 73 insertions(+), 25 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 7827699e277c..301d440f62f3 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -616,6 +616,35 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
return ret;
}
+static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_ctx *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->peripheral, 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
@@ -625,7 +654,7 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
* 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.
*
@@ -634,13 +663,19 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
* qcom_scm_pas_metadata_release() by the caller.
*/
int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
- struct qcom_scm_pas_metadata *ctx)
+ struct qcom_scm_pas_ctx *ctx)
{
+ struct qcom_scm_pas_metadata *mdt_ctx;
struct qcom_scm_res res;
dma_addr_t mdata_phys;
void *mdata_buf;
int ret;
+ if (ctx && ctx->has_iommu) {
+ ret = qcom_scm_pas_prep_and_init_image(ctx, metadata, size);
+ return ret;
+ }
+
/*
* During the scm call memory protection will be enabled for the meta
* data blob, so make sure it's physically contiguous, 4K aligned and
@@ -663,10 +698,11 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
ret = __qcom_scm_pas_init_image(peripheral, mdata_phys, mdata_buf, size, &res);
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->metadata) {
+ mdt_ctx = ctx->metadata;
+ mdt_ctx->ptr = mdata_buf;
+ mdt_ctx->addr.dma_addr = mdata_phys;
+ mdt_ctx->size = size;
}
return ret ? : res.result[0];
@@ -675,18 +711,27 @@ 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_ctx *ctx)
{
- if (!ctx->ptr)
+ struct qcom_scm_pas_metadata *mdt_ctx;
+
+ mdt_ctx = ctx->metadata;
+ if (!mdt_ctx->ptr)
return;
- dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, 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;
+ }
- ctx->ptr = NULL;
- ctx->phys = 0;
- ctx->size = 0;
+ mdt_ctx->ptr = NULL;
+ 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 e376c0338576..09cada92dfd5 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -209,9 +209,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_ctx->metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
return 0;
}
@@ -244,7 +244,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_ctx->metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
release_firmware(pas->dtb_firmware);
return ret;
@@ -313,9 +313,9 @@ static int qcom_pas_start(struct rproc *rproc)
goto release_pas_metadata;
}
- qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->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;
@@ -323,9 +323,9 @@ static int qcom_pas_start(struct rproc *rproc)
return 0;
release_pas_metadata:
- qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
+ qcom_scm_pas_metadata_release(pas->pas_ctx);
if (pas->dtb_pas_id)
- qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
+ qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
disable_px_supply:
if (pas->px_supply)
regulator_disable(pas->px_supply);
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index 509ff85d9bf6..a1718db91b3e 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
*/
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_metadata *ctx)
+ struct qcom_scm_pas_ctx *ctx)
{
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
@@ -491,7 +491,7 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
int ret;
ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->peripheral,
- ctx->mem_phys, ctx->metadata);
+ ctx->mem_phys, ctx);
if (ret)
return ret;
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index a31006fe49a9..bd3417d9c3f9 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;
};
@@ -85,8 +88,8 @@ struct qcom_scm_pas_ctx {
void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
size_t mem_size, bool save_mdt_ctx);
int qcom_scm_pas_init_image(u32 peripheral, 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_ctx *ctx);
+void qcom_scm_pas_metadata_release(struct qcom_scm_pas_ctx *ctx);
int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_ctx *ctx);
int qcom_scm_pas_auth_and_reset(u32 peripheral);
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (4 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-20 8:12 ` Stephan Gerhold
2025-08-19 16:54 ` [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Mukesh Ojha
` (5 subsequent siblings)
11 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
The resource table data structure has traditionally been associated with
the remoteproc framework, where the resource table is included as a
section within the remote processor firmware binary. However, it is also
possible to obtain the resource table through other means—such as from a
reserved memory region populated by the boot firmware, statically
maintained driver data, or via a secure SMC call—when it is not embedded
in the firmware.
There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
etc.) in the upstream kernel that do not use the remoteproc framework to
manage their lifecycle for various reasons.
When Linux is running at EL2, similar to the Qualcomm PAS driver
(qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
also want to use the resource table SMC call to retrieve and map
resources before they are used by the remote processor.
In such cases, the resource table data structure is no longer tightly
coupled with the remoteproc headers. Client drivers that do not use the
remoteproc framework should still be able to parse the resource table
obtained through alternative means. Therefore, there is a need to
decouple the resource table definitions from the remoteproc headers.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
include/linux/remoteproc.h | 269 +-------------------------------
include/linux/rsc_table.h | 306 +++++++++++++++++++++++++++++++++++++
2 files changed, 307 insertions(+), 268 deletions(-)
create mode 100644 include/linux/rsc_table.h
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index b4795698d8c2..7c1546d48008 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -42,274 +42,7 @@
#include <linux/completion.h>
#include <linux/idr.h>
#include <linux/of.h>
-
-/**
- * struct resource_table - firmware resource table header
- * @ver: version number
- * @num: number of resource entries
- * @reserved: reserved (must be zero)
- * @offset: array of offsets pointing at the various resource entries
- *
- * A resource table is essentially a list of system resources required
- * by the remote processor. It may also include configuration entries.
- * If needed, the remote processor firmware should contain this table
- * as a dedicated ".resource_table" ELF section.
- *
- * Some resources entries are mere announcements, where the host is informed
- * of specific remoteproc configuration. Other entries require the host to
- * do something (e.g. allocate a system resource). Sometimes a negotiation
- * is expected, where the firmware requests a resource, and once allocated,
- * the host should provide back its details (e.g. address of an allocated
- * memory region).
- *
- * The header of the resource table, as expressed by this structure,
- * contains a version number (should we need to change this format in the
- * future), the number of available resource entries, and their offsets
- * in the table.
- *
- * Immediately following this header are the resource entries themselves,
- * each of which begins with a resource entry header (as described below).
- */
-struct resource_table {
- u32 ver;
- u32 num;
- u32 reserved[2];
- u32 offset[];
-} __packed;
-
-/**
- * struct fw_rsc_hdr - firmware resource entry header
- * @type: resource type
- * @data: resource data
- *
- * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
- * its @type. The content of the entry itself will immediately follow
- * this header, and it should be parsed according to the resource type.
- */
-struct fw_rsc_hdr {
- u32 type;
- u8 data[];
-} __packed;
-
-/**
- * enum fw_resource_type - types of resource entries
- *
- * @RSC_CARVEOUT: request for allocation of a physically contiguous
- * memory region.
- * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
- * @RSC_TRACE: announces the availability of a trace buffer into which
- * the remote processor will be writing logs.
- * @RSC_VDEV: declare support for a virtio device, and serve as its
- * virtio header.
- * @RSC_LAST: just keep this one at the end of standard resources
- * @RSC_VENDOR_START: start of the vendor specific resource types range
- * @RSC_VENDOR_END: end of the vendor specific resource types range
- *
- * For more details regarding a specific resource type, please see its
- * dedicated structure below.
- *
- * Please note that these values are used as indices to the rproc_handle_rsc
- * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
- * check the validity of an index before the lookup table is accessed, so
- * please update it as needed.
- */
-enum fw_resource_type {
- RSC_CARVEOUT = 0,
- RSC_DEVMEM = 1,
- RSC_TRACE = 2,
- RSC_VDEV = 3,
- RSC_LAST = 4,
- RSC_VENDOR_START = 128,
- RSC_VENDOR_END = 512,
-};
-
-#define FW_RSC_ADDR_ANY (-1)
-
-/**
- * struct fw_rsc_carveout - physically contiguous memory request
- * @da: device address
- * @pa: physical address
- * @len: length (in bytes)
- * @flags: iommu protection flags
- * @reserved: reserved (must be zero)
- * @name: human-readable name of the requested memory region
- *
- * This resource entry requests the host to allocate a physically contiguous
- * memory region.
- *
- * These request entries should precede other firmware resource entries,
- * as other entries might request placing other data objects inside
- * these memory regions (e.g. data/code segments, trace resource entries, ...).
- *
- * Allocating memory this way helps utilizing the reserved physical memory
- * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
- * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
- * pressure is important; it may have a substantial impact on performance.
- *
- * If the firmware is compiled with static addresses, then @da should specify
- * the expected device address of this memory region. If @da is set to
- * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
- * overwrite @da with the dynamically allocated address.
- *
- * We will always use @da to negotiate the device addresses, even if it
- * isn't using an iommu. In that case, though, it will obviously contain
- * physical addresses.
- *
- * Some remote processors needs to know the allocated physical address
- * even if they do use an iommu. This is needed, e.g., if they control
- * hardware accelerators which access the physical memory directly (this
- * is the case with OMAP4 for instance). In that case, the host will
- * overwrite @pa with the dynamically allocated physical address.
- * Generally we don't want to expose physical addresses if we don't have to
- * (remote processors are generally _not_ trusted), so we might want to
- * change this to happen _only_ when explicitly required by the hardware.
- *
- * @flags is used to provide IOMMU protection flags, and @name should
- * (optionally) contain a human readable name of this carveout region
- * (mainly for debugging purposes).
- */
-struct fw_rsc_carveout {
- u32 da;
- u32 pa;
- u32 len;
- u32 flags;
- u32 reserved;
- u8 name[32];
-} __packed;
-
-/**
- * struct fw_rsc_devmem - iommu mapping request
- * @da: device address
- * @pa: physical address
- * @len: length (in bytes)
- * @flags: iommu protection flags
- * @reserved: reserved (must be zero)
- * @name: human-readable name of the requested region to be mapped
- *
- * This resource entry requests the host to iommu map a physically contiguous
- * memory region. This is needed in case the remote processor requires
- * access to certain memory-based peripherals; _never_ use it to access
- * regular memory.
- *
- * This is obviously only needed if the remote processor is accessing memory
- * via an iommu.
- *
- * @da should specify the required device address, @pa should specify
- * the physical address we want to map, @len should specify the size of
- * the mapping and @flags is the IOMMU protection flags. As always, @name may
- * (optionally) contain a human readable name of this mapping (mainly for
- * debugging purposes).
- *
- * Note: at this point we just "trust" those devmem entries to contain valid
- * physical addresses, but this isn't safe and will be changed: eventually we
- * want remoteproc implementations to provide us ranges of physical addresses
- * the firmware is allowed to request, and not allow firmwares to request
- * access to physical addresses that are outside those ranges.
- */
-struct fw_rsc_devmem {
- u32 da;
- u32 pa;
- u32 len;
- u32 flags;
- u32 reserved;
- u8 name[32];
-} __packed;
-
-/**
- * struct fw_rsc_trace - trace buffer declaration
- * @da: device address
- * @len: length (in bytes)
- * @reserved: reserved (must be zero)
- * @name: human-readable name of the trace buffer
- *
- * This resource entry provides the host information about a trace buffer
- * into which the remote processor will write log messages.
- *
- * @da specifies the device address of the buffer, @len specifies
- * its size, and @name may contain a human readable name of the trace buffer.
- *
- * After booting the remote processor, the trace buffers are exposed to the
- * user via debugfs entries (called trace0, trace1, etc..).
- */
-struct fw_rsc_trace {
- u32 da;
- u32 len;
- u32 reserved;
- u8 name[32];
-} __packed;
-
-/**
- * struct fw_rsc_vdev_vring - vring descriptor entry
- * @da: device address
- * @align: the alignment between the consumer and producer parts of the vring
- * @num: num of buffers supported by this vring (must be power of two)
- * @notifyid: a unique rproc-wide notify index for this vring. This notify
- * index is used when kicking a remote processor, to let it know that this
- * vring is triggered.
- * @pa: physical address
- *
- * This descriptor is not a resource entry by itself; it is part of the
- * vdev resource type (see below).
- *
- * Note that @da should either contain the device address where
- * the remote processor is expecting the vring, or indicate that
- * dynamically allocation of the vring's device address is supported.
- */
-struct fw_rsc_vdev_vring {
- u32 da;
- u32 align;
- u32 num;
- u32 notifyid;
- u32 pa;
-} __packed;
-
-/**
- * struct fw_rsc_vdev - virtio device header
- * @id: virtio device id (as in virtio_ids.h)
- * @notifyid: a unique rproc-wide notify index for this vdev. This notify
- * index is used when kicking a remote processor, to let it know that the
- * status/features of this vdev have changes.
- * @dfeatures: specifies the virtio device features supported by the firmware
- * @gfeatures: a place holder used by the host to write back the
- * negotiated features that are supported by both sides.
- * @config_len: the size of the virtio config space of this vdev. The config
- * space lies in the resource table immediate after this vdev header.
- * @status: a place holder where the host will indicate its virtio progress.
- * @num_of_vrings: indicates how many vrings are described in this vdev header
- * @reserved: reserved (must be zero)
- * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
- *
- * This resource is a virtio device header: it provides information about
- * the vdev, and is then used by the host and its peer remote processors
- * to negotiate and share certain virtio properties.
- *
- * By providing this resource entry, the firmware essentially asks remoteproc
- * to statically allocate a vdev upon registration of the rproc (dynamic vdev
- * allocation is not yet supported).
- *
- * Note:
- * 1. unlike virtualization systems, the term 'host' here means
- * the Linux side which is running remoteproc to control the remote
- * processors. We use the name 'gfeatures' to comply with virtio's terms,
- * though there isn't really any virtualized guest OS here: it's the host
- * which is responsible for negotiating the final features.
- * Yeah, it's a bit confusing.
- *
- * 2. immediately following this structure is the virtio config space for
- * this vdev (which is specific to the vdev; for more info, read the virtio
- * spec). The size of the config space is specified by @config_len.
- */
-struct fw_rsc_vdev {
- u32 id;
- u32 notifyid;
- u32 dfeatures;
- u32 gfeatures;
- u32 config_len;
- u8 status;
- u8 num_of_vrings;
- u8 reserved[2];
- struct fw_rsc_vdev_vring vring[];
-} __packed;
+#include <linux/rsc_table.h>
struct rproc;
diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h
new file mode 100644
index 000000000000..c32c8b6cd2a7
--- /dev/null
+++ b/include/linux/rsc_table.h
@@ -0,0 +1,306 @@
+/*
+ * Resource table and its types data structure
+ *
+ * Copyright(c) 2011 Texas Instruments, Inc.
+ * Copyright(c) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RSC_TABLE_H
+#define RSC_TABLE_H
+
+/**
+ * struct resource_table - firmware resource table header
+ * @ver: version number
+ * @num: number of resource entries
+ * @reserved: reserved (must be zero)
+ * @offset: array of offsets pointing at the various resource entries
+ *
+ * A resource table is essentially a list of system resources required
+ * by the remote processor. It may also include configuration entries.
+ * If needed, the remote processor firmware should contain this table
+ * as a dedicated ".resource_table" ELF section.
+ *
+ * Some resources entries are mere announcements, where the host is informed
+ * of specific remoteproc configuration. Other entries require the host to
+ * do something (e.g. allocate a system resource). Sometimes a negotiation
+ * is expected, where the firmware requests a resource, and once allocated,
+ * the host should provide back its details (e.g. address of an allocated
+ * memory region).
+ *
+ * The header of the resource table, as expressed by this structure,
+ * contains a version number (should we need to change this format in the
+ * future), the number of available resource entries, and their offsets
+ * in the table.
+ *
+ * Immediately following this header are the resource entries themselves,
+ * each of which begins with a resource entry header (as described below).
+ */
+struct resource_table {
+ u32 ver;
+ u32 num;
+ u32 reserved[2];
+ u32 offset[];
+} __packed;
+
+/**
+ * struct fw_rsc_hdr - firmware resource entry header
+ * @type: resource type
+ * @data: resource data
+ *
+ * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
+ * its @type. The content of the entry itself will immediately follow
+ * this header, and it should be parsed according to the resource type.
+ */
+struct fw_rsc_hdr {
+ u32 type;
+ u8 data[];
+} __packed;
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT: request for allocation of a physically contiguous
+ * memory region.
+ * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE: announces the availability of a trace buffer into which
+ * the remote processor will be writing logs.
+ * @RSC_VDEV: declare support for a virtio device, and serve as its
+ * virtio header.
+ * @RSC_LAST: just keep this one at the end of standard resources
+ * @RSC_VENDOR_START: start of the vendor specific resource types range
+ * @RSC_VENDOR_END: end of the vendor specific resource types range
+ *
+ * For more details regarding a specific resource type, please see its
+ * dedicated structure below.
+ *
+ * Please note that these values are used as indices to the rproc_handle_rsc
+ * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
+ * check the validity of an index before the lookup table is accessed, so
+ * please update it as needed.
+ */
+enum fw_resource_type {
+ RSC_CARVEOUT = 0,
+ RSC_DEVMEM = 1,
+ RSC_TRACE = 2,
+ RSC_VDEV = 3,
+ RSC_LAST = 4,
+ RSC_VENDOR_START = 128,
+ RSC_VENDOR_END = 512,
+};
+
+#define FW_RSC_ADDR_ANY (-1)
+
+/**
+ * struct fw_rsc_carveout - physically contiguous memory request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested memory region
+ *
+ * This resource entry requests the host to allocate a physically contiguous
+ * memory region.
+ *
+ * These request entries should precede other firmware resource entries,
+ * as other entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ *
+ * If the firmware is compiled with static addresses, then @da should specify
+ * the expected device address of this memory region. If @da is set to
+ * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
+ * overwrite @da with the dynamically allocated address.
+ *
+ * We will always use @da to negotiate the device addresses, even if it
+ * isn't using an iommu. In that case, though, it will obviously contain
+ * physical addresses.
+ *
+ * Some remote processors needs to know the allocated physical address
+ * even if they do use an iommu. This is needed, e.g., if they control
+ * hardware accelerators which access the physical memory directly (this
+ * is the case with OMAP4 for instance). In that case, the host will
+ * overwrite @pa with the dynamically allocated physical address.
+ * Generally we don't want to expose physical addresses if we don't have to
+ * (remote processors are generally _not_ trusted), so we might want to
+ * change this to happen _only_ when explicitly required by the hardware.
+ *
+ * @flags is used to provide IOMMU protection flags, and @name should
+ * (optionally) contain a human readable name of this carveout region
+ * (mainly for debugging purposes).
+ */
+struct fw_rsc_carveout {
+ u32 da;
+ u32 pa;
+ u32 len;
+ u32 flags;
+ u32 reserved;
+ u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_devmem - iommu mapping request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested region to be mapped
+ *
+ * This resource entry requests the host to iommu map a physically contiguous
+ * memory region. This is needed in case the remote processor requires
+ * access to certain memory-based peripherals; _never_ use it to access
+ * regular memory.
+ *
+ * This is obviously only needed if the remote processor is accessing memory
+ * via an iommu.
+ *
+ * @da should specify the required device address, @pa should specify
+ * the physical address we want to map, @len should specify the size of
+ * the mapping and @flags is the IOMMU protection flags. As always, @name may
+ * (optionally) contain a human readable name of this mapping (mainly for
+ * debugging purposes).
+ *
+ * Note: at this point we just "trust" those devmem entries to contain valid
+ * physical addresses, but this isn't safe and will be changed: eventually we
+ * want remoteproc implementations to provide us ranges of physical addresses
+ * the firmware is allowed to request, and not allow firmwares to request
+ * access to physical addresses that are outside those ranges.
+ */
+struct fw_rsc_devmem {
+ u32 da;
+ u32 pa;
+ u32 len;
+ u32 flags;
+ u32 reserved;
+ u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_trace - trace buffer declaration
+ * @da: device address
+ * @len: length (in bytes)
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the trace buffer
+ *
+ * This resource entry provides the host information about a trace buffer
+ * into which the remote processor will write log messages.
+ *
+ * @da specifies the device address of the buffer, @len specifies
+ * its size, and @name may contain a human readable name of the trace buffer.
+ *
+ * After booting the remote processor, the trace buffers are exposed to the
+ * user via debugfs entries (called trace0, trace1, etc..).
+ */
+struct fw_rsc_trace {
+ u32 da;
+ u32 len;
+ u32 reserved;
+ u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_vdev_vring - vring descriptor entry
+ * @da: device address
+ * @align: the alignment between the consumer and producer parts of the vring
+ * @num: num of buffers supported by this vring (must be power of two)
+ * @notifyid: a unique rproc-wide notify index for this vring. This notify
+ * index is used when kicking a remote processor, to let it know that this
+ * vring is triggered.
+ * @pa: physical address
+ *
+ * This descriptor is not a resource entry by itself; it is part of the
+ * vdev resource type (see below).
+ *
+ * Note that @da should either contain the device address where
+ * the remote processor is expecting the vring, or indicate that
+ * dynamically allocation of the vring's device address is supported.
+ */
+struct fw_rsc_vdev_vring {
+ u32 da;
+ u32 align;
+ u32 num;
+ u32 notifyid;
+ u32 pa;
+} __packed;
+
+/**
+ * struct fw_rsc_vdev - virtio device header
+ * @id: virtio device id (as in virtio_ids.h)
+ * @notifyid: a unique rproc-wide notify index for this vdev. This notify
+ * index is used when kicking a remote processor, to let it know that the
+ * status/features of this vdev have changes.
+ * @dfeatures: specifies the virtio device features supported by the firmware
+ * @gfeatures: a place holder used by the host to write back the
+ * negotiated features that are supported by both sides.
+ * @config_len: the size of the virtio config space of this vdev. The config
+ * space lies in the resource table immediate after this vdev header.
+ * @status: a place holder where the host will indicate its virtio progress.
+ * @num_of_vrings: indicates how many vrings are described in this vdev header
+ * @reserved: reserved (must be zero)
+ * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
+ *
+ * This resource is a virtio device header: it provides information about
+ * the vdev, and is then used by the host and its peer remote processors
+ * to negotiate and share certain virtio properties.
+ *
+ * By providing this resource entry, the firmware essentially asks remoteproc
+ * to statically allocate a vdev upon registration of the rproc (dynamic vdev
+ * allocation is not yet supported).
+ *
+ * Note:
+ * 1. unlike virtualization systems, the term 'host' here means
+ * the Linux side which is running remoteproc to control the remote
+ * processors. We use the name 'gfeatures' to comply with virtio's terms,
+ * though there isn't really any virtualized guest OS here: it's the host
+ * which is responsible for negotiating the final features.
+ * Yeah, it's a bit confusing.
+ *
+ * 2. immediately following this structure is the virtio config space for
+ * this vdev (which is specific to the vdev; for more info, read the virtio
+ * spec). The size of the config space is specified by @config_len.
+ */
+struct fw_rsc_vdev {
+ u32 id;
+ u32 notifyid;
+ u32 dfeatures;
+ u32 gfeatures;
+ u32 config_len;
+ u8 status;
+ u8 num_of_vrings;
+ u8 reserved[2];
+ struct fw_rsc_vdev_vring vring[];
+} __packed;
+
+#endif /* RSC_TABLE_H */
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (5 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-21 15:05 ` Krzysztof Kozlowski
2025-08-19 16:54 ` [PATCH v2 08/11] soc: qcom: mdt_loader: Add helper functions to map and unmap resources Mukesh Ojha
` (4 subsequent siblings)
11 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
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.
Add qcom_scm_pas_get_rsc_table() SMC call which will return resource table
including static and dynamic resource for a given PAS id in passed output
buffer of output size.
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. If the 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.
More about documentation on resource table format can be found in
include/linux/rsc_table.h
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 158 +++++++++++++++++++++++++
drivers/firmware/qcom/qcom_scm.h | 1 +
include/linux/firmware/qcom/qcom_scm.h | 5 +
3 files changed, 164 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 301d440f62f3..1b45aafd6c05 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/rsc_table.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
@@ -776,6 +781,159 @@ int qcom_scm_pas_mem_setup(u32 peripheral, 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 peripheral, 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] = peripheral,
+ .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
+ * @peripheral: peripheral 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_ctx *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->peripheral, 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 bd3417d9c3f9..4fd13661ecdb 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -91,6 +91,11 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
struct qcom_scm_pas_ctx *ctx);
void qcom_scm_pas_metadata_release(struct qcom_scm_pas_ctx *ctx);
int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
+
+int qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_ctx *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_ctx *ctx);
int qcom_scm_pas_auth_and_reset(u32 peripheral);
int qcom_scm_pas_shutdown(u32 peripheral);
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* [PATCH v2 08/11] soc: qcom: mdt_loader: Add helper functions to map and unmap resources
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (6 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table Mukesh Ojha
` (3 subsequent siblings)
11 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Most Qualcomm platforms feature a proprietary hypervisor (Gunyah, QHEE),
which normally takes care of the IOMMU configuration for remote processors
by intercepting qcom_scm_pas_auth_and_reset() calls.
When the aforementioned hypervisor is absent, the OS must perform the
configuration instead. To do so, it must first retrieve a resource table
from the secure world, to ensure the settings are in sync with TZ's
expectations and then it should map the resources before it calls
qcom_scm_pas_auth_and_reset().
Add helper function to IOMMU map and unmap devmem resources for a given
remote processor.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/soc/qcom/mdt_loader.c | 174 ++++++++++++++++++++++++++++
include/linux/soc/qcom/mdt_loader.h | 17 +++
2 files changed, 191 insertions(+)
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index a1718db91b3e..ea7034c4b996 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -11,13 +11,34 @@
#include <linux/device.h>
#include <linux/elf.h>
#include <linux/firmware.h>
+#include <linux/iommu.h>
#include <linux/kernel.h>
+#include <linux/hashtable.h>
+#include <linux/list.h>
#include <linux/module.h>
#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/rsc_table.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/soc/qcom/mdt_loader.h>
+#define MAX_RSCTABLE_SIZE SZ_16K
+#define RSC_TABLE_HASH_BITS 5 // 32 buckets
+
+DEFINE_HASHTABLE(qcom_pas_rsc_table_map, RSC_TABLE_HASH_BITS);
+
+struct qcom_pas_devmem_rsc {
+ struct fw_rsc_devmem *devmem;
+ struct list_head node;
+};
+
+struct qcom_pas_rsc_table_info {
+ struct resource_table *rsc_table;
+ struct list_head devmem_list;
+ struct hlist_node hnode;
+ int pas_id;
+};
+
static bool mdt_header_valid(const struct firmware *fw)
{
const struct elf32_hdr *ehdr;
@@ -500,5 +521,158 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
}
EXPORT_SYMBOL_GPL(qcom_mdt_pas_load);
+static void __qcom_mdt_unmap_devmem_rscs(struct qcom_pas_rsc_table_info *info,
+ struct iommu_domain *domain)
+{
+ struct qcom_pas_devmem_rsc *entry, *tmp;
+
+ list_for_each_entry_safe(entry, tmp, &info->devmem_list, node) {
+ iommu_unmap(domain, entry->devmem->da, entry->devmem->len);
+ list_del(&entry->node);
+ kfree(entry);
+ }
+}
+
+void qcom_mdt_pas_unmap_devmem_rscs(struct qcom_scm_pas_ctx *ctx, struct iommu_domain *domain)
+{
+ struct qcom_pas_rsc_table_info *info;
+
+ if (!ctx || !domain)
+ return;
+
+ if (!ctx->has_iommu)
+ return;
+
+ hash_for_each_possible(qcom_pas_rsc_table_map, info, hnode, ctx->peripheral) {
+ if (info->pas_id == ctx->peripheral)
+ __qcom_mdt_unmap_devmem_rscs(info, domain);
+
+ hash_del(&info->hnode);
+ kfree(info->rsc_table);
+ }
+
+ return;
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_pas_unmap_devmem_rscs);
+
+static int __qcom_mdt_map_devmem_rscs(struct device *dev, void *ptr, int avail,
+ struct iommu_domain *domain,
+ struct qcom_pas_rsc_table_info *info)
+{
+ struct qcom_pas_devmem_rsc *devmem_info;
+ struct fw_rsc_devmem *rsc = ptr;
+ int ret;
+
+ if (sizeof(*rsc) > avail) {
+ dev_err(dev, "devmem rsc is truncated\n");
+ return -EINVAL;
+ }
+
+ if (rsc->reserved) {
+ dev_err(dev, "devmem rsc has non zero reserved bytes\n");
+ return -EINVAL;
+ }
+
+ devmem_info = kzalloc(sizeof(*devmem_info), GFP_KERNEL);
+ if (!devmem_info)
+ return -ENOMEM;
+
+ ret = iommu_map(domain, rsc->da, rsc->pa, rsc->len, rsc->flags, GFP_KERNEL);
+ if (ret) {
+ dev_err(dev, "failed to map devmem: %d\n", ret);
+ kfree(devmem_info);
+ return ret;
+ }
+
+ devmem_info->devmem = rsc;
+ list_add_tail(&devmem_info->node, &info->devmem_list);
+
+ dev_dbg(dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
+ rsc->pa, rsc->da, rsc->len);
+
+ return ret;
+}
+
+/**
+ * qcom_mdt_pas_map_devmem_rscs() - IOMMU map device memory resources for
+ * a given Peripheral
+ *
+ * This routine should be called when it is known that the SoC is running
+ * with Linux as hypervisor at EL2 where it is in control of the IOMMU map
+ * of the resources for the remote processors.
+ *
+ * @ctx: pas context data structure
+ * @domain: IOMMU domain
+ * @input_rt: input resource table buffer when resource table is part of firmware
+ * binary, if not, pass NULL
+ * @input_rt_size: input resource table size, if input_rt is NULL, then pass zero.
+ *
+ * Returns 0 on success, negative errno otherwise.
+ *
+ */
+int qcom_mdt_pas_map_devmem_rscs(struct qcom_scm_pas_ctx *ctx, struct iommu_domain *domain,
+ void *input_rt, size_t input_rt_size)
+{
+ size_t output_rt_size = MAX_RSCTABLE_SIZE;
+ struct resource_table *rsc_table;
+ struct qcom_pas_rsc_table_info *info;
+ void *output_rt;
+ int ret;
+ int i;
+
+ if (!ctx || !domain)
+ return -EINVAL;
+
+ if (!ctx->has_iommu)
+ return 0;
+
+ ret = qcom_scm_pas_get_rsc_table(ctx, input_rt, input_rt_size, &output_rt,
+ &output_rt_size);
+ if (ret) {
+ dev_err(ctx->dev, "error %d getting resource_table\n", ret);
+ return ret;
+ }
+
+ rsc_table = output_rt;
+ info = devm_kzalloc(ctx->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ goto free_output_rt;
+
+ info->pas_id = ctx->peripheral;
+ info->rsc_table = output_rt;
+ INIT_LIST_HEAD(&info->devmem_list);
+ for (i = 0; i < rsc_table->num; i++) {
+ int offset = rsc_table->offset[i];
+ struct fw_rsc_hdr *hdr = (void *)rsc_table + offset;
+ int avail = output_rt_size - offset - sizeof(*hdr);
+ void *ptr = (void *)hdr + sizeof(*hdr);
+
+ if (avail < 0) {
+ dev_err(ctx->dev, "rsc table is truncated\n");
+ ret = -EINVAL;
+ goto undo_mapping;
+ }
+
+ if (hdr->type == RSC_DEVMEM) {
+ ret = __qcom_mdt_map_devmem_rscs(ctx->dev, ptr, avail, domain, info);
+ if (ret)
+ goto undo_mapping;
+ }
+ }
+
+ hash_add(qcom_pas_rsc_table_map, &info->hnode, ctx->peripheral);
+
+ return 0;
+
+undo_mapping:
+ __qcom_mdt_unmap_devmem_rscs(info, domain);
+
+free_output_rt:
+ devm_kfree(ctx->dev, info->rsc_table);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_pas_map_devmem_rscs);
+
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 450fa0be2af0..62f239f64dfb 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -11,6 +11,8 @@
struct device;
struct firmware;
struct qcom_scm_pas_ctx;
+struct resource_table;
+struct iommu_domain;
#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
@@ -31,6 +33,11 @@ int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
const char *fw_name, struct device *dev);
+int qcom_mdt_pas_map_devmem_rscs(struct qcom_scm_pas_ctx *ctx, struct iommu_domain *domain,
+ void *rsc_table, size_t rsc_size);
+
+void qcom_mdt_pas_unmap_devmem_rscs(struct qcom_scm_pas_ctx *ctx, struct iommu_domain *domain);
+
#else /* !IS_ENABLED(CONFIG_QCOM_MDT_LOADER) */
static inline ssize_t qcom_mdt_get_size(const struct firmware *fw)
@@ -68,6 +75,16 @@ static inline void *qcom_mdt_read_metadata(const struct firmware *fw,
return ERR_PTR(-ENODEV);
}
+static inline int qcom_mdt_pas_map_devmem_rscs(struct device *dev, bool has_iommu,
+ struct iommu_domain *domain, int pas_id,
+ phys_addr_t rsc_table, size_t rsc_size)
+{
+ return -ENODEV;
+}
+
+void qcom_mdt_pas_unmap_devmem_rscs(bool has_iommu, int pas_id, struct iommu_domain *domain)
+{
+}
#endif /* !IS_ENABLED(CONFIG_QCOM_MDT_LOADER) */
#endif
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (7 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 08/11] soc: qcom: mdt_loader: Add helper functions to map and unmap resources Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-20 8:36 ` Stephan Gerhold
2025-08-19 16:54 ` [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Mukesh Ojha
` (2 subsequent siblings)
11 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Extend parse_fw callback to include SMC call to get resource
table from TrustZone to leverage resource table parse and
mapping and unmapping code reuse from the framework.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/remoteproc/qcom_q6v5_pas.c | 33 +++++++++++++++++++++++++++--
drivers/soc/qcom/mdt_loader.c | 1 -
include/linux/soc/qcom/mdt_loader.h | 2 ++
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 09cada92dfd5..1e0f09bf1ef2 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -408,6 +408,35 @@ 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)
+{
+ struct qcom_pas *pas = rproc->priv;
+ size_t output_rt_size = MAX_RSCTABLE_SIZE;
+ void *output_rt;
+ 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 = qcom_scm_pas_get_rsc_table(pas->pas_id, NULL, 0, &output_rt, &output_rt_size);
+ if (ret) {
+ dev_err(pas->dev, "error %d getting resource_table\n", ret);
+ return ret;
+ }
+
+ 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;
@@ -420,7 +449,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,
};
@@ -430,7 +459,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,
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index ea7034c4b996..8456cca3f3e0 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -22,7 +22,6 @@
#include <linux/slab.h>
#include <linux/soc/qcom/mdt_loader.h>
-#define MAX_RSCTABLE_SIZE SZ_16K;
#define RSC_TABLE_HASH_BITS 5 // 32 buckets
DEFINE_HASHTABLE(qcom_pas_rsc_table_map, RSC_TABLE_HASH_BITS);
diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
index 62f239f64dfb..92ad862e733e 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -8,6 +8,8 @@
#define QCOM_MDT_TYPE_HASH (2 << 24)
#define QCOM_MDT_RELOCATABLE BIT(27)
+#define MAX_RSCTABLE_SIZE SZ_16K
+
struct device;
struct firmware;
struct qcom_scm_pas_ctx;
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (8 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-20 8:40 ` Stephan Gerhold
2025-08-19 16:54 ` [PATCH v2 11/11] media: iris: " Mukesh Ojha
2025-08-20 11:03 ` [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Bryan O'Donoghue
11 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
or QHEE), 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 (at 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 is the 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 | 63 +++++++++++++++++++++++++++---
1 file changed, 57 insertions(+), 6 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 1e0f09bf1ef2..180528bcd57c 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>
@@ -250,6 +251,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;
@@ -284,11 +301,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;
}
}
@@ -299,18 +320,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);
@@ -322,10 +347,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);
@@ -381,8 +412,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);
@@ -424,7 +459,8 @@ static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware *f
if (!rproc->has_iommu)
return ret;
- ret = qcom_scm_pas_get_rsc_table(pas->pas_id, NULL, 0, &output_rt, &output_rt_size);
+ ret = qcom_scm_pas_get_rsc_table(pas->pas_ctx, NULL, 0,
+ &output_rt, &output_rt_size);
if (ret) {
dev_err(pas->dev, "error %d getting resource_table\n", ret);
return ret;
@@ -726,6 +762,20 @@ static int qcom_pas_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ if (of_property_present(pdev->dev.of_node, "iommus")) {
+ struct of_phandle_args args;
+
+ ret = of_parse_phandle_with_args(pdev->dev.of_node, "iommus",
+ "#iommu-cells", 0, &args);
+ if (ret < 0)
+ return ret;
+
+ rproc->has_iommu = true;
+ of_node_put(args.np);
+ } else {
+ rproc->has_iommu = false;
+ }
+
rproc->auto_boot = desc->auto_boot;
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
@@ -800,6 +850,7 @@ static int qcom_pas_probe(struct platform_device *pdev)
if (!pas->dtb_pas_ctx)
goto remove_ssr_sysmon;
+ pas->pas_ctx->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] 74+ messages in thread
* [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (9 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Mukesh Ojha
@ 2025-08-19 16:54 ` Mukesh Ojha
2025-08-20 8:46 ` Stephan Gerhold
` (2 more replies)
2025-08-20 11:03 ` [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Bryan O'Donoghue
11 siblings, 3 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-19 16:54 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc, Mukesh Ojha
Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
or QHEE), 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 hypervisor is absent, the operating system must perform these
configurations instead.
Support for handling IOMMU and SHM setup in the absence of a hypervisor
is now in place. Extend the Iris driver to enable this functionality on
platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
Additionally, the Iris driver must map the firmware and its required
resources to the firmware SID, which is now specified via the device tree.
Co-developed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_core.c | 9 +-
drivers/media/platform/qcom/iris/iris_core.h | 6 +
.../media/platform/qcom/iris/iris_firmware.c | 156 ++++++++++++++++--
.../media/platform/qcom/iris/iris_firmware.h | 2 +
4 files changed, 155 insertions(+), 18 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c
index 0fa0a3b549a2..57417d4d7e05 100644
--- a/drivers/media/platform/qcom/iris/iris_core.c
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -17,6 +17,7 @@ void iris_core_deinit(struct iris_core *core)
mutex_lock(&core->lock);
iris_fw_unload(core);
iris_vpu_power_off(core);
+ iris_fw_deinit(core);
iris_hfi_queues_deinit(core);
core->state = IRIS_CORE_DEINIT;
mutex_unlock(&core->lock);
@@ -65,10 +66,14 @@ int iris_core_init(struct iris_core *core)
if (ret)
goto error_queue_deinit;
- ret = iris_fw_load(core);
+ ret = iris_fw_init(core);
if (ret)
goto error_power_off;
+ ret = iris_fw_load(core);
+ if (ret)
+ goto error_firmware_deinit;
+
ret = iris_vpu_boot_firmware(core);
if (ret)
goto error_unload_fw;
@@ -83,6 +88,8 @@ int iris_core_init(struct iris_core *core)
error_unload_fw:
iris_fw_unload(core);
+error_firmware_deinit:
+ iris_fw_deinit(core);
error_power_off:
iris_vpu_power_off(core);
error_queue_deinit:
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
index aeeac32a1f6d..57eeefb38f22 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -73,6 +73,12 @@ struct iris_core {
int irq;
struct v4l2_device v4l2_dev;
struct video_device *vdev_dec;
+ bool has_iommu;
+ struct video_firmware {
+ struct device *dev;
+ struct qcom_scm_pas_ctx *ctx;
+ struct iommu_domain *iommu_domain;
+ } fw;
const struct v4l2_file_operations *iris_v4l2_file_ops;
const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops;
const struct vb2_ops *iris_vb2_ops;
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
index f1b5cd56db32..e3f2fe5c9d7a 100644
--- a/drivers/media/platform/qcom/iris/iris_firmware.c
+++ b/drivers/media/platform/qcom/iris/iris_firmware.c
@@ -3,10 +3,18 @@
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
+#include <linux/device.h>
#include <linux/firmware.h>
-#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/kernel.h>
+#include <linux/iommu.h>
+#include <linux/io.h>
+#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/sizes.h>
#include <linux/soc/qcom/mdt_loader.h>
#include "iris_core.h"
@@ -17,15 +25,14 @@
static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
{
u32 pas_id = core->iris_platform_data->pas_id;
+ struct qcom_scm_pas_ctx *ctx;
const struct firmware *firmware = NULL;
struct device *dev = core->dev;
- struct reserved_mem *rmem;
- struct device_node *node;
- phys_addr_t mem_phys;
- size_t res_size;
- ssize_t fw_size;
- void *mem_virt;
- int ret;
+ struct reserved_mem *rmem = NULL;
+ struct device_node *node = NULL;
+ ssize_t fw_size = 0;
+ void *mem_virt = NULL;
+ int ret = 0;
if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
return -EINVAL;
@@ -39,36 +46,64 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
if (!rmem)
return -EINVAL;
- mem_phys = rmem->base;
- res_size = rmem->size;
+ if (core->has_iommu)
+ dev = core->fw.dev;
+ ctx = qcom_scm_pas_ctx_init(dev, pas_id, rmem->base, rmem->size, false);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->has_iommu = core->has_iommu;
ret = request_firmware(&firmware, fw_name, dev);
if (ret)
return ret;
fw_size = qcom_mdt_get_size(firmware);
- if (fw_size < 0 || res_size < (size_t)fw_size) {
+ if (fw_size < 0 || rmem->size < (size_t)fw_size) {
ret = -EINVAL;
goto err_release_fw;
}
- mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC);
+ mem_virt = memremap(rmem->base, rmem->size, MEMREMAP_WC);
if (!mem_virt) {
ret = -ENOMEM;
goto err_release_fw;
}
- ret = qcom_mdt_load(dev, firmware, fw_name,
- pas_id, mem_virt, mem_phys, res_size, NULL);
+ ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL);
if (ret)
goto err_mem_unmap;
- ret = qcom_scm_pas_auth_and_reset(pas_id);
+ if (core->has_iommu) {
+ ret = iommu_map(core->fw.iommu_domain, 0, rmem->base, rmem->size,
+ IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
+ if (ret)
+ goto err_mem_unmap;
+
+ /*
+ * Firmware has no support for resource table for now, so, lets
+ * pass NULL and zero for input resource table and input resource
+ * table respectively.
+ */
+ ret = qcom_mdt_pas_map_devmem_rscs(ctx, core->fw.iommu_domain, NULL, 0);
+ if (ret)
+ goto err_unmap_carveout;
+ }
+
+ ret = qcom_scm_pas_prepare_and_auth_reset(ctx);
if (ret)
- goto err_mem_unmap;
+ goto err_unmap_devmem_rscs;
+
+ core->fw.ctx = ctx;
return ret;
+err_unmap_devmem_rscs:
+ if (core->has_iommu)
+ qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
+err_unmap_carveout:
+ if (core->has_iommu)
+ iommu_unmap(core->fw.iommu_domain, 0, rmem->size);
err_mem_unmap:
memunmap(mem_virt);
err_release_fw:
@@ -109,10 +144,97 @@ int iris_fw_load(struct iris_core *core)
int iris_fw_unload(struct iris_core *core)
{
- return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
+ struct qcom_scm_pas_ctx *ctx;
+ int ret;
+
+ ctx = core->fw.ctx;
+ ret = qcom_scm_pas_shutdown(ctx->peripheral);
+ if (core->has_iommu) {
+ iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size);
+ qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
+ }
+
+ return ret;
}
int iris_set_hw_state(struct iris_core *core, bool resume)
{
return qcom_scm_set_remote_state(resume, 0);
}
+
+int iris_fw_init(struct iris_core *core)
+{
+ struct platform_device_info info;
+ struct iommu_domain *iommu_dom;
+ struct platform_device *pdev;
+ struct device_node *np;
+ int ret;
+
+ np = of_get_child_by_name(core->dev->of_node, "video-firmware");
+ if (!np)
+ return 0;
+
+ core->has_iommu = true;
+ memset(&info, 0, sizeof(info));
+ info.fwnode = &np->fwnode;
+ info.parent = core->dev;
+ info.name = np->name;
+ info.dma_mask = DMA_BIT_MASK(32);
+
+ pdev = platform_device_register_full(&info);
+ if (IS_ERR(pdev)) {
+ of_node_put(np);
+ return PTR_ERR(pdev);
+ }
+
+ pdev->dev.of_node = np;
+
+ ret = of_dma_configure(&pdev->dev, np, true);
+ if (ret) {
+ dev_err(core->dev, "failed to allocate domain\n");
+ goto err_unregister;
+ }
+
+ core->fw.dev = &pdev->dev;
+
+ iommu_dom = iommu_get_domain_for_dev(core->fw.dev);
+ if (!iommu_dom) {
+ dev_err(core->fw.dev, "Failed to get iommu domain\n");
+ ret = -EINVAL;
+ goto err_iommu_free;
+ }
+
+ ret = iommu_attach_device(iommu_dom, core->fw.dev);
+ if (ret) {
+ dev_err(core->fw.dev, "could not attach device\n");
+ goto err_iommu_free;
+ }
+
+ core->fw.iommu_domain = iommu_dom;
+
+ of_node_put(np);
+
+ return 0;
+
+err_iommu_free:
+ iommu_domain_free(iommu_dom);
+err_unregister:
+ platform_device_unregister(pdev);
+ of_node_put(np);
+ return ret;
+}
+
+void iris_fw_deinit(struct iris_core *core)
+{
+ struct iommu_domain *iommu_dom;
+
+ if (!core->has_iommu)
+ return;
+
+ iommu_dom = core->fw.iommu_domain;
+ iommu_detach_device(iommu_dom, core->fw.dev);
+ iommu_domain_free(iommu_dom);
+
+ core->fw.iommu_domain = NULL;
+ platform_device_unregister(to_platform_device(core->fw.dev));
+}
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/media/platform/qcom/iris/iris_firmware.h
index e833ecd34887..adde46109966 100644
--- a/drivers/media/platform/qcom/iris/iris_firmware.h
+++ b/drivers/media/platform/qcom/iris/iris_firmware.h
@@ -11,5 +11,7 @@ struct iris_core;
int iris_fw_load(struct iris_core *core);
int iris_fw_unload(struct iris_core *core);
int iris_set_hw_state(struct iris_core *core, bool resume);
+int iris_fw_init(struct iris_core *core);
+void iris_fw_deinit(struct iris_core *core);
#endif
--
2.50.1
^ permalink raw reply related [flat|nested] 74+ messages in thread
* Re: [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper
2025-08-19 16:54 ` [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper Mukesh Ojha
@ 2025-08-19 17:17 ` Pavan Kondeti
2025-08-20 6:19 ` Mukesh Ojha
2025-08-20 11:40 ` Bryan O'Donoghue
1 sibling, 1 reply; 74+ messages in thread
From: Pavan Kondeti @ 2025-08-19 17:17 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Tue, Aug 19, 2025 at 10:24:36PM +0530, Mukesh Ojha wrote:
> Currently, remoteproc and non-remoteproc subsystems use different
> variants of the MDT loader helper API, primarily due to the handling of
> the metadata context. Remoteproc subsystems retain this context until
> authentication and reset, while non-remoteproc subsystems (e.g., video,
> graphics) do not require it.
>
> Unify the metadata loading process for both remoteproc and
> non-remoteproc subsystems by introducing a dedicated PAS context
> initialization function.
>
> By introducing qcom_scm_pas_ctx_init(), we can standardize the API usage
> across subsystems and reduce the number of parameters passed to MDT
> loader functions, improving code clarity and maintainability.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/firmware/qcom/qcom_scm.c | 26 ++++++++++++++++++++++++++
> include/linux/firmware/qcom/qcom_scm.h | 11 +++++++++++
> 2 files changed, 37 insertions(+)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 96d5cf40a74c..33187d4f4aef 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -558,6 +558,32 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
> dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
> }
>
> +void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> + size_t mem_size, bool save_mdt_ctx)
Since we export this for other drivers/module, consider adding kerneldoc
comments.
> +{
> + struct qcom_scm_pas_ctx *ctx;
> +
> + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> + if (!ctx)
> + return NULL;
> +
> + ctx->dev = dev;
> + ctx->peripheral = peripheral;
> + ctx->mem_phys = mem_phys;
> + ctx->mem_size = mem_size;
> + ctx->save_mdt_ctx = save_mdt_ctx;
> + ctx->metadata = NULL;
This seems unnecessary.
> +
> + if (save_mdt_ctx) {
> + ctx->metadata = devm_kzalloc(dev, sizeof(*ctx->metadata), GFP_KERNEL);
> + if (!ctx->metadata)
> + return NULL;
Do we really need to pass this burden to the caller to pass save_mdt_ctx
as true/false? What happens if we always keep metadata in qcom_scm_pas_ctx struct
and let clients use it if needed.
> + }
> +
> + return ctx;
> +}
> +EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
Is there an equivalant ctx_destroy() function? It would be confusing for
drivers to call this in their probe and not doing anything upon error or
in their bus::remove callbacks. I don't know if we really want to
convert the whole function under devres or just provide a destroy
callback.
> +
> /**
> * 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 a55ca771286b..b7eb206561a9 100644
> --- a/include/linux/firmware/qcom/qcom_scm.h
> +++ b/include/linux/firmware/qcom/qcom_scm.h
> @@ -72,6 +72,17 @@ struct qcom_scm_pas_metadata {
> ssize_t size;
> };
>
> +struct qcom_scm_pas_ctx {
> + struct device *dev;
> + u32 peripheral;
> + phys_addr_t mem_phys;
> + size_t mem_size;
> + struct qcom_scm_pas_metadata *metadata;
> + bool save_mdt_ctx;
As mentioned above, can we just include qcom_scm_pas_metadata struct all
the time?
Thanks,
Pavan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper
2025-08-19 17:17 ` Pavan Kondeti
@ 2025-08-20 6:19 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 6:19 UTC (permalink / raw)
To: Pavan Kondeti
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Tue, Aug 19, 2025 at 10:47:45PM +0530, Pavan Kondeti wrote:
> On Tue, Aug 19, 2025 at 10:24:36PM +0530, Mukesh Ojha wrote:
> > Currently, remoteproc and non-remoteproc subsystems use different
> > variants of the MDT loader helper API, primarily due to the handling of
> > the metadata context. Remoteproc subsystems retain this context until
> > authentication and reset, while non-remoteproc subsystems (e.g., video,
> > graphics) do not require it.
> >
> > Unify the metadata loading process for both remoteproc and
> > non-remoteproc subsystems by introducing a dedicated PAS context
> > initialization function.
> >
> > By introducing qcom_scm_pas_ctx_init(), we can standardize the API usage
> > across subsystems and reduce the number of parameters passed to MDT
> > loader functions, improving code clarity and maintainability.
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/qcom_scm.c | 26 ++++++++++++++++++++++++++
> > include/linux/firmware/qcom/qcom_scm.h | 11 +++++++++++
> > 2 files changed, 37 insertions(+)
> >
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 96d5cf40a74c..33187d4f4aef 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -558,6 +558,32 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
> > dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
> > }
> >
> > +void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> > + size_t mem_size, bool save_mdt_ctx)
>
> Since we export this for other drivers/module, consider adding kerneldoc
> comments.
>
Sure.
> > +{
> > + struct qcom_scm_pas_ctx *ctx;
> > +
> > + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> > + if (!ctx)
> > + return NULL;
> > +
> > + ctx->dev = dev;
> > + ctx->peripheral = peripheral;
> > + ctx->mem_phys = mem_phys;
> > + ctx->mem_size = mem_size;
> > + ctx->save_mdt_ctx = save_mdt_ctx;
> > + ctx->metadata = NULL;
>
> This seems unnecessary.
Yes, it is redundant.
> > +
> > + if (save_mdt_ctx) {
> > + ctx->metadata = devm_kzalloc(dev, sizeof(*ctx->metadata), GFP_KERNEL);
> > + if (!ctx->metadata)
> > + return NULL;
>
> Do we really need to pass this burden to the caller to pass save_mdt_ctx
> as true/false? What happens if we always keep metadata in qcom_scm_pas_ctx struct
> and let clients use it if needed.
>
Do not wanted to be aggressive like changing every driver which uses
qcom_mdt_load(), Hence, taken this safe approach of adapting the current
way.
Obviously, it is the one approach where I was looking to unify API's
across remoteproc or non-remoteproc subsystems and that's why I have
put comment in the 2/11 if we feel fine to do it for other drivers too.
> > + }
> > +
> > + return ctx;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
>
> Is there an equivalant ctx_destroy() function? It would be confusing for
> drivers to call this in their probe and not doing anything upon error or
> in their bus::remove callbacks. I don't know if we really want to
> convert the whole function under devres or just provide a destroy
> callback.
>
I dont disagree., will wait for some more comments.
> > +
> > /**
> > * 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 a55ca771286b..b7eb206561a9 100644
> > --- a/include/linux/firmware/qcom/qcom_scm.h
> > +++ b/include/linux/firmware/qcom/qcom_scm.h
> > @@ -72,6 +72,17 @@ struct qcom_scm_pas_metadata {
> > ssize_t size;
> > };
> >
> > +struct qcom_scm_pas_ctx {
> > + struct device *dev;
> > + u32 peripheral;
> > + phys_addr_t mem_phys;
> > + size_t mem_size;
> > + struct qcom_scm_pas_metadata *metadata;
> > + bool save_mdt_ctx;
>
> As mentioned above, can we just include qcom_scm_pas_metadata struct all
> the time?
>
> Thanks,
> Pavan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-19 16:54 ` [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header Mukesh Ojha
@ 2025-08-20 8:12 ` Stephan Gerhold
2025-08-20 15:18 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 8:12 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Tue, Aug 19, 2025 at 10:24:41PM +0530, Mukesh Ojha wrote:
> The resource table data structure has traditionally been associated with
> the remoteproc framework, where the resource table is included as a
> section within the remote processor firmware binary. However, it is also
> possible to obtain the resource table through other means—such as from a
> reserved memory region populated by the boot firmware, statically
> maintained driver data, or via a secure SMC call—when it is not embedded
> in the firmware.
>
> There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> etc.) in the upstream kernel that do not use the remoteproc framework to
> manage their lifecycle for various reasons.
>
> When Linux is running at EL2, similar to the Qualcomm PAS driver
> (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> also want to use the resource table SMC call to retrieve and map
> resources before they are used by the remote processor.
>
All the examples you give here (Venus/Iris, GPU) have some sort of EL2
support already for older platforms:
- For GPU, we just skip loading the ZAP shader and access the protected
registers directly. I would expect the ZAP shader does effectively
the same, perhaps with some additional handling for secure mode. Is
this even a real remote processor that has a separate IOMMU domain?
- For Venus/Iris, there is code upstream similar to your PATCH 11/11
that maps the firmware with the IOMMU (but invokes reset directly
using the registers, without using PAS). There is no resource table
used for that either, so at least all Venus/Iris versions so far
apparently had no need for any mappings aside from the firmware
binary.
I understand that you want to continue using PAS for these, but I'm a
bit confused what kind of mappings we would expect to have in the
resource table for video and GPU. Could you give an example?
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table
2025-08-19 16:54 ` [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table Mukesh Ojha
@ 2025-08-20 8:36 ` Stephan Gerhold
2025-08-20 11:14 ` Mukesh Ojha
2025-08-21 14:49 ` Krzysztof Kozlowski
0 siblings, 2 replies; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 8:36 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Tue, Aug 19, 2025 at 10:24:44PM +0530, Mukesh Ojha wrote:
> Extend parse_fw callback to include SMC call to get resource
> table from TrustZone to leverage resource table parse and
> mapping and unmapping code reuse from the framework.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/remoteproc/qcom_q6v5_pas.c | 33 +++++++++++++++++++++++++++--
> drivers/soc/qcom/mdt_loader.c | 1 -
> include/linux/soc/qcom/mdt_loader.h | 2 ++
> 3 files changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index 09cada92dfd5..1e0f09bf1ef2 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> @@ -408,6 +408,35 @@ 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)
> +{
> + struct qcom_pas *pas = rproc->priv;
> + size_t output_rt_size = MAX_RSCTABLE_SIZE;
> + void *output_rt;
> + 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 = qcom_scm_pas_get_rsc_table(pas->pas_id, NULL, 0, &output_rt, &output_rt_size);
In PATCH 07/11 you have support for "static" resources that can be part
of the firmware binary, but then you never make use of it. Like in the
iris patch you just give in NULL, 0 for input_rt, even though,
(presumably?) the remoteproc framework has support for parsing the
resource table from the ELF firmware image.
I would suggest adding a comment here justifying this and perhaps
something to the commit message. I do see value in having the
qcom_scm_pas_get_rsc_table() properly defined with input RT support, but
it's not obvious from the description of your patches that this is
effectively dead code right now(?).
> + if (ret) {
> + dev_err(pas->dev, "error %d getting resource_table\n", ret);
> + return ret;
> + }
> +
> + 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;
> @@ -420,7 +449,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,
> };
> @@ -430,7 +459,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,
> diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> index ea7034c4b996..8456cca3f3e0 100644
> --- a/drivers/soc/qcom/mdt_loader.c
> +++ b/drivers/soc/qcom/mdt_loader.c
> @@ -22,7 +22,6 @@
> #include <linux/slab.h>
> #include <linux/soc/qcom/mdt_loader.h>
>
> -#define MAX_RSCTABLE_SIZE SZ_16K;
I'm confused why there is a semicolon here suddenly. Did you edit this
patch by hand?
Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse resource table
error: patch failed: drivers/soc/qcom/mdt_loader.c:22
error: drivers/soc/qcom/mdt_loader.c: patch does not apply
> #define RSC_TABLE_HASH_BITS 5 // 32 buckets
>
> DEFINE_HASHTABLE(qcom_pas_rsc_table_map, RSC_TABLE_HASH_BITS);
> diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
> index 62f239f64dfb..92ad862e733e 100644
> --- a/include/linux/soc/qcom/mdt_loader.h
> +++ b/include/linux/soc/qcom/mdt_loader.h
> @@ -8,6 +8,8 @@
> #define QCOM_MDT_TYPE_HASH (2 << 24)
> #define QCOM_MDT_RELOCATABLE BIT(27)
>
> +#define MAX_RSCTABLE_SIZE SZ_16K
> +
> struct device;
> struct firmware;
> struct qcom_scm_pas_ctx;
You added this define yourself in PATCH 08/11, so just add it in the
right place directly. Make sure you scroll through your patch set before
sending to make sure all changes are in the right commit. :-)
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
2025-08-19 16:54 ` [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Mukesh Ojha
@ 2025-08-20 8:40 ` Stephan Gerhold
2025-08-20 12:03 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 8:40 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Tue, Aug 19, 2025 at 10:24:45PM +0530, Mukesh Ojha wrote:
> Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> or QHEE), 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 (at 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 is the 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 | 63 +++++++++++++++++++++++++++---
> 1 file changed, 57 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index 1e0f09bf1ef2..180528bcd57c 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> [...]
> @@ -424,7 +459,8 @@ static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware *f
> if (!rproc->has_iommu)
> return ret;
>
> - ret = qcom_scm_pas_get_rsc_table(pas->pas_id, NULL, 0, &output_rt, &output_rt_size);
> + ret = qcom_scm_pas_get_rsc_table(pas->pas_ctx, NULL, 0,
> + &output_rt, &output_rt_size);
Unrelated formatting change, should be in previous commit.
> if (ret) {
> dev_err(pas->dev, "error %d getting resource_table\n", ret);
> return ret;
> @@ -726,6 +762,20 @@ static int qcom_pas_probe(struct platform_device *pdev)
> return -ENOMEM;
> }
>
> + if (of_property_present(pdev->dev.of_node, "iommus")) {
I think you need a dt-bindings change for this? You had one in v1, but
dropped it entirely for some reason.
> + struct of_phandle_args args;
> +
> + ret = of_parse_phandle_with_args(pdev->dev.of_node, "iommus",
> + "#iommu-cells", 0, &args);
> + if (ret < 0)
> + return ret;
> +
> + rproc->has_iommu = true;
> + of_node_put(args.np);
> + } else {
> + rproc->has_iommu = false;
> + }
> +
> rproc->auto_boot = desc->auto_boot;
> rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>
> @@ -800,6 +850,7 @@ static int qcom_pas_probe(struct platform_device *pdev)
> if (!pas->dtb_pas_ctx)
> goto remove_ssr_sysmon;
>
> + pas->pas_ctx->has_iommu = pas->dtb_pas_ctx->has_iommu = rproc->has_iommu;
Nitpick: I think this would look cleaner if you separate it into two
lines (only one assignment on each line).
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-19 16:54 ` [PATCH v2 11/11] media: iris: " Mukesh Ojha
@ 2025-08-20 8:46 ` Stephan Gerhold
2025-08-20 11:56 ` Mukesh Ojha
2025-08-20 11:33 ` Bryan O'Donoghue
2025-08-22 8:45 ` Krzysztof Kozlowski
2 siblings, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 8:46 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Tue, Aug 19, 2025 at 10:24:46PM +0530, Mukesh Ojha wrote:
> Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> or QHEE), 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 hypervisor is absent, the operating system must perform these
> configurations instead.
>
> Support for handling IOMMU and SHM setup in the absence of a hypervisor
> is now in place. Extend the Iris driver to enable this functionality on
> platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
>
> Additionally, the Iris driver must map the firmware and its required
> resources to the firmware SID, which is now specified via the device tree.
>
> Co-developed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_core.c | 9 +-
> drivers/media/platform/qcom/iris/iris_core.h | 6 +
> .../media/platform/qcom/iris/iris_firmware.c | 156 ++++++++++++++++--
> .../media/platform/qcom/iris/iris_firmware.h | 2 +
> 4 files changed, 155 insertions(+), 18 deletions(-)
>
> [...]
> diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
> index f1b5cd56db32..e3f2fe5c9d7a 100644
> --- a/drivers/media/platform/qcom/iris/iris_firmware.c
> +++ b/drivers/media/platform/qcom/iris/iris_firmware.c
> @@ -3,10 +3,18 @@
> * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> */
>
> +#include <linux/device.h>
> #include <linux/firmware.h>
> -#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/kernel.h>
> +#include <linux/iommu.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/of_reserved_mem.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_device.h>
> +#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/sizes.h>
> #include <linux/soc/qcom/mdt_loader.h>
>
> #include "iris_core.h"
> @@ -17,15 +25,14 @@
> static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> {
> u32 pas_id = core->iris_platform_data->pas_id;
> + struct qcom_scm_pas_ctx *ctx;
> const struct firmware *firmware = NULL;
> struct device *dev = core->dev;
> - struct reserved_mem *rmem;
> - struct device_node *node;
> - phys_addr_t mem_phys;
> - size_t res_size;
> - ssize_t fw_size;
> - void *mem_virt;
> - int ret;
> + struct reserved_mem *rmem = NULL;
> + struct device_node *node = NULL;
> + ssize_t fw_size = 0;
> + void *mem_virt = NULL;
> + int ret = 0;
>
> if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
> return -EINVAL;
> @@ -39,36 +46,64 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> if (!rmem)
> return -EINVAL;
>
> - mem_phys = rmem->base;
> - res_size = rmem->size;
> + if (core->has_iommu)
> + dev = core->fw.dev;
>
> + ctx = qcom_scm_pas_ctx_init(dev, pas_id, rmem->base, rmem->size, false);
> + if (!ctx)
> + return -ENOMEM;
> +
> + ctx->has_iommu = core->has_iommu;
> ret = request_firmware(&firmware, fw_name, dev);
> if (ret)
> return ret;
>
> fw_size = qcom_mdt_get_size(firmware);
> - if (fw_size < 0 || res_size < (size_t)fw_size) {
> + if (fw_size < 0 || rmem->size < (size_t)fw_size) {
> ret = -EINVAL;
> goto err_release_fw;
> }
>
> - mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC);
> + mem_virt = memremap(rmem->base, rmem->size, MEMREMAP_WC);
> if (!mem_virt) {
> ret = -ENOMEM;
> goto err_release_fw;
> }
>
> - ret = qcom_mdt_load(dev, firmware, fw_name,
> - pas_id, mem_virt, mem_phys, res_size, NULL);
> + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL);
> if (ret)
> goto err_mem_unmap;
>
> - ret = qcom_scm_pas_auth_and_reset(pas_id);
> + if (core->has_iommu) {
> + ret = iommu_map(core->fw.iommu_domain, 0, rmem->base, rmem->size,
> + IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
What is the use case for IOMMU_PRIV here? You don't have this flag for
the qcom_q6v5_pas change.
> + if (ret)
> + goto err_mem_unmap;
> +
> + /*
> + * Firmware has no support for resource table for now, so, lets
> + * pass NULL and zero for input resource table and input resource
> + * table respectively.
> + */
> + ret = qcom_mdt_pas_map_devmem_rscs(ctx, core->fw.iommu_domain, NULL, 0);
> + if (ret)
> + goto err_unmap_carveout;
> + }
> +
> + ret = qcom_scm_pas_prepare_and_auth_reset(ctx);
> if (ret)
> - goto err_mem_unmap;
> + goto err_unmap_devmem_rscs;
> +
> + core->fw.ctx = ctx;
>
> return ret;
>
> +err_unmap_devmem_rscs:
> + if (core->has_iommu)
> + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> +err_unmap_carveout:
> + if (core->has_iommu)
> + iommu_unmap(core->fw.iommu_domain, 0, rmem->size);
> err_mem_unmap:
> memunmap(mem_virt);
> err_release_fw:
> @@ -109,10 +144,97 @@ int iris_fw_load(struct iris_core *core)
>
> int iris_fw_unload(struct iris_core *core)
> {
> - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> + struct qcom_scm_pas_ctx *ctx;
> + int ret;
> +
> + ctx = core->fw.ctx;
> + ret = qcom_scm_pas_shutdown(ctx->peripheral);
> + if (core->has_iommu) {
> + iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size);
> + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> + }
> +
> + return ret;
> }
>
> int iris_set_hw_state(struct iris_core *core, bool resume)
> {
> return qcom_scm_set_remote_state(resume, 0);
> }
> +
> +int iris_fw_init(struct iris_core *core)
> +{
> + struct platform_device_info info;
> + struct iommu_domain *iommu_dom;
> + struct platform_device *pdev;
> + struct device_node *np;
> + int ret;
> +
> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> + if (!np)
> + return 0;
You need a dt-bindings change for this as well. This is documented only
for Venus.
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
` (10 preceding siblings ...)
2025-08-19 16:54 ` [PATCH v2 11/11] media: iris: " Mukesh Ojha
@ 2025-08-20 11:03 ` Bryan O'Donoghue
2025-08-20 11:22 ` Mukesh Ojha
11 siblings, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-20 11:03 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> This is a further continuation with a new approach to the topic
> discussed in [1] regarding the enablement of Secure Peripheral Image
> Loader support on Qualcomm SoCs when Linux runs at EL2.
>
> A few months ago, we also discussed the challenges at Linaro Connect
> 2025 [2] related to enabling remoteproc when Linux is running at EL2.
>
> [1]
> https://lore.kernel.org/lkml/20241004212359.2263502-1-quic_mojha@quicinc.com/
>
> [2]
> https://resources.linaro.org/en/resource/sF8jXifdb9V1mUefdbfafa
>
> Below, is the summary of the discussion.
Which tree does this apply to exactly ?
git-log-graph linux-stable/master
* c17b750b3ad9f - (tag: v6.17-rc2, linux-stable/master,
linux-stable/HEAD) Linux 6.17-rc2 (3 days ago)
* 8d561baae505b - Merge tag 'x86_urgent_for_v6.17_rc2' of
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip (3 days ago)
b4 shazam
20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com
b4 shazam 20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com
Grabbing thread from
lore.kernel.org/all/20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com/t.mbox.gz
Checking for newer revisions
Grabbing search results from lore.kernel.org
Analyzing 18 messages in the thread
Analyzing 0 code-review messages
Checking attestation on all messages, may take a moment...
---
✓ [PATCH v2 1/11] firmware: qcom_scm: Introduce PAS context
initialization helper
✓ [PATCH v2 2/11] soc: qcom: mdtloader: Add context aware
qcom_mdt_pas_load() helper
✓ [PATCH v2 3/11] firmware: qcom_scm: Add a prep version of
auth_and_reset function
✓ [PATCH v2 4/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
✓ [PATCH v2 5/11] firmware: qcom_scm: Add shmbridge support to
pas_init/release function
✓ [PATCH v2 6/11] remoteproc: Move resource table data structure to
its own header
✓ [PATCH v2 7/11] firmware: qcom_scm: Add
qcom_scm_pas_get_rsc_table() to get resource table
✓ [PATCH v2 8/11] soc: qcom: mdt_loader: Add helper functions to map
and unmap resources
✓ [PATCH v2 9/11] remoteproc: pas: Extend parse_fw callback to parse
resource table
✓ [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support
with IOMMU managed by Linux
✓ [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU
managed by Linux
---
✓ Signed: DKIM/qualcomm.com (From: mukesh.ojha@oss.qualcomm.com)
---
Total patches: 11
---
Applying: firmware: qcom_scm: Introduce PAS context initialization helper
Applying: soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
Patch failed at 0002 soc: qcom: mdtloader: Add context aware
qcom_mdt_pas_load() helper
error: patch failed: drivers/remoteproc/qcom_q6v5_pas.c:235
error: drivers/remoteproc/qcom_q6v5_pas.c: patch does not apply
error: patch failed: drivers/soc/qcom/mdt_loader.c:302
error: drivers/soc/qcom/mdt_loader.c: patch does not apply
error: patch failed: include/linux/soc/qcom/mdt_loader.h:10
error: include/linux/soc/qcom/mdt_loader.h: patch does not apply
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am
--abort".
hint: Disable this message with "git config set advice.mergeConflict false"
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table
2025-08-20 8:36 ` Stephan Gerhold
@ 2025-08-20 11:14 ` Mukesh Ojha
2025-08-20 13:07 ` Stephan Gerhold
2025-08-21 14:49 ` Krzysztof Kozlowski
1 sibling, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 11:14 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 10:36:10AM +0200, Stephan Gerhold wrote:
> On Tue, Aug 19, 2025 at 10:24:44PM +0530, Mukesh Ojha wrote:
> > Extend parse_fw callback to include SMC call to get resource
> > table from TrustZone to leverage resource table parse and
> > mapping and unmapping code reuse from the framework.
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/remoteproc/qcom_q6v5_pas.c | 33 +++++++++++++++++++++++++++--
> > drivers/soc/qcom/mdt_loader.c | 1 -
> > include/linux/soc/qcom/mdt_loader.h | 2 ++
> > 3 files changed, 33 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> > index 09cada92dfd5..1e0f09bf1ef2 100644
> > --- a/drivers/remoteproc/qcom_q6v5_pas.c
> > +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> > @@ -408,6 +408,35 @@ 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)
> > +{
> > + struct qcom_pas *pas = rproc->priv;
> > + size_t output_rt_size = MAX_RSCTABLE_SIZE;
> > + void *output_rt;
> > + 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 = qcom_scm_pas_get_rsc_table(pas->pas_id, NULL, 0, &output_rt, &output_rt_size);
>
> In PATCH 07/11 you have support for "static" resources that can be part
> of the firmware binary, but then you never make use of it. Like in the
> iris patch you just give in NULL, 0 for input_rt, even though,
> (presumably?) the remoteproc framework has support for parsing the
> resource table from the ELF firmware image.
Should have added a check here
ret = rproc_elf_load_rsc_table(rproc, fw);
if (ret)
dev_info(&rproc->dev, "Error in loading resource table in firmware\n");
ret = qcom_scm_pas_get_rsc_table(pas->pas_id, rproc->table_ptr, rproc->table_sz, &output_rt, &output_rt_size);
...
..
return ret;
..
}
> I would suggest adding a comment here justifying this and perhaps
> something to the commit message. I do see value in having the
> qcom_scm_pas_get_rsc_table() properly defined with input RT support, but
> it's not obvious from the description of your patches that this is
> effectively dead code right now(?).
Sure, will add the comment where ever, I am going to pass NULL, 0, which
is for like IRIS. You rightly said, remoteproc can have its input_rt
by checking it in firmware binary have resource table while for others like
iris/venus etc. support is not there now but can be added in future.
-Mukesh
>
> > + if (ret) {
> > + dev_err(pas->dev, "error %d getting resource_table\n", ret);
> > + return ret;
> > + }
> > +
> > + 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;
> > @@ -420,7 +449,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,
> > };
> > @@ -430,7 +459,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,
> > diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> > index ea7034c4b996..8456cca3f3e0 100644
> > --- a/drivers/soc/qcom/mdt_loader.c
> > +++ b/drivers/soc/qcom/mdt_loader.c
> > @@ -22,7 +22,6 @@
> > #include <linux/slab.h>
> > #include <linux/soc/qcom/mdt_loader.h>
> >
> > -#define MAX_RSCTABLE_SIZE SZ_16K;
>
> I'm confused why there is a semicolon here suddenly. Did you edit this
> patch by hand?
>
> Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
> Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse resource table
> error: patch failed: drivers/soc/qcom/mdt_loader.c:22
> error: drivers/soc/qcom/mdt_loader.c: patch does not apply
Yes, I did this edit just before sending when checkpatch caught this.
Will avoid this in future.
>
> > #define RSC_TABLE_HASH_BITS 5 // 32 buckets
> >
> > DEFINE_HASHTABLE(qcom_pas_rsc_table_map, RSC_TABLE_HASH_BITS);
> > diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
> > index 62f239f64dfb..92ad862e733e 100644
> > --- a/include/linux/soc/qcom/mdt_loader.h
> > +++ b/include/linux/soc/qcom/mdt_loader.h
> > @@ -8,6 +8,8 @@
> > #define QCOM_MDT_TYPE_HASH (2 << 24)
> > #define QCOM_MDT_RELOCATABLE BIT(27)
> >
> > +#define MAX_RSCTABLE_SIZE SZ_16K
> > +
> > struct device;
> > struct firmware;
> > struct qcom_scm_pas_ctx;
>
> You added this define yourself in PATCH 08/11, so just add it in the
> right place directly. Make sure you scroll through your patch set before
> sending to make sure all changes are in the right commit. :-)
I did this intentionally, because there is outside user of this macro
with this patch.
>
> Thanks,
> Stephan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-08-20 11:03 ` [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Bryan O'Donoghue
@ 2025-08-20 11:22 ` Mukesh Ojha
2025-09-03 11:56 ` Konrad Dybcio
0 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 11:22 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Wed, Aug 20, 2025 at 12:03:16PM +0100, Bryan O'Donoghue wrote:
> On 19/08/2025 17:54, Mukesh Ojha wrote:
> > This is a further continuation with a new approach to the topic
> > discussed in [1] regarding the enablement of Secure Peripheral Image
> > Loader support on Qualcomm SoCs when Linux runs at EL2.
> >
> > A few months ago, we also discussed the challenges at Linaro Connect
> > 2025 [2] related to enabling remoteproc when Linux is running at EL2.
> >
> > [1]
> > https://lore.kernel.org/lkml/20241004212359.2263502-1-quic_mojha@quicinc.com/
> >
> > [2]
> > https://resources.linaro.org/en/resource/sF8jXifdb9V1mUefdbfafa
> >
> > Below, is the summary of the discussion.
>
> Which tree does this apply to exactly ?
>
> git-log-graph linux-stable/master
> * c17b750b3ad9f - (tag: v6.17-rc2, linux-stable/master, linux-stable/HEAD)
> Linux 6.17-rc2 (3 days ago)
> * 8d561baae505b - Merge tag 'x86_urgent_for_v6.17_rc2' of
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip (3 days ago)
>
> b4 shazam 20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com
>
> b4 shazam 20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com
>
> Grabbing thread from lore.kernel.org/all/20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com/t.mbox.gz
> Checking for newer revisions
> Grabbing search results from lore.kernel.org
> Analyzing 18 messages in the thread
> Analyzing 0 code-review messages
> Checking attestation on all messages, may take a moment...
> ---
> ✓ [PATCH v2 1/11] firmware: qcom_scm: Introduce PAS context initialization
> helper
> ✓ [PATCH v2 2/11] soc: qcom: mdtloader: Add context aware
> qcom_mdt_pas_load() helper
> ✓ [PATCH v2 3/11] firmware: qcom_scm: Add a prep version of auth_and_reset
> function
> ✓ [PATCH v2 4/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
> ✓ [PATCH v2 5/11] firmware: qcom_scm: Add shmbridge support to
> pas_init/release function
> ✓ [PATCH v2 6/11] remoteproc: Move resource table data structure to its
> own header
> ✓ [PATCH v2 7/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to
> get resource table
> ✓ [PATCH v2 8/11] soc: qcom: mdt_loader: Add helper functions to map and
> unmap resources
> ✓ [PATCH v2 9/11] remoteproc: pas: Extend parse_fw callback to parse
> resource table
> ✓ [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with
> IOMMU managed by Linux
> ✓ [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU
> managed by Linux
> ---
> ✓ Signed: DKIM/qualcomm.com (From: mukesh.ojha@oss.qualcomm.com)
> ---
> Total patches: 11
> ---
> Applying: firmware: qcom_scm: Introduce PAS context initialization helper
> Applying: soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
> Patch failed at 0002 soc: qcom: mdtloader: Add context aware
> qcom_mdt_pas_load() helper
> error: patch failed: drivers/remoteproc/qcom_q6v5_pas.c:235
> error: drivers/remoteproc/qcom_q6v5_pas.c: patch does not apply
> error: patch failed: drivers/soc/qcom/mdt_loader.c:302
> error: drivers/soc/qcom/mdt_loader.c: patch does not apply
> error: patch failed: include/linux/soc/qcom/mdt_loader.h:10
> error: include/linux/soc/qcom/mdt_loader.h: patch does not apply
> hint: Use 'git am --show-current-patch=diff' to see the failed patch
> hint: When you have resolved this problem, run "git am --continue".
> hint: If you prefer to skip this patch, run "git am --skip" instead.
> hint: To restore the original branch and stop patching, run "git am
> --abort".
> hint: Disable this message with "git config set advice.mergeConflict false"
Very sorry for the error.
Can you try with this next-20250814 tag ?
But yes, forgive me for the minor manual edit I did
https://lore.kernel.org/lkml/20250820111448.tjaz2wld2nxg52aq@hu-mojha-hyd.qualcomm.com/
>
> ---
> bod
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-19 16:54 ` [PATCH v2 11/11] media: iris: " Mukesh Ojha
2025-08-20 8:46 ` Stephan Gerhold
@ 2025-08-20 11:33 ` Bryan O'Donoghue
2025-08-20 12:00 ` Mukesh Ojha
2025-08-22 8:45 ` Krzysztof Kozlowski
2 siblings, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-20 11:33 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> or QHEE), 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 hypervisor is absent, the operating system must perform these
> configurations instead.
>
> Support for handling IOMMU and SHM setup in the absence of a hypervisor
> is now in place. Extend the Iris driver to enable this functionality on
> platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
>
> Additionally, the Iris driver must map the firmware and its required
> resources to the firmware SID, which is now specified via the device tree.
>
> Co-developed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_core.c | 9 +-
> drivers/media/platform/qcom/iris/iris_core.h | 6 +
> .../media/platform/qcom/iris/iris_firmware.c | 156 ++++++++++++++++--
> .../media/platform/qcom/iris/iris_firmware.h | 2 +
> 4 files changed, 155 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c
> index 0fa0a3b549a2..57417d4d7e05 100644
> --- a/drivers/media/platform/qcom/iris/iris_core.c
> +++ b/drivers/media/platform/qcom/iris/iris_core.c
> @@ -17,6 +17,7 @@ void iris_core_deinit(struct iris_core *core)
> mutex_lock(&core->lock);
> iris_fw_unload(core);
> iris_vpu_power_off(core);
> + iris_fw_deinit(core);
> iris_hfi_queues_deinit(core);
> core->state = IRIS_CORE_DEINIT;
> mutex_unlock(&core->lock);
> @@ -65,10 +66,14 @@ int iris_core_init(struct iris_core *core)
> if (ret)
> goto error_queue_deinit;
>
> - ret = iris_fw_load(core);
> + ret = iris_fw_init(core);
> if (ret)
> goto error_power_off;
>
> + ret = iris_fw_load(core);
> + if (ret)
> + goto error_firmware_deinit;
> +
> ret = iris_vpu_boot_firmware(core);
> if (ret)
> goto error_unload_fw;
> @@ -83,6 +88,8 @@ int iris_core_init(struct iris_core *core)
>
> error_unload_fw:
> iris_fw_unload(core);
> +error_firmware_deinit:
> + iris_fw_deinit(core);
> error_power_off:
> iris_vpu_power_off(core);
> error_queue_deinit:
> diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
> index aeeac32a1f6d..57eeefb38f22 100644
> --- a/drivers/media/platform/qcom/iris/iris_core.h
> +++ b/drivers/media/platform/qcom/iris/iris_core.h
> @@ -73,6 +73,12 @@ struct iris_core {
> int irq;
> struct v4l2_device v4l2_dev;
> struct video_device *vdev_dec;
> + bool has_iommu;
> + struct video_firmware {
> + struct device *dev;
> + struct qcom_scm_pas_ctx *ctx;
> + struct iommu_domain *iommu_domain;
> + } fw;
> const struct v4l2_file_operations *iris_v4l2_file_ops;
> const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops;
> const struct vb2_ops *iris_vb2_ops;
> diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
> index f1b5cd56db32..e3f2fe5c9d7a 100644
> --- a/drivers/media/platform/qcom/iris/iris_firmware.c
> +++ b/drivers/media/platform/qcom/iris/iris_firmware.c
> @@ -3,10 +3,18 @@
> * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> */
>
> +#include <linux/device.h>
> #include <linux/firmware.h>
> -#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/kernel.h>
> +#include <linux/iommu.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/of_reserved_mem.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_device.h>
> +#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/sizes.h>
> #include <linux/soc/qcom/mdt_loader.h>
>
> #include "iris_core.h"
> @@ -17,15 +25,14 @@
> static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> {
> u32 pas_id = core->iris_platform_data->pas_id;
> + struct qcom_scm_pas_ctx *ctx;
> const struct firmware *firmware = NULL;
> struct device *dev = core->dev;
> - struct reserved_mem *rmem;
> - struct device_node *node;
> - phys_addr_t mem_phys;
> - size_t res_size;
> - ssize_t fw_size;
> - void *mem_virt;
> - int ret;
> + struct reserved_mem *rmem = NULL;
> + struct device_node *node = NULL;
> + ssize_t fw_size = 0;
> + void *mem_virt = NULL;
> + int ret = 0;
>
> if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
> return -EINVAL;
> @@ -39,36 +46,64 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> if (!rmem)
> return -EINVAL;
>
> - mem_phys = rmem->base;
> - res_size = rmem->size;
> + if (core->has_iommu)
> + dev = core->fw.dev;
>
> + ctx = qcom_scm_pas_ctx_init(dev, pas_id, rmem->base, rmem->size, false);
> + if (!ctx)
> + return -ENOMEM;
> +
> + ctx->has_iommu = core->has_iommu;
> ret = request_firmware(&firmware, fw_name, dev);
> if (ret)
> return ret;
>
> fw_size = qcom_mdt_get_size(firmware);
> - if (fw_size < 0 || res_size < (size_t)fw_size) {
> + if (fw_size < 0 || rmem->size < (size_t)fw_size) {
> ret = -EINVAL;
> goto err_release_fw;
> }
>
> - mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC);
> + mem_virt = memremap(rmem->base, rmem->size, MEMREMAP_WC);
> if (!mem_virt) {
> ret = -ENOMEM;
> goto err_release_fw;
> }
>
> - ret = qcom_mdt_load(dev, firmware, fw_name,
> - pas_id, mem_virt, mem_phys, res_size, NULL);
> + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL);
> if (ret)
> goto err_mem_unmap;
>
> - ret = qcom_scm_pas_auth_and_reset(pas_id);
> + if (core->has_iommu) {
> + ret = iommu_map(core->fw.iommu_domain, 0, rmem->base, rmem->size,
> + IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
> + if (ret)
> + goto err_mem_unmap;
> +
> + /*
> + * Firmware has no support for resource table for now, so, lets
> + * pass NULL and zero for input resource table and input resource
> + * table respectively.
> + */
> + ret = qcom_mdt_pas_map_devmem_rscs(ctx, core->fw.iommu_domain, NULL, 0);
> + if (ret)
> + goto err_unmap_carveout;
> + }
> +
> + ret = qcom_scm_pas_prepare_and_auth_reset(ctx);
> if (ret)
> - goto err_mem_unmap;
> + goto err_unmap_devmem_rscs;
> +
> + core->fw.ctx = ctx;
>
> return ret;
>
> +err_unmap_devmem_rscs:
> + if (core->has_iommu)
> + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> +err_unmap_carveout:
> + if (core->has_iommu)
> + iommu_unmap(core->fw.iommu_domain, 0, rmem->size);
> err_mem_unmap:
> memunmap(mem_virt);
> err_release_fw:
> @@ -109,10 +144,97 @@ int iris_fw_load(struct iris_core *core)
>
> int iris_fw_unload(struct iris_core *core)
> {
> - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> + struct qcom_scm_pas_ctx *ctx;
> + int ret;
> +
> + ctx = core->fw.ctx;
> + ret = qcom_scm_pas_shutdown(ctx->peripheral);
> + if (core->has_iommu) {
> + iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size);
> + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> + }
> +
> + return ret;
> }
>
> int iris_set_hw_state(struct iris_core *core, bool resume)
> {
> return qcom_scm_set_remote_state(resume, 0);
> }
> +
> +int iris_fw_init(struct iris_core *core)
> +{
> + struct platform_device_info info;
> + struct iommu_domain *iommu_dom;
> + struct platform_device *pdev;
> + struct device_node *np;
> + int ret;
> +
> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> + if (!np)
> + return 0;
> +
> + core->has_iommu = true;
You set has_iommu = true and then you check this flag throughout this
patch..
> + memset(&info, 0, sizeof(info));
> + info.fwnode = &np->fwnode;
> + info.parent = core->dev;
> + info.name = np->name;
> + info.dma_mask = DMA_BIT_MASK(32);
> +
> + pdev = platform_device_register_full(&info);
> + if (IS_ERR(pdev)) {
> + of_node_put(np);
> + return PTR_ERR(pdev);
> + }
> +
> + pdev->dev.of_node = np;
> +
> + ret = of_dma_configure(&pdev->dev, np, true);
> + if (ret) {
> + dev_err(core->dev, "failed to allocate domain\n");
> + goto err_unregister;
> + }
> +
> + core->fw.dev = &pdev->dev;
> +
> + iommu_dom = iommu_get_domain_for_dev(core->fw.dev);
> + if (!iommu_dom) {
> + dev_err(core->fw.dev, "Failed to get iommu domain\n");
> + ret = -EINVAL;
> + goto err_iommu_free;
> + }
> +
> + ret = iommu_attach_device(iommu_dom, core->fw.dev);
> + if (ret) {
> + dev_err(core->fw.dev, "could not attach device\n");
> + goto err_iommu_free;
> + }
> +
> + core->fw.iommu_domain = iommu_dom;
> +
> + of_node_put(np);
> +
> + return 0;
> +
> +err_iommu_free:
> + iommu_domain_free(iommu_dom);
> +err_unregister:
> + platform_device_unregister(pdev);
> + of_node_put(np);
> + return ret;
> +}
> +
> +void iris_fw_deinit(struct iris_core *core)
> +{
> + struct iommu_domain *iommu_dom;
> +
> + if (!core->has_iommu)
This is fixed in your code is it not ?
You presumably are going to change this later otherwise suggest dropping
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper
2025-08-19 16:54 ` [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper Mukesh Ojha
2025-08-19 17:17 ` Pavan Kondeti
@ 2025-08-20 11:40 ` Bryan O'Donoghue
2025-08-20 12:28 ` Mukesh Ojha
1 sibling, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-20 11:40 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> Currently, remoteproc and non-remoteproc subsystems use different
> variants of the MDT loader helper API, primarily due to the handling of
> the metadata context. Remoteproc subsystems retain this context until
> authentication and reset, while non-remoteproc subsystems (e.g., video,
> graphics) do not require it.
>
> Unify the metadata loading process for both remoteproc and
> non-remoteproc subsystems by introducing a dedicated PAS context
> initialization function.
You've introduced what PAS is in the cover letter but you haven't done
so in the commit log where you use it.
"Peripheral Authentication Service (PAS)" should be defined in this
patch somewhere so we know what PAS means.
>
> By introducing qcom_scm_pas_ctx_init(), we can standardize the API usage
> across subsystems and reduce the number of parameters passed to MDT
> loader functions, improving code clarity and maintainability.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/firmware/qcom/qcom_scm.c | 26 ++++++++++++++++++++++++++
> include/linux/firmware/qcom/qcom_scm.h | 11 +++++++++++
> 2 files changed, 37 insertions(+)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 96d5cf40a74c..33187d4f4aef 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -558,6 +558,32 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
> dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
> }
>
> +void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> + size_t mem_size, bool save_mdt_ctx)
> +{
> + struct qcom_scm_pas_ctx *ctx;
> +
> + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> + if (!ctx)
> + return NULL;
> +
> + ctx->dev = dev;
> + ctx->peripheral = peripheral;
> + ctx->mem_phys = mem_phys;
> + ctx->mem_size = mem_size;
> + ctx->save_mdt_ctx = save_mdt_ctx;
> + ctx->metadata = NULL;
> +
> + if (save_mdt_ctx) {
You could check metadata != NULL and drop the bool ctx->save_mdt_ctx
entirely.
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
2025-08-19 16:54 ` [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper Mukesh Ojha
@ 2025-08-20 11:48 ` Bryan O'Donoghue
2025-08-20 12:25 ` Mukesh Ojha
2025-09-03 15:03 ` Bryan O'Donoghue
1 sibling, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-20 11:48 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> Currently, remoteproc and non-remoteproc subsystems use different
> variants of the MDT loader helper API, primarily due to the handling of
> the metadata context. Remoteproc subsystems retain this context until
> authentication and reset, while non-remoteproc subsystems (e.g., video,
> graphics) do not require it.
>
> Add context aware qcom_mdt_pas_load() function which uses context
> returned from qcom_scm_pas_ctx_init() and use it till subsystems
> is out of set. This will also help in unifying the API used by
> remoteproc and non-remoteproc subsystems drivers.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> If this approach is preferred, will convert all subsystem drivers to use the
> same set of API's using context and completely get away with qcom_mdt_load()
>
> -Mukesh
>
> drivers/remoteproc/qcom_q6v5_pas.c | 53 ++++++++++++++---------------
> drivers/soc/qcom/mdt_loader.c | 26 ++++++++++----
> include/linux/soc/qcom/mdt_loader.h | 22 ++++++------
> 3 files changed, 56 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index 55a7da801183..e376c0338576 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> @@ -115,8 +115,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_ctx *pas_ctx;
> + struct qcom_scm_pas_ctx *dtb_pas_ctx;
> };
>
> static void qcom_pas_segment_dump(struct rproc *rproc,
> @@ -209,9 +209,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->metadata);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
>
> return 0;
> }
> @@ -235,15 +235,8 @@ 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_metadata);
> - 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;
> }
> @@ -251,9 +244,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);
> -
> -release_dtb_firmware:
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> release_firmware(pas->dtb_firmware);
>
> return ret;
> @@ -301,14 +292,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_metadata);
> - 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->dtb_mem_reloc);
> if (ret)
> goto release_pas_metadata;
>
> @@ -328,9 +313,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->metadata);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
>
> /* firmware is used to pass reference from qcom_pas_start(), drop it now */
> pas->firmware = NULL;
> @@ -338,9 +323,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->metadata);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> disable_px_supply:
> if (pas->px_supply)
> regulator_disable(pas->px_supply);
> @@ -774,6 +759,18 @@ 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_ctx_init(pas->dev, pas->pas_id, pas->mem_phys,
> + pas->mem_size, true);
> + if (!pas->pas_ctx)
> + goto remove_ssr_sysmon;
this function already returns -ENOMEM you don't set ret to any
particular value so if qcom_scm_pas_ctx_init() returned NULL, you would
exit your probe function here "error out" with returning ret = 0
Please ERR_PTR() in qcom_scm_pas_ctx_init() and return the error up the
call stack via your remove_ssr_sysmon jump label.
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-20 8:46 ` Stephan Gerhold
@ 2025-08-20 11:56 ` Mukesh Ojha
2025-08-20 13:39 ` Stephan Gerhold
0 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 11:56 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 10:46:31AM +0200, Stephan Gerhold wrote:
> On Tue, Aug 19, 2025 at 10:24:46PM +0530, Mukesh Ojha wrote:
> > Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> > or QHEE), 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 hypervisor is absent, the operating system must perform these
> > configurations instead.
> >
> > Support for handling IOMMU and SHM setup in the absence of a hypervisor
> > is now in place. Extend the Iris driver to enable this functionality on
> > platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
> >
> > Additionally, the Iris driver must map the firmware and its required
> > resources to the firmware SID, which is now specified via the device tree.
> >
> > Co-developed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> > Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/media/platform/qcom/iris/iris_core.c | 9 +-
> > drivers/media/platform/qcom/iris/iris_core.h | 6 +
> > .../media/platform/qcom/iris/iris_firmware.c | 156 ++++++++++++++++--
> > .../media/platform/qcom/iris/iris_firmware.h | 2 +
> > 4 files changed, 155 insertions(+), 18 deletions(-)
> >
> > [...]
> > diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
> > index f1b5cd56db32..e3f2fe5c9d7a 100644
> > --- a/drivers/media/platform/qcom/iris/iris_firmware.c
> > +++ b/drivers/media/platform/qcom/iris/iris_firmware.c
> > @@ -3,10 +3,18 @@
> > * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> > */
> >
> > +#include <linux/device.h>
> > #include <linux/firmware.h>
> > -#include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/kernel.h>
> > +#include <linux/iommu.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > #include <linux/of_address.h>
> > #include <linux/of_reserved_mem.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/of_device.h>
> > +#include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/sizes.h>
> > #include <linux/soc/qcom/mdt_loader.h>
> >
> > #include "iris_core.h"
> > @@ -17,15 +25,14 @@
> > static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > {
> > u32 pas_id = core->iris_platform_data->pas_id;
> > + struct qcom_scm_pas_ctx *ctx;
> > const struct firmware *firmware = NULL;
> > struct device *dev = core->dev;
> > - struct reserved_mem *rmem;
> > - struct device_node *node;
> > - phys_addr_t mem_phys;
> > - size_t res_size;
> > - ssize_t fw_size;
> > - void *mem_virt;
> > - int ret;
> > + struct reserved_mem *rmem = NULL;
> > + struct device_node *node = NULL;
> > + ssize_t fw_size = 0;
> > + void *mem_virt = NULL;
> > + int ret = 0;
> >
> > if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
> > return -EINVAL;
> > @@ -39,36 +46,64 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > if (!rmem)
> > return -EINVAL;
> >
> > - mem_phys = rmem->base;
> > - res_size = rmem->size;
> > + if (core->has_iommu)
> > + dev = core->fw.dev;
> >
> > + ctx = qcom_scm_pas_ctx_init(dev, pas_id, rmem->base, rmem->size, false);
> > + if (!ctx)
> > + return -ENOMEM;
> > +
> > + ctx->has_iommu = core->has_iommu;
> > ret = request_firmware(&firmware, fw_name, dev);
> > if (ret)
> > return ret;
> >
> > fw_size = qcom_mdt_get_size(firmware);
> > - if (fw_size < 0 || res_size < (size_t)fw_size) {
> > + if (fw_size < 0 || rmem->size < (size_t)fw_size) {
> > ret = -EINVAL;
> > goto err_release_fw;
> > }
> >
> > - mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC);
> > + mem_virt = memremap(rmem->base, rmem->size, MEMREMAP_WC);
> > if (!mem_virt) {
> > ret = -ENOMEM;
> > goto err_release_fw;
> > }
> >
> > - ret = qcom_mdt_load(dev, firmware, fw_name,
> > - pas_id, mem_virt, mem_phys, res_size, NULL);
> > + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL);
> > if (ret)
> > goto err_mem_unmap;
> >
> > - ret = qcom_scm_pas_auth_and_reset(pas_id);
> > + if (core->has_iommu) {
> > + ret = iommu_map(core->fw.iommu_domain, 0, rmem->base, rmem->size,
> > + IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
>
> What is the use case for IOMMU_PRIV here? You don't have this flag for
> the qcom_q6v5_pas change.
This is there for historic regions, I may not have complete information about why
is it required but the reference is taken from venus support for chrome.
> > + if (ret)
> > + goto err_mem_unmap;
> > +
> > + /*
> > + * Firmware has no support for resource table for now, so, lets
> > + * pass NULL and zero for input resource table and input resource
> > + * table respectively.
> > + */
> > + ret = qcom_mdt_pas_map_devmem_rscs(ctx, core->fw.iommu_domain, NULL, 0);
> > + if (ret)
> > + goto err_unmap_carveout;
> > + }
> > +
> > + ret = qcom_scm_pas_prepare_and_auth_reset(ctx);
> > if (ret)
> > - goto err_mem_unmap;
> > + goto err_unmap_devmem_rscs;
> > +
> > + core->fw.ctx = ctx;
> >
> > return ret;
> >
> > +err_unmap_devmem_rscs:
> > + if (core->has_iommu)
> > + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> > +err_unmap_carveout:
> > + if (core->has_iommu)
> > + iommu_unmap(core->fw.iommu_domain, 0, rmem->size);
> > err_mem_unmap:
> > memunmap(mem_virt);
> > err_release_fw:
> > @@ -109,10 +144,97 @@ int iris_fw_load(struct iris_core *core)
> >
> > int iris_fw_unload(struct iris_core *core)
> > {
> > - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> > + struct qcom_scm_pas_ctx *ctx;
> > + int ret;
> > +
> > + ctx = core->fw.ctx;
> > + ret = qcom_scm_pas_shutdown(ctx->peripheral);
> > + if (core->has_iommu) {
> > + iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size);
> > + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> > + }
> > +
> > + return ret;
> > }
> >
> > int iris_set_hw_state(struct iris_core *core, bool resume)
> > {
> > return qcom_scm_set_remote_state(resume, 0);
> > }
> > +
> > +int iris_fw_init(struct iris_core *core)
> > +{
> > + struct platform_device_info info;
> > + struct iommu_domain *iommu_dom;
> > + struct platform_device *pdev;
> > + struct device_node *np;
> > + int ret;
> > +
> > + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > + if (!np)
> > + return 0;
>
> You need a dt-bindings change for this as well. This is documented only
> for Venus.
You are right, wanted to send device tree and binding support separately.
But if required, will add with the series in the next version.
>
> Thanks,
> Stephan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-20 11:33 ` Bryan O'Donoghue
@ 2025-08-20 12:00 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 12:00 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Wed, Aug 20, 2025 at 12:33:44PM +0100, Bryan O'Donoghue wrote:
> On 19/08/2025 17:54, Mukesh Ojha wrote:
> > Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> > or QHEE), 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 hypervisor is absent, the operating system must perform these
> > configurations instead.
> >
> > Support for handling IOMMU and SHM setup in the absence of a hypervisor
> > is now in place. Extend the Iris driver to enable this functionality on
> > platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
> >
> > Additionally, the Iris driver must map the firmware and its required
> > resources to the firmware SID, which is now specified via the device tree.
> >
> > Co-developed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> > Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/media/platform/qcom/iris/iris_core.c | 9 +-
> > drivers/media/platform/qcom/iris/iris_core.h | 6 +
> > .../media/platform/qcom/iris/iris_firmware.c | 156 ++++++++++++++++--
> > .../media/platform/qcom/iris/iris_firmware.h | 2 +
> > 4 files changed, 155 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c
> > index 0fa0a3b549a2..57417d4d7e05 100644
> > --- a/drivers/media/platform/qcom/iris/iris_core.c
> > +++ b/drivers/media/platform/qcom/iris/iris_core.c
> > @@ -17,6 +17,7 @@ void iris_core_deinit(struct iris_core *core)
> > mutex_lock(&core->lock);
> > iris_fw_unload(core);
> > iris_vpu_power_off(core);
> > + iris_fw_deinit(core);
> > iris_hfi_queues_deinit(core);
> > core->state = IRIS_CORE_DEINIT;
> > mutex_unlock(&core->lock);
> > @@ -65,10 +66,14 @@ int iris_core_init(struct iris_core *core)
> > if (ret)
> > goto error_queue_deinit;
> > - ret = iris_fw_load(core);
> > + ret = iris_fw_init(core);
> > if (ret)
> > goto error_power_off;
> > + ret = iris_fw_load(core);
> > + if (ret)
> > + goto error_firmware_deinit;
> > +
> > ret = iris_vpu_boot_firmware(core);
> > if (ret)
> > goto error_unload_fw;
> > @@ -83,6 +88,8 @@ int iris_core_init(struct iris_core *core)
> > error_unload_fw:
> > iris_fw_unload(core);
> > +error_firmware_deinit:
> > + iris_fw_deinit(core);
> > error_power_off:
> > iris_vpu_power_off(core);
> > error_queue_deinit:
> > diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
> > index aeeac32a1f6d..57eeefb38f22 100644
> > --- a/drivers/media/platform/qcom/iris/iris_core.h
> > +++ b/drivers/media/platform/qcom/iris/iris_core.h
> > @@ -73,6 +73,12 @@ struct iris_core {
> > int irq;
> > struct v4l2_device v4l2_dev;
> > struct video_device *vdev_dec;
> > + bool has_iommu;
> > + struct video_firmware {
> > + struct device *dev;
> > + struct qcom_scm_pas_ctx *ctx;
> > + struct iommu_domain *iommu_domain;
> > + } fw;
> > const struct v4l2_file_operations *iris_v4l2_file_ops;
> > const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops;
> > const struct vb2_ops *iris_vb2_ops;
> > diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
> > index f1b5cd56db32..e3f2fe5c9d7a 100644
> > --- a/drivers/media/platform/qcom/iris/iris_firmware.c
> > +++ b/drivers/media/platform/qcom/iris/iris_firmware.c
> > @@ -3,10 +3,18 @@
> > * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> > */
> > +#include <linux/device.h>
> > #include <linux/firmware.h>
> > -#include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/kernel.h>
> > +#include <linux/iommu.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > #include <linux/of_address.h>
> > #include <linux/of_reserved_mem.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/of_device.h>
> > +#include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/sizes.h>
> > #include <linux/soc/qcom/mdt_loader.h>
> > #include "iris_core.h"
> > @@ -17,15 +25,14 @@
> > static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > {
> > u32 pas_id = core->iris_platform_data->pas_id;
> > + struct qcom_scm_pas_ctx *ctx;
> > const struct firmware *firmware = NULL;
> > struct device *dev = core->dev;
> > - struct reserved_mem *rmem;
> > - struct device_node *node;
> > - phys_addr_t mem_phys;
> > - size_t res_size;
> > - ssize_t fw_size;
> > - void *mem_virt;
> > - int ret;
> > + struct reserved_mem *rmem = NULL;
> > + struct device_node *node = NULL;
> > + ssize_t fw_size = 0;
> > + void *mem_virt = NULL;
> > + int ret = 0;
> > if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
> > return -EINVAL;
> > @@ -39,36 +46,64 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > if (!rmem)
> > return -EINVAL;
> > - mem_phys = rmem->base;
> > - res_size = rmem->size;
> > + if (core->has_iommu)
> > + dev = core->fw.dev;
> > + ctx = qcom_scm_pas_ctx_init(dev, pas_id, rmem->base, rmem->size, false);
> > + if (!ctx)
> > + return -ENOMEM;
> > +
> > + ctx->has_iommu = core->has_iommu;
> > ret = request_firmware(&firmware, fw_name, dev);
> > if (ret)
> > return ret;
> > fw_size = qcom_mdt_get_size(firmware);
> > - if (fw_size < 0 || res_size < (size_t)fw_size) {
> > + if (fw_size < 0 || rmem->size < (size_t)fw_size) {
> > ret = -EINVAL;
> > goto err_release_fw;
> > }
> > - mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC);
> > + mem_virt = memremap(rmem->base, rmem->size, MEMREMAP_WC);
> > if (!mem_virt) {
> > ret = -ENOMEM;
> > goto err_release_fw;
> > }
> > - ret = qcom_mdt_load(dev, firmware, fw_name,
> > - pas_id, mem_virt, mem_phys, res_size, NULL);
> > + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL);
> > if (ret)
> > goto err_mem_unmap;
> > - ret = qcom_scm_pas_auth_and_reset(pas_id);
> > + if (core->has_iommu) {
> > + ret = iommu_map(core->fw.iommu_domain, 0, rmem->base, rmem->size,
> > + IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
> > + if (ret)
> > + goto err_mem_unmap;
> > +
> > + /*
> > + * Firmware has no support for resource table for now, so, lets
> > + * pass NULL and zero for input resource table and input resource
> > + * table respectively.
> > + */
> > + ret = qcom_mdt_pas_map_devmem_rscs(ctx, core->fw.iommu_domain, NULL, 0);
> > + if (ret)
> > + goto err_unmap_carveout;
> > + }
> > +
> > + ret = qcom_scm_pas_prepare_and_auth_reset(ctx);
> > if (ret)
> > - goto err_mem_unmap;
> > + goto err_unmap_devmem_rscs;
> > +
> > + core->fw.ctx = ctx;
> > return ret;
> > +err_unmap_devmem_rscs:
> > + if (core->has_iommu)
> > + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> > +err_unmap_carveout:
> > + if (core->has_iommu)
> > + iommu_unmap(core->fw.iommu_domain, 0, rmem->size);
> > err_mem_unmap:
> > memunmap(mem_virt);
> > err_release_fw:
> > @@ -109,10 +144,97 @@ int iris_fw_load(struct iris_core *core)
> > int iris_fw_unload(struct iris_core *core)
> > {
> > - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> > + struct qcom_scm_pas_ctx *ctx;
> > + int ret;
> > +
> > + ctx = core->fw.ctx;
> > + ret = qcom_scm_pas_shutdown(ctx->peripheral);
> > + if (core->has_iommu) {
> > + iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size);
> > + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> > + }
> > +
> > + return ret;
> > }
> > int iris_set_hw_state(struct iris_core *core, bool resume)
> > {
> > return qcom_scm_set_remote_state(resume, 0);
> > }
> > +
> > +int iris_fw_init(struct iris_core *core)
> > +{
> > + struct platform_device_info info;
> > + struct iommu_domain *iommu_dom;
> > + struct platform_device *pdev;
> > + struct device_node *np;
> > + int ret;
> > +
> > + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > + if (!np)
> > + return 0;
> > +
> > + core->has_iommu = true;
>
> You set has_iommu = true and then you check this flag throughout this
> patch..
>
>
> > + memset(&info, 0, sizeof(info));
> > + info.fwnode = &np->fwnode;
> > + info.parent = core->dev;
> > + info.name = np->name;
> > + info.dma_mask = DMA_BIT_MASK(32);
> > +
> > + pdev = platform_device_register_full(&info);
> > + if (IS_ERR(pdev)) {
> > + of_node_put(np);
> > + return PTR_ERR(pdev);
> > + }
> > +
> > + pdev->dev.of_node = np;
> > +
> > + ret = of_dma_configure(&pdev->dev, np, true);
> > + if (ret) {
> > + dev_err(core->dev, "failed to allocate domain\n");
> > + goto err_unregister;
> > + }
> > +
> > + core->fw.dev = &pdev->dev;
> > +
> > + iommu_dom = iommu_get_domain_for_dev(core->fw.dev);
> > + if (!iommu_dom) {
> > + dev_err(core->fw.dev, "Failed to get iommu domain\n");
> > + ret = -EINVAL;
> > + goto err_iommu_free;
> > + }
> > +
> > + ret = iommu_attach_device(iommu_dom, core->fw.dev);
> > + if (ret) {
> > + dev_err(core->fw.dev, "could not attach device\n");
> > + goto err_iommu_free;
> > + }
> > +
> > + core->fw.iommu_domain = iommu_dom;
> > +
> > + of_node_put(np);
> > +
> > + return 0;
> > +
> > +err_iommu_free:
> > + iommu_domain_free(iommu_dom);
> > +err_unregister:
> > + platform_device_unregister(pdev);
> > + of_node_put(np);
> > + return ret;
> > +}
> > +
> > +void iris_fw_deinit(struct iris_core *core)
> > +{
> > + struct iommu_domain *iommu_dom;
> > +
> > + if (!core->has_iommu)
>
> This is fixed in your code is it not ?
>
> You presumably are going to change this later otherwise suggest dropping
Sure.
>
> ---
> bod
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 03/11] firmware: qcom_scm: Add a prep version of auth_and_reset function
2025-08-19 16:54 ` [PATCH v2 03/11] firmware: qcom_scm: Add a prep version of auth_and_reset function Mukesh Ojha
@ 2025-08-20 12:03 ` Bryan O'Donoghue
2025-08-20 12:24 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-20 12:03 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> Qualcomm SoCs running with QHEE (Qualcomm Hypervisor Execution
> Environment—a library present in the Gunyah hypervisor) utilize the
> Peripheral Authentication Service (PAS) from TrustZone (TZ) firmware to
> securely authenticate and reset remote processors via a sequence of SMC
> calls such as qcom_scm_pas_init_image(), qcom_scm_pas_mem_setup(), and
> qcom_scm_pas_auth_and_reset().
>
> For memory passed to Qualcomm TrustZone, it must either be part of a
> pool registered with TZ or be directly registered via SHMbridge SMC
> calls.
>
> When QHEE is present, PAS SMC calls from Linux running at EL1 are
> trapped by QHEE (running at EL2), which then creates or retrieves memory
> from the SHMbridge for both metadata and remoteproc carveout memory
> before passing them to TZ. However, when the SoC runs with a
> non-QHEE-based hypervisor, Linux must create the SHM bridge for both
> metadata (before it is passed to TZ in qcom_scm_pas_init_image()) and
> for remoteproc memory (before the call is made to TZ in
> qcom_scm_pas_auth_and_reset()).
>
> For auth_and_reset() call, first it need to register remoteproc carveout
> memory with TZ via SHMbridge SMC call and then it can trigger
> auth_and_reset SMC call and once the call returns, remoteproc carveout
> memory can be deregisterd with TZ.
>
> Add qcom_scm_pas_prepare_and_auth_reset() function which does prepare
> the SHMbridge over carveout memory and call auth_and_reset SMC call.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/firmware/qcom/qcom_scm.c | 46 ++++++++++++++++++++++++++
> include/linux/firmware/qcom/qcom_scm.h | 2 ++
> 2 files changed, 48 insertions(+)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 33187d4f4aef..9a5b34f5bacb 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -759,6 +759,52 @@ int qcom_scm_pas_auth_and_reset(u32 peripheral)
> }
> 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_ctx_init()
> + *
> + * This function performs the necessary steps to prepare a PAS subsystem,
> + * authenticate it using the provided metadata, and initiate a reset sequence.
> + *
> + * It is typically used when Linux is in control setting up the IOMMU hardware
Is there a non-typical case ?
"This function is used"
> + * for remote subsystem during secure firmware loading processes. The preparation
> + * step sets up shmbridge over the firmware memory before TrustZone access the
shmbridge -> "a shmbridge"
"access" -> "accesses"
> + * 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_ctx *ctx)
> +{
> + u64 handle;
> + int ret;
> +
> + if (!ctx->has_iommu)
> + return qcom_scm_pas_auth_and_reset(ctx->peripheral);
> +
> + /*
> + * When Linux running at EL1, Gunyah(EL2) traps auth_and_reset call and creates
> + * shmbridge on subsystem memory region before it passes the call to TrustZone
> + * to authenticate it while when Linux runs at EL2, it needs to create shmbridge
> + * before this call goes to TrustZone.
> + */
If Linux is running at EL1, Gunyah running at EL2 traps the
auth_and_reset call, creates a shmbridge in "subsystem memory ? bod:
which subsystem do you mean here" and then passes the call to TrustZone.
If Linux is running at EL2 then Linux needs to create the shmbridge
before calling into TrustZone.
> + ret = qcom_tzmem_shm_bridge_create(ctx->mem_phys, ctx->mem_size, &handle);
> + if (ret) {
> + dev_err(__scm->dev, "Failed to create shmbridge ret=%d %u\n",
> + ret, ctx->peripheral);
> + return ret;
> + }
> +
> + ret = qcom_scm_pas_auth_and_reset(ctx->peripheral);
> + 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
> * @peripheral: peripheral id
> diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> index b7eb206561a9..a31006fe49a9 100644
> --- a/include/linux/firmware/qcom/qcom_scm.h
> +++ b/include/linux/firmware/qcom/qcom_scm.h
> @@ -79,6 +79,7 @@ struct qcom_scm_pas_ctx {
> size_t mem_size;
> struct qcom_scm_pas_metadata *metadata;
> bool save_mdt_ctx;
> + bool has_iommu;
> };
>
> void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> @@ -87,6 +88,7 @@ int qcom_scm_pas_init_image(u32 peripheral, 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_prepare_and_auth_reset(struct qcom_scm_pas_ctx *ctx);
> int qcom_scm_pas_auth_and_reset(u32 peripheral);
> int qcom_scm_pas_shutdown(u32 peripheral);
> bool qcom_scm_pas_supported(u32 peripheral);
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux
2025-08-20 8:40 ` Stephan Gerhold
@ 2025-08-20 12:03 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 12:03 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 10:40:25AM +0200, Stephan Gerhold wrote:
> On Tue, Aug 19, 2025 at 10:24:45PM +0530, Mukesh Ojha wrote:
> > Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> > or QHEE), 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 (at 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 is the 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 | 63 +++++++++++++++++++++++++++---
> > 1 file changed, 57 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> > index 1e0f09bf1ef2..180528bcd57c 100644
> > --- a/drivers/remoteproc/qcom_q6v5_pas.c
> > +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> > [...]
> > @@ -424,7 +459,8 @@ static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware *f
> > if (!rproc->has_iommu)
> > return ret;
> >
> > - ret = qcom_scm_pas_get_rsc_table(pas->pas_id, NULL, 0, &output_rt, &output_rt_size);
> > + ret = qcom_scm_pas_get_rsc_table(pas->pas_ctx, NULL, 0,
> > + &output_rt, &output_rt_size);
>
> Unrelated formatting change, should be in previous commit.
Ack, will fix.
>
> > if (ret) {
> > dev_err(pas->dev, "error %d getting resource_table\n", ret);
> > return ret;
> > @@ -726,6 +762,20 @@ static int qcom_pas_probe(struct platform_device *pdev)
> > return -ENOMEM;
> > }
> >
> > + if (of_property_present(pdev->dev.of_node, "iommus")) {
>
> I think you need a dt-bindings change for this? You had one in v1, but
> dropped it entirely for some reason.
I missed to mentioned it in changelog.
As I said in another patch, I intended to send it separately however,
will send it along with this series in the next version.
>
> > + struct of_phandle_args args;
> > +
> > + ret = of_parse_phandle_with_args(pdev->dev.of_node, "iommus",
> > + "#iommu-cells", 0, &args);
> > + if (ret < 0)
> > + return ret;
> > +
> > + rproc->has_iommu = true;
> > + of_node_put(args.np);
> > + } else {
> > + rproc->has_iommu = false;
> > + }
> > +
> > rproc->auto_boot = desc->auto_boot;
> > rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
> >
> > @@ -800,6 +850,7 @@ static int qcom_pas_probe(struct platform_device *pdev)
> > if (!pas->dtb_pas_ctx)
> > goto remove_ssr_sysmon;
> >
> > + pas->pas_ctx->has_iommu = pas->dtb_pas_ctx->has_iommu = rproc->has_iommu;
>
> Nitpick: I think this would look cleaner if you separate it into two
> lines (only one assignment on each line).
>
Sure.
Thanks for the review.
> Thanks,
> Stephan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 03/11] firmware: qcom_scm: Add a prep version of auth_and_reset function
2025-08-20 12:03 ` Bryan O'Donoghue
@ 2025-08-20 12:24 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 12:24 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Wed, Aug 20, 2025 at 01:03:41PM +0100, Bryan O'Donoghue wrote:
> On 19/08/2025 17:54, Mukesh Ojha wrote:
> > Qualcomm SoCs running with QHEE (Qualcomm Hypervisor Execution
> > Environment—a library present in the Gunyah hypervisor) utilize the
> > Peripheral Authentication Service (PAS) from TrustZone (TZ) firmware to
> > securely authenticate and reset remote processors via a sequence of SMC
> > calls such as qcom_scm_pas_init_image(), qcom_scm_pas_mem_setup(), and
> > qcom_scm_pas_auth_and_reset().
> >
> > For memory passed to Qualcomm TrustZone, it must either be part of a
> > pool registered with TZ or be directly registered via SHMbridge SMC
> > calls.
> >
> > When QHEE is present, PAS SMC calls from Linux running at EL1 are
> > trapped by QHEE (running at EL2), which then creates or retrieves memory
> > from the SHMbridge for both metadata and remoteproc carveout memory
> > before passing them to TZ. However, when the SoC runs with a
> > non-QHEE-based hypervisor, Linux must create the SHM bridge for both
> > metadata (before it is passed to TZ in qcom_scm_pas_init_image()) and
> > for remoteproc memory (before the call is made to TZ in
> > qcom_scm_pas_auth_and_reset()).
> >
> > For auth_and_reset() call, first it need to register remoteproc carveout
> > memory with TZ via SHMbridge SMC call and then it can trigger
> > auth_and_reset SMC call and once the call returns, remoteproc carveout
> > memory can be deregisterd with TZ.
> >
> > Add qcom_scm_pas_prepare_and_auth_reset() function which does prepare
> > the SHMbridge over carveout memory and call auth_and_reset SMC call.
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/qcom_scm.c | 46 ++++++++++++++++++++++++++
> > include/linux/firmware/qcom/qcom_scm.h | 2 ++
> > 2 files changed, 48 insertions(+)
> >
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 33187d4f4aef..9a5b34f5bacb 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -759,6 +759,52 @@ int qcom_scm_pas_auth_and_reset(u32 peripheral)
> > }
> > 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_ctx_init()
> > + *
> > + * This function performs the necessary steps to prepare a PAS subsystem,
> > + * authenticate it using the provided metadata, and initiate a reset sequence.
> > + *
> > + * It is typically used when Linux is in control setting up the IOMMU hardware
>
> Is there a non-typical case ?
In non-typical case is when system runs with Gunyah which in control of
IOMMU and create shmbridge before it passes the call to TrustZone.
>
> "This function is used"
Ack.
> > + * for remote subsystem during secure firmware loading processes. The preparation
> > + * step sets up shmbridge over the firmware memory before TrustZone access the
>
> shmbridge -> "a shmbridge"
> "access" -> "accesses"
Ack.
>
> > + * 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_ctx *ctx)
> > +{
> > + u64 handle;
> > + int ret;
> > +
> > + if (!ctx->has_iommu)
> > + return qcom_scm_pas_auth_and_reset(ctx->peripheral);
> > +
> > + /*
> > + * When Linux running at EL1, Gunyah(EL2) traps auth_and_reset call and creates
> > + * shmbridge on subsystem memory region before it passes the call to TrustZone
> > + * to authenticate it while when Linux runs at EL2, it needs to create shmbridge
> > + * before this call goes to TrustZone.
> > + */
>
> If Linux is running at EL1, Gunyah running at EL2 traps the auth_and_reset
> call, creates a shmbridge in "subsystem memory ? bod: which subsystem do you
> mean here"
Subsystem memory => remote processor carve out memory
> and then passes the call to TrustZone. If Linux is running at EL2
> then Linux needs to create the shmbridge before calling into TrustZone.
>
> > + ret = qcom_tzmem_shm_bridge_create(ctx->mem_phys, ctx->mem_size, &handle);
> > + if (ret) {
> > + dev_err(__scm->dev, "Failed to create shmbridge ret=%d %u\n",
> > + ret, ctx->peripheral);
> > + return ret;
> > + }
> > +
> > + ret = qcom_scm_pas_auth_and_reset(ctx->peripheral);
> > + 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
> > * @peripheral: peripheral id
> > diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> > index b7eb206561a9..a31006fe49a9 100644
> > --- a/include/linux/firmware/qcom/qcom_scm.h
> > +++ b/include/linux/firmware/qcom/qcom_scm.h
> > @@ -79,6 +79,7 @@ struct qcom_scm_pas_ctx {
> > size_t mem_size;
> > struct qcom_scm_pas_metadata *metadata;
> > bool save_mdt_ctx;
> > + bool has_iommu;
> > };
> > void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> > @@ -87,6 +88,7 @@ int qcom_scm_pas_init_image(u32 peripheral, 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_prepare_and_auth_reset(struct qcom_scm_pas_ctx *ctx);
> > int qcom_scm_pas_auth_and_reset(u32 peripheral);
> > int qcom_scm_pas_shutdown(u32 peripheral);
> > bool qcom_scm_pas_supported(u32 peripheral);
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
2025-08-20 11:48 ` Bryan O'Donoghue
@ 2025-08-20 12:25 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 12:25 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Wed, Aug 20, 2025 at 12:48:55PM +0100, Bryan O'Donoghue wrote:
> On 19/08/2025 17:54, Mukesh Ojha wrote:
> > Currently, remoteproc and non-remoteproc subsystems use different
> > variants of the MDT loader helper API, primarily due to the handling of
> > the metadata context. Remoteproc subsystems retain this context until
> > authentication and reset, while non-remoteproc subsystems (e.g., video,
> > graphics) do not require it.
> >
> > Add context aware qcom_mdt_pas_load() function which uses context
> > returned from qcom_scm_pas_ctx_init() and use it till subsystems
> > is out of set. This will also help in unifying the API used by
> > remoteproc and non-remoteproc subsystems drivers.
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > If this approach is preferred, will convert all subsystem drivers to use the
> > same set of API's using context and completely get away with qcom_mdt_load()
> >
> > -Mukesh
> >
> > drivers/remoteproc/qcom_q6v5_pas.c | 53 ++++++++++++++---------------
> > drivers/soc/qcom/mdt_loader.c | 26 ++++++++++----
> > include/linux/soc/qcom/mdt_loader.h | 22 ++++++------
> > 3 files changed, 56 insertions(+), 45 deletions(-)
> >
> > diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> > index 55a7da801183..e376c0338576 100644
> > --- a/drivers/remoteproc/qcom_q6v5_pas.c
> > +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> > @@ -115,8 +115,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_ctx *pas_ctx;
> > + struct qcom_scm_pas_ctx *dtb_pas_ctx;
> > };
> > static void qcom_pas_segment_dump(struct rproc *rproc,
> > @@ -209,9 +209,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->metadata);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > return 0;
> > }
> > @@ -235,15 +235,8 @@ 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_metadata);
> > - 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;
> > }
> > @@ -251,9 +244,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);
> > -
> > -release_dtb_firmware:
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > release_firmware(pas->dtb_firmware);
> > return ret;
> > @@ -301,14 +292,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_metadata);
> > - 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->dtb_mem_reloc);
> > if (ret)
> > goto release_pas_metadata;
> > @@ -328,9 +313,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->metadata);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > /* firmware is used to pass reference from qcom_pas_start(), drop it now */
> > pas->firmware = NULL;
> > @@ -338,9 +323,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->metadata);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > disable_px_supply:
> > if (pas->px_supply)
> > regulator_disable(pas->px_supply);
> > @@ -774,6 +759,18 @@ 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_ctx_init(pas->dev, pas->pas_id, pas->mem_phys,
> > + pas->mem_size, true);
> > + if (!pas->pas_ctx)
> > + goto remove_ssr_sysmon;
>
> this function already returns -ENOMEM you don't set ret to any particular
> value so if qcom_scm_pas_ctx_init() returned NULL, you would exit your probe
> function here "error out" with returning ret = 0
Ack.
>
> Please ERR_PTR() in qcom_scm_pas_ctx_init() and return the error up the call
> stack via your remove_ssr_sysmon jump label.
Sure.
>
> ---
> bod
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper
2025-08-20 11:40 ` Bryan O'Donoghue
@ 2025-08-20 12:28 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 12:28 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Wed, Aug 20, 2025 at 12:40:51PM +0100, Bryan O'Donoghue wrote:
> On 19/08/2025 17:54, Mukesh Ojha wrote:
> > Currently, remoteproc and non-remoteproc subsystems use different
> > variants of the MDT loader helper API, primarily due to the handling of
> > the metadata context. Remoteproc subsystems retain this context until
> > authentication and reset, while non-remoteproc subsystems (e.g., video,
> > graphics) do not require it.
> >
> > Unify the metadata loading process for both remoteproc and
> > non-remoteproc subsystems by introducing a dedicated PAS context
> > initialization function.
>
> You've introduced what PAS is in the cover letter but you haven't done so in
> the commit log where you use it.
>
> "Peripheral Authentication Service (PAS)" should be defined in this patch
> somewhere so we know what PAS means.
Ack.
>
> >
> > By introducing qcom_scm_pas_ctx_init(), we can standardize the API usage
> > across subsystems and reduce the number of parameters passed to MDT
> > loader functions, improving code clarity and maintainability.
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/qcom_scm.c | 26 ++++++++++++++++++++++++++
> > include/linux/firmware/qcom/qcom_scm.h | 11 +++++++++++
> > 2 files changed, 37 insertions(+)
> >
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 96d5cf40a74c..33187d4f4aef 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -558,6 +558,32 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
> > dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
> > }
> > +void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> > + size_t mem_size, bool save_mdt_ctx)
> > +{
> > + struct qcom_scm_pas_ctx *ctx;
> > +
> > + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> > + if (!ctx)
> > + return NULL;
> > +
> > + ctx->dev = dev;
> > + ctx->peripheral = peripheral;
> > + ctx->mem_phys = mem_phys;
> > + ctx->mem_size = mem_size;
> > + ctx->save_mdt_ctx = save_mdt_ctx;
> > + ctx->metadata = NULL;
> > +
> > + if (save_mdt_ctx) {
>
> You could check metadata != NULL and drop the bool ctx->save_mdt_ctx
> entirely.
Ack.
>
> ---
> bod
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table
2025-08-20 11:14 ` Mukesh Ojha
@ 2025-08-20 13:07 ` Stephan Gerhold
0 siblings, 0 replies; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 13:07 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 04:44:48PM +0530, Mukesh Ojha wrote:
> On Wed, Aug 20, 2025 at 10:36:10AM +0200, Stephan Gerhold wrote:
> > On Tue, Aug 19, 2025 at 10:24:44PM +0530, Mukesh Ojha wrote:
> [...]
> > > diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> > > index ea7034c4b996..8456cca3f3e0 100644
> > > --- a/drivers/soc/qcom/mdt_loader.c
> > > +++ b/drivers/soc/qcom/mdt_loader.c
> > > @@ -22,7 +22,6 @@
> > > #include <linux/slab.h>
> > > #include <linux/soc/qcom/mdt_loader.h>
> > >
> > > -#define MAX_RSCTABLE_SIZE SZ_16K;
> >
> > I'm confused why there is a semicolon here suddenly. Did you edit this
> > patch by hand?
> >
> > Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
> > Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse resource table
> > error: patch failed: drivers/soc/qcom/mdt_loader.c:22
> > error: drivers/soc/qcom/mdt_loader.c: patch does not apply
>
> Yes, I did this edit just before sending when checkpatch caught this.
> Will avoid this in future.
>
Please don't edit patches manually, fix the commit instead. ;)
> >
> > > #define RSC_TABLE_HASH_BITS 5 // 32 buckets
> > >
> > > DEFINE_HASHTABLE(qcom_pas_rsc_table_map, RSC_TABLE_HASH_BITS);
> > > diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
> > > index 62f239f64dfb..92ad862e733e 100644
> > > --- a/include/linux/soc/qcom/mdt_loader.h
> > > +++ b/include/linux/soc/qcom/mdt_loader.h
> > > @@ -8,6 +8,8 @@
> > > #define QCOM_MDT_TYPE_HASH (2 << 24)
> > > #define QCOM_MDT_RELOCATABLE BIT(27)
> > >
> > > +#define MAX_RSCTABLE_SIZE SZ_16K
> > > +
> > > struct device;
> > > struct firmware;
> > > struct qcom_scm_pas_ctx;
> >
> > You added this define yourself in PATCH 08/11, so just add it in the
> > right place directly. Make sure you scroll through your patch set before
> > sending to make sure all changes are in the right commit. :-)
>
> I did this intentionally, because there is outside user of this macro
> with this patch.
>
I don't think putting it in the header without an immediate user is a
problem, as long as a user appears somewhere in the same series.
Right now this patch touches multiple subsystems at once (qcom soc and
remoteproc), which should be avoided when possible.
Thanks,
Stpehan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-20 11:56 ` Mukesh Ojha
@ 2025-08-20 13:39 ` Stephan Gerhold
2025-08-22 4:26 ` Vikash Garodia
0 siblings, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 13:39 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 05:26:59PM +0530, Mukesh Ojha wrote:
> On Wed, Aug 20, 2025 at 10:46:31AM +0200, Stephan Gerhold wrote:
> > On Tue, Aug 19, 2025 at 10:24:46PM +0530, Mukesh Ojha wrote:
> > > Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> > > or QHEE), 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 hypervisor is absent, the operating system must perform these
> > > configurations instead.
> > >
> > > Support for handling IOMMU and SHM setup in the absence of a hypervisor
> > > is now in place. Extend the Iris driver to enable this functionality on
> > > platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
> > >
> > > Additionally, the Iris driver must map the firmware and its required
> > > resources to the firmware SID, which is now specified via the device tree.
> > >
> > > Co-developed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> > > Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > > ---
> > > drivers/media/platform/qcom/iris/iris_core.c | 9 +-
> > > drivers/media/platform/qcom/iris/iris_core.h | 6 +
> > > .../media/platform/qcom/iris/iris_firmware.c | 156 ++++++++++++++++--
> > > .../media/platform/qcom/iris/iris_firmware.h | 2 +
> > > 4 files changed, 155 insertions(+), 18 deletions(-)
> > >
> > > [...]
> > > diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
> > > index f1b5cd56db32..e3f2fe5c9d7a 100644
> > > --- a/drivers/media/platform/qcom/iris/iris_firmware.c
> > > +++ b/drivers/media/platform/qcom/iris/iris_firmware.c
> > > @@ -3,10 +3,18 @@
> > > * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> > > */
> > >
> > > +#include <linux/device.h>
> > > #include <linux/firmware.h>
> > > -#include <linux/firmware/qcom/qcom_scm.h>
> > > +#include <linux/kernel.h>
> > > +#include <linux/iommu.h>
> > > +#include <linux/io.h>
> > > +#include <linux/of.h>
> > > #include <linux/of_address.h>
> > > #include <linux/of_reserved_mem.h>
> > > +#include <linux/platform_device.h>
> > > +#include <linux/of_device.h>
> > > +#include <linux/firmware/qcom/qcom_scm.h>
> > > +#include <linux/sizes.h>
> > > #include <linux/soc/qcom/mdt_loader.h>
> > >
> > > #include "iris_core.h"
> > > @@ -17,15 +25,14 @@
> > > static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > > {
> > > u32 pas_id = core->iris_platform_data->pas_id;
> > > + struct qcom_scm_pas_ctx *ctx;
> > > const struct firmware *firmware = NULL;
> > > struct device *dev = core->dev;
> > > - struct reserved_mem *rmem;
> > > - struct device_node *node;
> > > - phys_addr_t mem_phys;
> > > - size_t res_size;
> > > - ssize_t fw_size;
> > > - void *mem_virt;
> > > - int ret;
> > > + struct reserved_mem *rmem = NULL;
> > > + struct device_node *node = NULL;
> > > + ssize_t fw_size = 0;
> > > + void *mem_virt = NULL;
> > > + int ret = 0;
> > >
> > > if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
> > > return -EINVAL;
> > > @@ -39,36 +46,64 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > > if (!rmem)
> > > return -EINVAL;
> > >
> > > - mem_phys = rmem->base;
> > > - res_size = rmem->size;
> > > + if (core->has_iommu)
> > > + dev = core->fw.dev;
> > >
> > > + ctx = qcom_scm_pas_ctx_init(dev, pas_id, rmem->base, rmem->size, false);
> > > + if (!ctx)
> > > + return -ENOMEM;
> > > +
> > > + ctx->has_iommu = core->has_iommu;
> > > ret = request_firmware(&firmware, fw_name, dev);
> > > if (ret)
> > > return ret;
> > >
> > > fw_size = qcom_mdt_get_size(firmware);
> > > - if (fw_size < 0 || res_size < (size_t)fw_size) {
> > > + if (fw_size < 0 || rmem->size < (size_t)fw_size) {
> > > ret = -EINVAL;
> > > goto err_release_fw;
> > > }
> > >
> > > - mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC);
> > > + mem_virt = memremap(rmem->base, rmem->size, MEMREMAP_WC);
> > > if (!mem_virt) {
> > > ret = -ENOMEM;
> > > goto err_release_fw;
> > > }
> > >
> > > - ret = qcom_mdt_load(dev, firmware, fw_name,
> > > - pas_id, mem_virt, mem_phys, res_size, NULL);
> > > + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL);
> > > if (ret)
> > > goto err_mem_unmap;
> > >
> > > - ret = qcom_scm_pas_auth_and_reset(pas_id);
> > > + if (core->has_iommu) {
> > > + ret = iommu_map(core->fw.iommu_domain, 0, rmem->base, rmem->size,
> > > + IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
> >
> > What is the use case for IOMMU_PRIV here? You don't have this flag for
> > the qcom_q6v5_pas change.
>
> This is there for historic regions, I may not have complete information about why
> is it required but the reference is taken from venus support for chrome.
>
Setting IOMMU_PRIV results in omitting the ARM_LPAE_PTE_AP_UNPRIV bit in
the IOMMU page tables - have you checked if QHEE sets this? Ideally we
want to do the same QHEE would normally do.
Also, please add a define for the 0 numbere here similar to
#define VENUS_FW_START_ADDR 0x0
It's quite hard to see that this is not an identity-mapping like for
qcom_q6v5_pas.
>
> > > + if (ret)
> > > + goto err_mem_unmap;
> > > +
> > > + /*
> > > + * Firmware has no support for resource table for now, so, lets
> > > + * pass NULL and zero for input resource table and input resource
> > > + * table respectively.
> > > + */
> > > + ret = qcom_mdt_pas_map_devmem_rscs(ctx, core->fw.iommu_domain, NULL, 0);
> > > + if (ret)
> > > + goto err_unmap_carveout;
> > > + }
> > > +
> > > + ret = qcom_scm_pas_prepare_and_auth_reset(ctx);
> > > if (ret)
> > > - goto err_mem_unmap;
> > > + goto err_unmap_devmem_rscs;
> > > +
> > > + core->fw.ctx = ctx;
> > >
> > > return ret;
> > >
> > > +err_unmap_devmem_rscs:
> > > + if (core->has_iommu)
> > > + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> > > +err_unmap_carveout:
> > > + if (core->has_iommu)
> > > + iommu_unmap(core->fw.iommu_domain, 0, rmem->size);
> > > err_mem_unmap:
> > > memunmap(mem_virt);
> > > err_release_fw:
> > > @@ -109,10 +144,97 @@ int iris_fw_load(struct iris_core *core)
> > >
> > > int iris_fw_unload(struct iris_core *core)
> > > {
> > > - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> > > + struct qcom_scm_pas_ctx *ctx;
> > > + int ret;
> > > +
> > > + ctx = core->fw.ctx;
> > > + ret = qcom_scm_pas_shutdown(ctx->peripheral);
> > > + if (core->has_iommu) {
> > > + iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size);
> > > + qcom_mdt_pas_unmap_devmem_rscs(ctx, core->fw.iommu_domain);
> > > + }
> > > +
> > > + return ret;
> > > }
> > >
> > > int iris_set_hw_state(struct iris_core *core, bool resume)
> > > {
> > > return qcom_scm_set_remote_state(resume, 0);
> > > }
> > > +
> > > +int iris_fw_init(struct iris_core *core)
> > > +{
> > > + struct platform_device_info info;
> > > + struct iommu_domain *iommu_dom;
> > > + struct platform_device *pdev;
> > > + struct device_node *np;
> > > + int ret;
> > > +
> > > + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > > + if (!np)
> > > + return 0;
> >
> > You need a dt-bindings change for this as well. This is documented only
> > for Venus.
>
> You are right, wanted to send device tree and binding support separately.
> But if required, will add with the series in the next version.
>
You can send device tree changes separately, but dt-binding changes
always need to come before the driver changes.
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-20 8:12 ` Stephan Gerhold
@ 2025-08-20 15:18 ` Mukesh Ojha
2025-08-20 15:31 ` Stephan Gerhold
2025-08-20 16:32 ` Mukesh Ojha
0 siblings, 2 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 15:18 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 10:12:15AM +0200, Stephan Gerhold wrote:
> On Tue, Aug 19, 2025 at 10:24:41PM +0530, Mukesh Ojha wrote:
> > The resource table data structure has traditionally been associated with
> > the remoteproc framework, where the resource table is included as a
> > section within the remote processor firmware binary. However, it is also
> > possible to obtain the resource table through other means—such as from a
> > reserved memory region populated by the boot firmware, statically
> > maintained driver data, or via a secure SMC call—when it is not embedded
> > in the firmware.
> >
> > There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> > etc.) in the upstream kernel that do not use the remoteproc framework to
> > manage their lifecycle for various reasons.
> >
> > When Linux is running at EL2, similar to the Qualcomm PAS driver
> > (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> > also want to use the resource table SMC call to retrieve and map
> > resources before they are used by the remote processor.
> >
>
> All the examples you give here (Venus/Iris, GPU) have some sort of EL2
> support already for older platforms:
Example was taken from perspective of remote processor life-cycle management.
You are right they have worked before in non-secure way for Chrome.
>
> - For GPU, we just skip loading the ZAP shader and access the protected
> registers directly. I would expect the ZAP shader does effectively
> the same, perhaps with some additional handling for secure mode. Is
> this even a real remote processor that has a separate IOMMU domain?
>
I don't think it is the case and think the same that they can skip
loading and Hence, I have not yet added support for it.
Will check internally before doing anything on GPU.
> - For Venus/Iris, there is code upstream similar to your PATCH 11/11
> that maps the firmware with the IOMMU (but invokes reset directly
> using the registers, without using PAS). There is no resource table
> used for that either, so at least all Venus/Iris versions so far
> apparently had no need for any mappings aside from the firmware
> binary.
You are absolutely right
>
> I understand that you want to continue using PAS for these, but I'm a
> bit confused what kind of mappings we would expect to have in the
> resource table for video and GPU. Could you give an example?
We have some debug hw tracing available for video for lemans, which is
optional However, I believe infra is good to have incase we need some
required resources to be map for Video to work for a SoC.
>
> Thanks,
> Stephan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-20 15:18 ` Mukesh Ojha
@ 2025-08-20 15:31 ` Stephan Gerhold
2025-08-22 7:56 ` Mukesh Ojha
2025-08-20 16:32 ` Mukesh Ojha
1 sibling, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 15:31 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 08:48:22PM +0530, Mukesh Ojha wrote:
> On Wed, Aug 20, 2025 at 10:12:15AM +0200, Stephan Gerhold wrote:
> > On Tue, Aug 19, 2025 at 10:24:41PM +0530, Mukesh Ojha wrote:
> > > The resource table data structure has traditionally been associated with
> > > the remoteproc framework, where the resource table is included as a
> > > section within the remote processor firmware binary. However, it is also
> > > possible to obtain the resource table through other means—such as from a
> > > reserved memory region populated by the boot firmware, statically
> > > maintained driver data, or via a secure SMC call—when it is not embedded
> > > in the firmware.
> > >
> > > There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> > > etc.) in the upstream kernel that do not use the remoteproc framework to
> > > manage their lifecycle for various reasons.
> > >
> > > When Linux is running at EL2, similar to the Qualcomm PAS driver
> > > (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> > > also want to use the resource table SMC call to retrieve and map
> > > resources before they are used by the remote processor.
> > >
> >
> > All the examples you give here (Venus/Iris, GPU) have some sort of EL2
> > support already for older platforms:
>
> Example was taken from perspective of remote processor life-cycle management.
> You are right they have worked before in non-secure way for Chrome.
>
> >
> > - For GPU, we just skip loading the ZAP shader and access the protected
> > registers directly. I would expect the ZAP shader does effectively
> > the same, perhaps with some additional handling for secure mode. Is
> > this even a real remote processor that has a separate IOMMU domain?
> >
>
> I don't think it is the case and think the same that they can skip
> loading and Hence, I have not yet added support for it.
>
> Will check internally before doing anything on GPU.
>
> > - For Venus/Iris, there is code upstream similar to your PATCH 11/11
> > that maps the firmware with the IOMMU (but invokes reset directly
> > using the registers, without using PAS). There is no resource table
> > used for that either, so at least all Venus/Iris versions so far
> > apparently had no need for any mappings aside from the firmware
> > binary.
>
> You are absolutely right
>
> >
> > I understand that you want to continue using PAS for these, but I'm a
> > bit confused what kind of mappings we would expect to have in the
> > resource table for video and GPU. Could you give an example?
>
> We have some debug hw tracing available for video for lemans, which is
> optional However, I believe infra is good to have incase we need some
> required resources to be map for Video to work for a SoC.
>
Thanks for the clarification.
Personally, I'm a bit concerned about the code duplication in PATCH
08/11, I think parsing the resource table should ideally be code shared
between the remoteproc subsystem and whereever else you need it. The way
you parse it and handle the IOMMU mappings is largely the same, you just
don't support all of the resource table functionality. Have you checked
if sharing the code would be feasible?
If there is no upstream requirement for this right now, you might want
to consider handling this in a follow up series, after you get the
required functionality in. This would reduce the amount of changes in
your series quite a bit.
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-20 15:18 ` Mukesh Ojha
2025-08-20 15:31 ` Stephan Gerhold
@ 2025-08-20 16:32 ` Mukesh Ojha
2025-08-20 16:53 ` Stephan Gerhold
2025-08-22 8:35 ` Krzysztof Kozlowski
1 sibling, 2 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-20 16:32 UTC (permalink / raw)
To: Stephan Gerhold, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On Wed, Aug 20, 2025 at 08:48:22PM +0530, Mukesh Ojha wrote:
> On Wed, Aug 20, 2025 at 10:12:15AM +0200, Stephan Gerhold wrote:
> > On Tue, Aug 19, 2025 at 10:24:41PM +0530, Mukesh Ojha wrote:
> > > The resource table data structure has traditionally been associated with
> > > the remoteproc framework, where the resource table is included as a
> > > section within the remote processor firmware binary. However, it is also
> > > possible to obtain the resource table through other means—such as from a
> > > reserved memory region populated by the boot firmware, statically
> > > maintained driver data, or via a secure SMC call—when it is not embedded
> > > in the firmware.
> > >
> > > There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> > > etc.) in the upstream kernel that do not use the remoteproc framework to
> > > manage their lifecycle for various reasons.
> > >
> > > When Linux is running at EL2, similar to the Qualcomm PAS driver
> > > (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> > > also want to use the resource table SMC call to retrieve and map
> > > resources before they are used by the remote processor.
> > >
> >
> > All the examples you give here (Venus/Iris, GPU) have some sort of EL2
> > support already for older platforms:
>
> Example was taken from perspective of remote processor life-cycle management.
> You are right they have worked before in non-secure way for Chrome.
>
> >
> > - For GPU, we just skip loading the ZAP shader and access the protected
> > registers directly. I would expect the ZAP shader does effectively
> > the same, perhaps with some additional handling for secure mode. Is
> > this even a real remote processor that has a separate IOMMU domain?
> >
>
> I don't think it is the case and think the same that they can skip
> loading and Hence, I have not yet added support for it.
>
> Will check internally before doing anything on GPU.
>
> > - For Venus/Iris, there is code upstream similar to your PATCH 11/11
> > that maps the firmware with the IOMMU (but invokes reset directly
> > using the registers, without using PAS). There is no resource table
> > used for that either, so at least all Venus/Iris versions so far
> > apparently had no need for any mappings aside from the firmware
> > binary.
>
> You are absolutely right
>
> >
> > I understand that you want to continue using PAS for these, but I'm a
> > bit confused what kind of mappings we would expect to have in the
> > resource table for video and GPU. Could you give an example?
>
> We have some debug hw tracing available for video for lemans, which is
> optional However, I believe infra is good to have incase we need some
> required resources to be map for Video to work for a SoC.
>
> >
> > Thanks,
> > Stephan
>
> --
> -Mukesh Ojha
Since I am not subscribed to any of the mailing lists to which this
series was sent, I am not receiving emails from the list. As a result,
your recent messages did not reach my inbox. Additionally, it seems your
reply inadvertently removed me from the To-list.
https://lore.kernel.org/lkml/aKXqSU-487b6Je2B@linaro.org/
https://lore.kernel.org/lkml/aKXQAoXZyR6SRPAA@linaro.org/
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-20 16:32 ` Mukesh Ojha
@ 2025-08-20 16:53 ` Stephan Gerhold
2025-08-22 9:21 ` Mukesh Ojha
2025-08-22 8:35 ` Krzysztof Kozlowski
1 sibling, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-20 16:53 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 10:02:50PM +0530, Mukesh Ojha wrote:
> On Wed, Aug 20, 2025 at 08:48:22PM +0530, Mukesh Ojha wrote:
> > On Wed, Aug 20, 2025 at 10:12:15AM +0200, Stephan Gerhold wrote:
> > > On Tue, Aug 19, 2025 at 10:24:41PM +0530, Mukesh Ojha wrote:
> > > > The resource table data structure has traditionally been associated with
> > > > the remoteproc framework, where the resource table is included as a
> > > > section within the remote processor firmware binary. However, it is also
> > > > possible to obtain the resource table through other means—such as from a
> > > > reserved memory region populated by the boot firmware, statically
> > > > maintained driver data, or via a secure SMC call—when it is not embedded
> > > > in the firmware.
> > > >
> > > > There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> > > > etc.) in the upstream kernel that do not use the remoteproc framework to
> > > > manage their lifecycle for various reasons.
> > > >
> > > > When Linux is running at EL2, similar to the Qualcomm PAS driver
> > > > (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> > > > also want to use the resource table SMC call to retrieve and map
> > > > resources before they are used by the remote processor.
> > > >
> > >
> > > All the examples you give here (Venus/Iris, GPU) have some sort of EL2
> > > support already for older platforms:
> >
> > Example was taken from perspective of remote processor life-cycle management.
> > You are right they have worked before in non-secure way for Chrome.
> >
> > >
> > > - For GPU, we just skip loading the ZAP shader and access the protected
> > > registers directly. I would expect the ZAP shader does effectively
> > > the same, perhaps with some additional handling for secure mode. Is
> > > this even a real remote processor that has a separate IOMMU domain?
> > >
> >
> > I don't think it is the case and think the same that they can skip
> > loading and Hence, I have not yet added support for it.
> >
> > Will check internally before doing anything on GPU.
> >
> > > - For Venus/Iris, there is code upstream similar to your PATCH 11/11
> > > that maps the firmware with the IOMMU (but invokes reset directly
> > > using the registers, without using PAS). There is no resource table
> > > used for that either, so at least all Venus/Iris versions so far
> > > apparently had no need for any mappings aside from the firmware
> > > binary.
> >
> > You are absolutely right
> >
> > >
> > > I understand that you want to continue using PAS for these, but I'm a
> > > bit confused what kind of mappings we would expect to have in the
> > > resource table for video and GPU. Could you give an example?
> >
> > We have some debug hw tracing available for video for lemans, which is
> > optional However, I believe infra is good to have incase we need some
> > required resources to be map for Video to work for a SoC.
> >
> > >
> > > Thanks,
> > > Stephan
> >
> > --
> > -Mukesh Ojha
>
> Since I am not subscribed to any of the mailing lists to which this
> series was sent, I am not receiving emails from the list. As a result,
> your recent messages did not reach my inbox. Additionally, it seems your
> reply inadvertently removed me from the To-list.
>
>
> https://lore.kernel.org/lkml/aKXqSU-487b6Je2B@linaro.org/
>
> https://lore.kernel.org/lkml/aKXQAoXZyR6SRPAA@linaro.org/
>
Indeed, but I don't think this is my fault: You have a strange
"Mail-Followup-To:" list in the email header of your reply [1] and my
email client honors it when I press "group reply". Your email client or
server seems to produce this header without including you in the follow
up list, as if you don't want to receive any replies. :-)
I fixed it up manually this time, but perhaps you should look into the
source of this weird header in your replies, I'm probably not the only
person using mutt and just hitting "group reply" all the time ...
Stephan
[1]: https://lore.kernel.org/linux-arm-msm/20250820163250.hszey3i2gtd3o2i6@hu-mojha-hyd.qualcomm.com/raw
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 04/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
2025-08-19 16:54 ` [PATCH v2 04/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image() Mukesh Ojha
@ 2025-08-21 14:36 ` Bryan O'Donoghue
2025-08-21 16:29 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-21 14:36 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> Simplify qcom_scm_pas_init_image() by making the memory
> allocation, copy and free work in a separate function
> then the actual SMC call.
then is temporal
than is disjunctive
you mean than here, not then.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/firmware/qcom/qcom_scm.c | 59 ++++++++++++++++++--------------
> 1 file changed, 34 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 9a5b34f5bacb..7827699e277c 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -584,6 +584,38 @@ void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_
> }
> EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
>
> +static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> + void *metadata, size_t size,
> + struct qcom_scm_res *res)
> +{
> + 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] = peripheral,
> + .owner = ARM_SMCCC_OWNER_SIP,
> + };
A minor detail but please reverse christmas tree your defintions and try
to make int ret come last.
> +
> + 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
> @@ -604,17 +636,10 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
> int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> struct qcom_scm_pas_metadata *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] = peripheral,
> - .owner = ARM_SMCCC_OWNER_SIP,
> - };
> - struct qcom_scm_res res;
>
> /*
> * During the scm call memory protection will be enabled for the meta
> @@ -635,23 +660,7 @@ int qcom_scm_pas_init_image(u32 peripheral, 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(peripheral, mdata_phys, mdata_buf, size, &res);
> if (ret < 0 || !ctx) {
> dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
> } else if (ctx) {
With those changes.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table
2025-08-20 8:36 ` Stephan Gerhold
2025-08-20 11:14 ` Mukesh Ojha
@ 2025-08-21 14:49 ` Krzysztof Kozlowski
2025-08-21 17:41 ` Mukesh Ojha
1 sibling, 1 reply; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-21 14:49 UTC (permalink / raw)
To: Stephan Gerhold, Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 20/08/2025 10:36, Stephan Gerhold wrote:
>> #include <linux/slab.h>
>> #include <linux/soc/qcom/mdt_loader.h>
>>
>> -#define MAX_RSCTABLE_SIZE SZ_16K;
>
> I'm confused why there is a semicolon here suddenly. Did you edit this
> patch by hand?
>
> Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
> Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse resource table
> error: patch failed: drivers/soc/qcom/mdt_loader.c:22
> error: drivers/soc/qcom/mdt_loader.c: patch does not apply
This is very, very odd process. Editing patches POST format-patch or
post b4 (wut?) is a serious warning sign.
Few commit msgs also bring attention to possibility of AI, therefore
please clarify:
Did you use AI tools (qcom internal, external, any LLM/AI related tools)
when writing that code, formatting it or creating this patchset?
This is very important, as it create might create legal risk and
everyone should be aware of it.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
2025-08-19 16:54 ` [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Mukesh Ojha
@ 2025-08-21 15:05 ` Krzysztof Kozlowski
2025-08-21 17:20 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-21 15:05 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On 19/08/2025 18:54, Mukesh Ojha wrote:
> 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
It is possible? Only possible?
> are not embedded in the firmware binary and instead are provided by
> TrustZone However, dynamic resources are always expected to come from
So dynamic are always in TZ?
> TrustZone. This indicates that for Qualcomm devices, all resources
> (static and dynamic) will be provided by TrustZone via the SMC call.
And now all of them are by TZ? Previously it was only possible?
Srsly, what sort of AI hallucinated slop it is?
I think this is pretty close to proof that your submission does not meet
criteria of open source contribution.
Did you run any of this through your legal process in Qualcomm?
I don't trust any part of this code.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function
2025-08-19 16:54 ` [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function Mukesh Ojha
@ 2025-08-21 15:23 ` Bryan O'Donoghue
2025-08-21 17:03 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-21 15:23 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> Qualcomm SoCs running with QHEE (Qualcomm Hypervisor Execution
> Environment—a library present in the Gunyah hypervisor) utilize the
> Peripheral Authentication Service (PAS) from Qualcomm TrustZone (TZ)
> also called QTEE(Qualcomm Trusted Execution Environment firmware)
> to securely authenticate and reset remote processors via a sequence
> of SMC calls such as qcom_scm_pas_init_image(), qcom_scm_pas_mem_setup(),
> and qcom_scm_pas_auth_and_reset().
>
> For memory passed to Qualcomm TrustZone, it must either be part of a
> pool registered with TZ or be directly registered via SHMbridge SMC
> calls.
>
> When QHEE is present, PAS SMC calls from Linux running at EL1 are
> trapped by QHEE (running at EL2), which then creates or retrieves memory
> from the SHM bridge for both metadata and remoteproc carveout memory
> before passing them to TZ. However, when the SoC runs with a
> non-QHEE-based hypervisor, Linux must create the SHM bridge for both
> metadata (before it is passed to TZ in qcom_scm_pas_init_image()) and
> for remoteproc memory (before the call is made to TZ in
> qcom_scm_pas_auth_and_reset()).
>
> For the qcom_scm_pas_init_image() call, metadata content must be copied
> to a buffer allocated from the SHM bridge before making the SMC call.
> This buffer should be freed either immediately after the call or during
> the qcom_scm_pas_metadata_release() function, depending on the context
> parameter passed to qcom_scm_pas_init_image(). Convert the metadata
> context parameter to use PAS context data structure so that it will also
> be possible to decide whether to get memory from SHMbridge pool or not.
>
> When QHEE is present, it manages the IOMMU translation context so, in
> absence of it device driver will be aware through device tree that its
> translation context is managed by Linux and it need to create SHMbridge
> before passing any buffer to TZ, So, remote processor driver should
> appropriately set ctx->has_iommu to let PAS SMC function to take care of
> everything ready for the call to work.
>
> Lets convert qcom_scm_pas_init_image() and qcom_scm_pas_metadata_release()
> to have these awareness.
I like the effort in the commit log here but its also a bit too long.
Please go through these paragraphs and try to reduce down the amount of
text you are generating.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
> drivers/firmware/qcom/qcom_scm.c | 71 +++++++++++++++++++++-----
> drivers/remoteproc/qcom_q6v5_pas.c | 14 ++---
> drivers/soc/qcom/mdt_loader.c | 4 +-
> include/linux/firmware/qcom/qcom_scm.h | 9 ++--
> 4 files changed, 73 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 7827699e277c..301d440f62f3 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -616,6 +616,35 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> return ret;
> }
>
> +static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_ctx *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->peripheral, mdata_phys, mdata_buf, size, &res);
> + if (ret < 0 || !mdt_ctx) {
if ret is an error or mdt_ctx is null free the memory
> + qcom_tzmem_free(mdata_buf);
> + } else if (mdt_ctx) {
if mdt_ctx is valid do this
> + mdt_ctx->ptr = mdata_buf;
> + mdt_ctx->addr.phys_addr = mdata_phys;
> + mdt_ctx->size = size;
> + }
> +
> + return ret ? : res.result[0];
so we can have ctx_mtd valid but return the value at ret but also mtd
valid and return the res.result[0]
That seems like an odd choice - surely if you are enumerating the
data-structure the result code we care about is res.result[0] instead of
ret ?
OK I see this return logic comes from below..
But
drivers/soc/qcom/mdt_loader.c::qcom_mdt_pas_init
ret = qcom_scm_pas_init_image(pas_id, metadata, metadata_len, ctx);
kfree(metadata);
if (ret) {
/* Invalid firmware metadata */
dev_err(dev, "error %d initializing firmware %s\n", ret, fw_name);
goto out;
}
So if ret as returned from your function is > 0 you will leak the memory
allocated @ mdata_buf ..
Do you expect something else to come along and call
qcom_scm_pas_metadata_release() ?
> +}
> +
> /**
> * qcom_scm_pas_init_image() - Initialize peripheral authentication service
> * state machine for a given peripheral, using the
> @@ -625,7 +654,7 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> * 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.
> *
> @@ -634,13 +663,19 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> * qcom_scm_pas_metadata_release() by the caller.
> */
> int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> - struct qcom_scm_pas_metadata *ctx)
> + struct qcom_scm_pas_ctx *ctx)
> {
> + struct qcom_scm_pas_metadata *mdt_ctx;
> struct qcom_scm_res res;
> dma_addr_t mdata_phys;
> void *mdata_buf;
> int ret;
>
> + if (ctx && ctx->has_iommu) {
> + ret = qcom_scm_pas_prep_and_init_image(ctx, metadata, size);
> + return ret;
> + }
> +
> /*
> * During the scm call memory protection will be enabled for the meta
> * data blob, so make sure it's physically contiguous, 4K aligned and
> @@ -663,10 +698,11 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> ret = __qcom_scm_pas_init_image(peripheral, mdata_phys, mdata_buf, size, &res);
> 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->metadata) {
> + mdt_ctx = ctx->metadata;
> + mdt_ctx->ptr = mdata_buf;
> + mdt_ctx->addr.dma_addr = mdata_phys;
> + mdt_ctx->size = size;
> }
>
> return ret ? : res.result[0];
is this return path still valid now that you've functionally decomposed
into qcom_sm_pas_prep_and_init ?
> @@ -675,18 +711,27 @@ 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_ctx *ctx)
> {
> - if (!ctx->ptr)
> + struct qcom_scm_pas_metadata *mdt_ctx;
> +
> + mdt_ctx = ctx->metadata;
> + if (!mdt_ctx->ptr)
> return;
>
> - dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, 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;
> + }
>
> - ctx->ptr = NULL;
> - ctx->phys = 0;
> - ctx->size = 0;
> + mdt_ctx->ptr = NULL;
> + 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 e376c0338576..09cada92dfd5 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> @@ -209,9 +209,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_ctx->metadata);
> + qcom_scm_pas_metadata_release(pas->pas_ctx);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
>
> return 0;
> }
> @@ -244,7 +244,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_ctx->metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> release_firmware(pas->dtb_firmware);
>
> return ret;
> @@ -313,9 +313,9 @@ static int qcom_pas_start(struct rproc *rproc)
> goto release_pas_metadata;
> }
>
> - qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
> + qcom_scm_pas_metadata_release(pas->pas_ctx);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->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;
> @@ -323,9 +323,9 @@ static int qcom_pas_start(struct rproc *rproc)
> return 0;
>
> release_pas_metadata:
> - qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
> + qcom_scm_pas_metadata_release(pas->pas_ctx);
> if (pas->dtb_pas_id)
> - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> disable_px_supply:
> if (pas->px_supply)
> regulator_disable(pas->px_supply);
> diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> index 509ff85d9bf6..a1718db91b3e 100644
> --- a/drivers/soc/qcom/mdt_loader.c
> +++ b/drivers/soc/qcom/mdt_loader.c
> @@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
> */
> 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_metadata *ctx)
> + struct qcom_scm_pas_ctx *ctx)
> {
> const struct elf32_phdr *phdrs;
> const struct elf32_phdr *phdr;
> @@ -491,7 +491,7 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
> int ret;
>
> ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->peripheral,
> - ctx->mem_phys, ctx->metadata);
> + ctx->mem_phys, ctx);
> if (ret)
> return ret;
>
> diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> index a31006fe49a9..bd3417d9c3f9 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;
> };
>
> @@ -85,8 +88,8 @@ struct qcom_scm_pas_ctx {
> void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> size_t mem_size, bool save_mdt_ctx);
> int qcom_scm_pas_init_image(u32 peripheral, 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_ctx *ctx);
> +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_ctx *ctx);
> int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
> int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_ctx *ctx);
> int qcom_scm_pas_auth_and_reset(u32 peripheral);
Please review the error paths here especially WRT to qcom_mdt_pas_init();
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 04/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
2025-08-21 14:36 ` Bryan O'Donoghue
@ 2025-08-21 16:29 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-21 16:29 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Thu, Aug 21, 2025 at 03:36:26PM +0100, Bryan O'Donoghue wrote:
> On 19/08/2025 17:54, Mukesh Ojha wrote:
> > Simplify qcom_scm_pas_init_image() by making the memory
> > allocation, copy and free work in a separate function
> > then the actual SMC call.
>
> then is temporal
> than is disjunctive
>
> you mean than here, not then.
Thanks, its a typo.
>
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/qcom_scm.c | 59 ++++++++++++++++++--------------
> > 1 file changed, 34 insertions(+), 25 deletions(-)
> >
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 9a5b34f5bacb..7827699e277c 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -584,6 +584,38 @@ void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_
> > }
> > EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
> > +static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> > + void *metadata, size_t size,
> > + struct qcom_scm_res *res)
> > +{
> > + 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] = peripheral,
> > + .owner = ARM_SMCCC_OWNER_SIP,
> > + };
>
> A minor detail but please reverse christmas tree your defintions and try to
> make int ret come last.
Sure.
>
> > +
> > + 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
> > @@ -604,17 +636,10 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_ctx_init);
> > int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> > struct qcom_scm_pas_metadata *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] = peripheral,
> > - .owner = ARM_SMCCC_OWNER_SIP,
> > - };
> > - struct qcom_scm_res res;
> > /*
> > * During the scm call memory protection will be enabled for the meta
> > @@ -635,23 +660,7 @@ int qcom_scm_pas_init_image(u32 peripheral, 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(peripheral, mdata_phys, mdata_buf, size, &res);
> > if (ret < 0 || !ctx) {
> > dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
> > } else if (ctx) {
>
> With those changes.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function
2025-08-21 15:23 ` Bryan O'Donoghue
@ 2025-08-21 17:03 ` Mukesh Ojha
2025-08-22 16:52 ` Mukesh Ojha
2025-08-22 23:13 ` Bryan O'Donoghue
0 siblings, 2 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-21 17:03 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Thu, Aug 21, 2025 at 04:23:53PM +0100, Bryan O'Donoghue wrote:
> On 19/08/2025 17:54, Mukesh Ojha wrote:
> > Qualcomm SoCs running with QHEE (Qualcomm Hypervisor Execution
> > Environment—a library present in the Gunyah hypervisor) utilize the
> > Peripheral Authentication Service (PAS) from Qualcomm TrustZone (TZ)
> > also called QTEE(Qualcomm Trusted Execution Environment firmware)
> > to securely authenticate and reset remote processors via a sequence
> > of SMC calls such as qcom_scm_pas_init_image(), qcom_scm_pas_mem_setup(),
> > and qcom_scm_pas_auth_and_reset().
> >
> > For memory passed to Qualcomm TrustZone, it must either be part of a
> > pool registered with TZ or be directly registered via SHMbridge SMC
> > calls.
> >
> > When QHEE is present, PAS SMC calls from Linux running at EL1 are
> > trapped by QHEE (running at EL2), which then creates or retrieves memory
> > from the SHM bridge for both metadata and remoteproc carveout memory
> > before passing them to TZ. However, when the SoC runs with a
> > non-QHEE-based hypervisor, Linux must create the SHM bridge for both
> > metadata (before it is passed to TZ in qcom_scm_pas_init_image()) and
> > for remoteproc memory (before the call is made to TZ in
> > qcom_scm_pas_auth_and_reset()).
> >
> > For the qcom_scm_pas_init_image() call, metadata content must be copied
> > to a buffer allocated from the SHM bridge before making the SMC call.
> > This buffer should be freed either immediately after the call or during
> > the qcom_scm_pas_metadata_release() function, depending on the context
> > parameter passed to qcom_scm_pas_init_image(). Convert the metadata
> > context parameter to use PAS context data structure so that it will also
> > be possible to decide whether to get memory from SHMbridge pool or not.
> >
> > When QHEE is present, it manages the IOMMU translation context so, in
> > absence of it device driver will be aware through device tree that its
> > translation context is managed by Linux and it need to create SHMbridge
> > before passing any buffer to TZ, So, remote processor driver should
> > appropriately set ctx->has_iommu to let PAS SMC function to take care of
> > everything ready for the call to work.
> >
> > Lets convert qcom_scm_pas_init_image() and qcom_scm_pas_metadata_release()
> > to have these awareness.
>
> I like the effort in the commit log here but its also a bit too long.
>
> Please go through these paragraphs and try to reduce down the amount of text
> you are generating.
I was writing to set context for each commit and for the record and hence, the
repetition of text you would see in some of the lines used.
I will take your suggestion and reduce it.
>
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/qcom_scm.c | 71 +++++++++++++++++++++-----
> > drivers/remoteproc/qcom_q6v5_pas.c | 14 ++---
> > drivers/soc/qcom/mdt_loader.c | 4 +-
> > include/linux/firmware/qcom/qcom_scm.h | 9 ++--
> > 4 files changed, 73 insertions(+), 25 deletions(-)
> >
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 7827699e277c..301d440f62f3 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -616,6 +616,35 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> > return ret;
> > }
> > +static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_ctx *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->peripheral, mdata_phys, mdata_buf, size, &res);
> > + if (ret < 0 || !mdt_ctx) {
>
> if ret is an error or mdt_ctx is null free the memory
>
> > + qcom_tzmem_free(mdata_buf);
> > + } else if (mdt_ctx) {
>
> if mdt_ctx is valid do this
Nothing change, it is similar to the earlier code.
>
> > + mdt_ctx->ptr = mdata_buf;
> > + mdt_ctx->addr.phys_addr = mdata_phys;
> > + mdt_ctx->size = size;
> > + }
> > +
> > + return ret ? : res.result[0];
>
> so we can have ctx_mtd valid but return the value at ret but also mtd valid
> and return the res.result[0]
>
> That seems like an odd choice - surely if you are enumerating the
> data-structure the result code we care about is res.result[0] instead of ret
> ?
>
> OK I see this return logic comes from below..
>
> But
>
> drivers/soc/qcom/mdt_loader.c::qcom_mdt_pas_init
>
> ret = qcom_scm_pas_init_image(pas_id, metadata, metadata_len, ctx);
> kfree(metadata);
> if (ret) {
> /* Invalid firmware metadata */
> dev_err(dev, "error %d initializing firmware %s\n", ret, fw_name);
> goto out;
> }
>
> So if ret as returned from your function is > 0 you will leak the memory
> allocated @ mdata_buf ..
>
> Do you expect something else to come along and call
> qcom_scm_pas_metadata_release() ?
You just identified a bug in the existing code where qcom_mdt_pas_init()
does not call qcom_scm_pas_metadata_release() for firmware image for
failure case from qcom_q6v5_pas().
>
> > +}
> > +
> > /**
> > * qcom_scm_pas_init_image() - Initialize peripheral authentication service
> > * state machine for a given peripheral, using the
> > @@ -625,7 +654,7 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> > * 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.
> > *
> > @@ -634,13 +663,19 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> > * qcom_scm_pas_metadata_release() by the caller.
> > */
> > int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> > - struct qcom_scm_pas_metadata *ctx)
> > + struct qcom_scm_pas_ctx *ctx)
> > {
> > + struct qcom_scm_pas_metadata *mdt_ctx;
> > struct qcom_scm_res res;
> > dma_addr_t mdata_phys;
> > void *mdata_buf;
> > int ret;
> > + if (ctx && ctx->has_iommu) {
> > + ret = qcom_scm_pas_prep_and_init_image(ctx, metadata, size);
> > + return ret;
> > + }
> > +
> > /*
> > * During the scm call memory protection will be enabled for the meta
> > * data blob, so make sure it's physically contiguous, 4K aligned and
> > @@ -663,10 +698,11 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> > ret = __qcom_scm_pas_init_image(peripheral, mdata_phys, mdata_buf, size, &res);
> > 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->metadata) {
> > + mdt_ctx = ctx->metadata;
> > + mdt_ctx->ptr = mdata_buf;
> > + mdt_ctx->addr.dma_addr = mdata_phys;
> > + mdt_ctx->size = size;
> > }
> > return ret ? : res.result[0];
>
> is this return path still valid now that you've functionally decomposed into
> qcom_sm_pas_prep_and_init ?
>
> > @@ -675,18 +711,27 @@ 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_ctx *ctx)
> > {
> > - if (!ctx->ptr)
> > + struct qcom_scm_pas_metadata *mdt_ctx;
> > +
> > + mdt_ctx = ctx->metadata;
> > + if (!mdt_ctx->ptr)
> > return;
> > - dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, 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;
> > + }
> > - ctx->ptr = NULL;
> > - ctx->phys = 0;
> > - ctx->size = 0;
> > + mdt_ctx->ptr = NULL;
> > + 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 e376c0338576..09cada92dfd5 100644
> > --- a/drivers/remoteproc/qcom_q6v5_pas.c
> > +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> > @@ -209,9 +209,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_ctx->metadata);
> > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > return 0;
> > }
> > @@ -244,7 +244,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_ctx->metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > release_firmware(pas->dtb_firmware);
> > return ret;
> > @@ -313,9 +313,9 @@ static int qcom_pas_start(struct rproc *rproc)
> > goto release_pas_metadata;
> > }
> > - qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
> > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->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;
> > @@ -323,9 +323,9 @@ static int qcom_pas_start(struct rproc *rproc)
> > return 0;
> > release_pas_metadata:
> > - qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
> > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > if (pas->dtb_pas_id)
> > - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > disable_px_supply:
> > if (pas->px_supply)
> > regulator_disable(pas->px_supply);
> > diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> > index 509ff85d9bf6..a1718db91b3e 100644
> > --- a/drivers/soc/qcom/mdt_loader.c
> > +++ b/drivers/soc/qcom/mdt_loader.c
> > @@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
> > */
> > 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_metadata *ctx)
> > + struct qcom_scm_pas_ctx *ctx)
> > {
> > const struct elf32_phdr *phdrs;
> > const struct elf32_phdr *phdr;
> > @@ -491,7 +491,7 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
> > int ret;
> > ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->peripheral,
> > - ctx->mem_phys, ctx->metadata);
> > + ctx->mem_phys, ctx);
> > if (ret)
> > return ret;
> > diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> > index a31006fe49a9..bd3417d9c3f9 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;
> > };
> > @@ -85,8 +88,8 @@ struct qcom_scm_pas_ctx {
> > void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> > size_t mem_size, bool save_mdt_ctx);
> > int qcom_scm_pas_init_image(u32 peripheral, 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_ctx *ctx);
> > +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_ctx *ctx);
> > int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
> > int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_ctx *ctx);
> > int qcom_scm_pas_auth_and_reset(u32 peripheral);
>
> Please review the error paths here especially WRT to qcom_mdt_pas_init();
Sure, will send the fix patch for the existing bug.
>
> ---
> bod
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
2025-08-21 15:05 ` Krzysztof Kozlowski
@ 2025-08-21 17:20 ` Mukesh Ojha
2025-08-22 6:22 ` Krzysztof Kozlowski
0 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-21 17:20 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Thu, Aug 21, 2025 at 05:05:59PM +0200, Krzysztof Kozlowski wrote:
> On 19/08/2025 18:54, Mukesh Ojha wrote:
> > 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
>
> It is possible? Only possible?
its possible
>
> > are not embedded in the firmware binary and instead are provided by
> > TrustZone However, dynamic resources are always expected to come from
>
> So dynamic are always in TZ?
Yes.
>
> > TrustZone. This indicates that for Qualcomm devices, all resources
> > (static and dynamic) will be provided by TrustZone via the SMC call.
>
> And now all of them are by TZ? Previously it was only possible?
Will correct the wording if it has cause confusion, I meant, currently,
some of the chrome product supported in upstream has resource table in
subsystem firmware while most of them Qualcomm SoC supported in upstream
does not pack resources in subsystem firmware and rely on Gunyah to take
care of its static + dynamic resources when it is present. On its
absence, TZ will provide.
Will add above thing if it is not clear.
>
> Srsly, what sort of AI hallucinated slop it is?
>
> I think this is pretty close to proof that your submission does not meet
> criteria of open source contribution.
>
> Did you run any of this through your legal process in Qualcomm?
>
> I don't trust any part of this code.
I don't know what made you think that way. There could be confusion with
my writing and may not have expressed the thing i wanted.
>
> Best regards,
> Krzysztof
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table
2025-08-21 14:49 ` Krzysztof Kozlowski
@ 2025-08-21 17:41 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-21 17:41 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Stephan Gerhold, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On Thu, Aug 21, 2025 at 04:49:39PM +0200, Krzysztof Kozlowski wrote:
> On 20/08/2025 10:36, Stephan Gerhold wrote:
> >> #include <linux/slab.h>
> >> #include <linux/soc/qcom/mdt_loader.h>
> >>
> >> -#define MAX_RSCTABLE_SIZE SZ_16K;
> >
> > I'm confused why there is a semicolon here suddenly. Did you edit this
> > patch by hand?
> >
> > Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
> > Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse resource table
> > error: patch failed: drivers/soc/qcom/mdt_loader.c:22
> > error: drivers/soc/qcom/mdt_loader.c: patch does not apply
>
>
> This is very, very odd process. Editing patches POST format-patch or
> post b4 (wut?) is a serious warning sign.
>
> Few commit msgs also bring attention to possibility of AI, therefore
> please clarify:
>
> Did you use AI tools (qcom internal, external, any LLM/AI related tools)
> when writing that code, formatting it or creating this patchset?
>
> This is very important, as it create might create legal risk and
> everyone should be aware of it.
Again, I already accepted my mistakes of editing(removing ;) 8/11 patch
once I checked minor checkpatch warning on it and will not do it again.
And again, I don't use any of such tools, and hopeful it clarifies.
>
> Best regards,
> Krzysztof
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-20 13:39 ` Stephan Gerhold
@ 2025-08-22 4:26 ` Vikash Garodia
2025-08-22 8:46 ` Stephan Gerhold
0 siblings, 1 reply; 74+ messages in thread
From: Vikash Garodia @ 2025-08-22 4:26 UTC (permalink / raw)
To: Stephan Gerhold, Bjorn Andersson, Konrad Dybcio, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 8/20/2025 7:09 PM, Stephan Gerhold wrote:
>>>> +int iris_fw_init(struct iris_core *core)
>>>> +{
>>>> + struct platform_device_info info;
>>>> + struct iommu_domain *iommu_dom;
>>>> + struct platform_device *pdev;
>>>> + struct device_node *np;
>>>> + int ret;
>>>> +
>>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
>>>> + if (!np)
>>>> + return 0;
>>> You need a dt-bindings change for this as well. This is documented only
>>> for Venus.
>> You are right, wanted to send device tree and binding support separately.
>> But if required, will add with the series in the next version.
>>
> You can send device tree changes separately, but dt-binding changes
> always need to come before the driver changes.
Do you mean to update the examples section[1] with the firmware subnode,
something similar to venus schema[2] ?
Regards,
Vikash
[1]
https://elixir.bootlin.com/linux/v6.17-rc2/source/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml#L109
[2]
https://elixir.bootlin.com/linux/v6.17-rc2/source/Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml#L128
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
2025-08-21 17:20 ` Mukesh Ojha
@ 2025-08-22 6:22 ` Krzysztof Kozlowski
2025-08-22 7:21 ` Mukesh Ojha
2025-08-22 8:30 ` Krzysztof Kozlowski
0 siblings, 2 replies; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-22 6:22 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 21/08/2025 19:20, Mukesh Ojha wrote:
>>
>> Srsly, what sort of AI hallucinated slop it is?
>>
>> I think this is pretty close to proof that your submission does not meet
>> criteria of open source contribution.
>>
>> Did you run any of this through your legal process in Qualcomm?
>>
>> I don't trust any part of this code.
>
> I don't know what made you think that way. There could be confusion with
> my writing and may not have expressed the thing i wanted.
Commits were written by two different people, but signed only by you.
They have 100% different style and the other looks like taken out of
ChatGPT.
Editing patches post factum is another reason.
Reasoning here is typical for LLM - first claim something ("static is
possible"), then claim another ("dynamic are always") and then connect
these two to create false third statement (static and dynamic are always).
You got three strong indications. So this is what made me think that way.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
2025-08-22 6:22 ` Krzysztof Kozlowski
@ 2025-08-22 7:21 ` Mukesh Ojha
2025-08-22 8:30 ` Krzysztof Kozlowski
1 sibling, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 7:21 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Fri, Aug 22, 2025 at 08:22:10AM +0200, Krzysztof Kozlowski wrote:
> On 21/08/2025 19:20, Mukesh Ojha wrote:
> >>
> >> Srsly, what sort of AI hallucinated slop it is?
> >>
> >> I think this is pretty close to proof that your submission does not meet
> >> criteria of open source contribution.
> >>
> >> Did you run any of this through your legal process in Qualcomm?
> >>
> >> I don't trust any part of this code.
> >
> > I don't know what made you think that way. There could be confusion with
> > my writing and may not have expressed the thing i wanted.
> Commits were written by two different people, but signed only by you.
> They have 100% different style and the other looks like taken out of
> ChatGPT.
I am not expert here how things written and understand by them and
ChatGPT are not used by my organisation.
>
> Editing patches post factum is another reason.
>
> Reasoning here is typical for LLM - first claim something ("static is
> possible"), then claim another ("dynamic are always") and then connect
> these two to create false third statement (static and dynamic are always).
Again, I am not an english expert as it is not my first language but I am
explaining again about my thought process, writing for some of devices
where this is the case hence it is written in separate paragraph and the
reason behind, "static is possible" written with chrome in mind which
is true, and "dynamic is always" going to come from EL2(gunyah) and from
TZ on Gunyah absence and this is also true as they are decided on runtime
and not all devices have this dynamic resource requirement.
And writing behind this "This indicates that for Qualcomm devices, all
resources (static and dynamic) will be provided by TrustZone via the SMC
call." is in context of this commit where we are going to get this resources
via SMC call with this series in mind which may be slightly confusing to
someone to understand and I will clarify this in next version.
I believe the mistake I did in this patch is that I did not include
Gunyah/QHEE absence which I have done in other parts of series but this
SMC call in future would be used even in case of Gunyah hence, it was
not used.
I know that I will have to declare these things if I use such tool and if it
falls within my company legal framework.
>
> You got three strong indications. So this is what made me think that way.
>
> Best regards,
> Krzysztof
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-20 15:31 ` Stephan Gerhold
@ 2025-08-22 7:56 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 7:56 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 05:31:21PM +0200, Stephan Gerhold wrote:
> On Wed, Aug 20, 2025 at 08:48:22PM +0530, Mukesh Ojha wrote:
> > On Wed, Aug 20, 2025 at 10:12:15AM +0200, Stephan Gerhold wrote:
> > > On Tue, Aug 19, 2025 at 10:24:41PM +0530, Mukesh Ojha wrote:
> > > > The resource table data structure has traditionally been associated with
> > > > the remoteproc framework, where the resource table is included as a
> > > > section within the remote processor firmware binary. However, it is also
> > > > possible to obtain the resource table through other means—such as from a
> > > > reserved memory region populated by the boot firmware, statically
> > > > maintained driver data, or via a secure SMC call—when it is not embedded
> > > > in the firmware.
> > > >
> > > > There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> > > > etc.) in the upstream kernel that do not use the remoteproc framework to
> > > > manage their lifecycle for various reasons.
> > > >
> > > > When Linux is running at EL2, similar to the Qualcomm PAS driver
> > > > (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> > > > also want to use the resource table SMC call to retrieve and map
> > > > resources before they are used by the remote processor.
> > > >
> > >
> > > All the examples you give here (Venus/Iris, GPU) have some sort of EL2
> > > support already for older platforms:
> >
> > Example was taken from perspective of remote processor life-cycle management.
> > You are right they have worked before in non-secure way for Chrome.
> >
> > >
> > > - For GPU, we just skip loading the ZAP shader and access the protected
> > > registers directly. I would expect the ZAP shader does effectively
> > > the same, perhaps with some additional handling for secure mode. Is
> > > this even a real remote processor that has a separate IOMMU domain?
> > >
> >
> > I don't think it is the case and think the same that they can skip
> > loading and Hence, I have not yet added support for it.
> >
> > Will check internally before doing anything on GPU.
> >
> > > - For Venus/Iris, there is code upstream similar to your PATCH 11/11
> > > that maps the firmware with the IOMMU (but invokes reset directly
> > > using the registers, without using PAS). There is no resource table
> > > used for that either, so at least all Venus/Iris versions so far
> > > apparently had no need for any mappings aside from the firmware
> > > binary.
> >
> > You are absolutely right
> >
> > >
> > > I understand that you want to continue using PAS for these, but I'm a
> > > bit confused what kind of mappings we would expect to have in the
> > > resource table for video and GPU. Could you give an example?
> >
> > We have some debug hw tracing available for video for lemans, which is
> > optional However, I believe infra is good to have incase we need some
> > required resources to be map for Video to work for a SoC.
> >
>
> Thanks for the clarification.
>
> Personally, I'm a bit concerned about the code duplication in PATCH
> 08/11, I think parsing the resource table should ideally be code shared
> between the remoteproc subsystem and whereever else you need it. The way
> you parse it and handle the IOMMU mappings is largely the same, you just
> don't support all of the resource table functionality. Have you checked
> if sharing the code would be feasible?
>
> If there is no upstream requirement for this right now, you might want
> to consider handling this in a follow up series, after you get the
> required functionality in. This would reduce the amount of changes in
> your series quite a bit.
Yes, there is duplication in the parsing and I initially given a thought
to do it but dropped temporarily if we are open for such changes in rproc
framework and I even have a doubt about 6/11 if it is fine or not just
because there is user who does not care about remoteproc framework but
worried about resources.
I agree, it will be good if we do separation of resource table related code
from remoteproc framework so that the code can be shared but doubtful
whether it should be done as part of series or and can be followed
separately.
>
> Thanks,
> Stephan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table
2025-08-22 6:22 ` Krzysztof Kozlowski
2025-08-22 7:21 ` Mukesh Ojha
@ 2025-08-22 8:30 ` Krzysztof Kozlowski
1 sibling, 0 replies; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-22 8:30 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 22/08/2025 08:22, Krzysztof Kozlowski wrote:
> On 21/08/2025 19:20, Mukesh Ojha wrote:
>>>
>>> Srsly, what sort of AI hallucinated slop it is?
>>>
>>> I think this is pretty close to proof that your submission does not meet
>>> criteria of open source contribution.
>>>
>>> Did you run any of this through your legal process in Qualcomm?
>>>
>>> I don't trust any part of this code.
>>
>> I don't know what made you think that way. There could be confusion with
>> my writing and may not have expressed the thing i wanted.
> Commits were written by two different people, but signed only by you.
> They have 100% different style and the other looks like taken out of
> ChatGPT.
>
> Editing patches post factum is another reason.
>
> Reasoning here is typical for LLM - first claim something ("static is
> possible"), then claim another ("dynamic are always") and then connect
> these two to create false third statement (static and dynamic are always).
>
> You got three strong indications. So this is what made me think that way.
Huh, so this email was not sent to you, because of weird headers you
have in your email client ("Mail-Followup-To:"). You were notified about
this by Stephan and yet you ignored the problem.
Well, your call, your problem to find emails if you decide not to
receive replies. :/
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-20 16:32 ` Mukesh Ojha
2025-08-20 16:53 ` Stephan Gerhold
@ 2025-08-22 8:35 ` Krzysztof Kozlowski
2025-08-22 9:30 ` Mukesh Ojha
1 sibling, 1 reply; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-22 8:35 UTC (permalink / raw)
To: Stephan Gerhold, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On 20/08/2025 18:32, Mukesh Ojha wrote:
>>
>> --
>> -Mukesh Ojha
>
> Since I am not subscribed to any of the mailing lists to which this
> series was sent, I am not receiving emails from the list. As a result,
> your recent messages did not reach my inbox. Additionally, it seems your
> reply inadvertently removed me from the To-list.
You decided to remove your address from replies via "Mail-Followup-To:"
header you introduced. It's on your email client.
Just like you will not receive this email (surprise!)...
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-19 16:54 ` [PATCH v2 11/11] media: iris: " Mukesh Ojha
2025-08-20 8:46 ` Stephan Gerhold
2025-08-20 11:33 ` Bryan O'Donoghue
@ 2025-08-22 8:45 ` Krzysztof Kozlowski
2025-08-22 15:13 ` Mukesh Ojha
2 siblings, 1 reply; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-22 8:45 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On 19/08/2025 18:54, Mukesh Ojha wrote:
> +int iris_fw_init(struct iris_core *core)
> +{
> + struct platform_device_info info;
> + struct iommu_domain *iommu_dom;
> + struct platform_device *pdev;
> + struct device_node *np;
> + int ret;
> +
> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
Undocumented ABI.
If you tested your DTS, you would notice warnings.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-22 4:26 ` Vikash Garodia
@ 2025-08-22 8:46 ` Stephan Gerhold
2025-08-22 15:06 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-22 8:46 UTC (permalink / raw)
To: Vikash Garodia
Cc: Bjorn Andersson, Konrad Dybcio, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Fri, Aug 22, 2025 at 09:56:49AM +0530, Vikash Garodia wrote:
> On 8/20/2025 7:09 PM, Stephan Gerhold wrote:
> >>>> +int iris_fw_init(struct iris_core *core)
> >>>> +{
> >>>> + struct platform_device_info info;
> >>>> + struct iommu_domain *iommu_dom;
> >>>> + struct platform_device *pdev;
> >>>> + struct device_node *np;
> >>>> + int ret;
> >>>> +
> >>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> >>>> + if (!np)
> >>>> + return 0;
> >>> You need a dt-bindings change for this as well. This is documented only
> >>> for Venus.
> >> You are right, wanted to send device tree and binding support separately.
> >> But if required, will add with the series in the next version.
> >>
> > You can send device tree changes separately, but dt-binding changes
> > always need to come before the driver changes.
>
> Do you mean to update the examples section[1] with the firmware subnode,
> something similar to venus schema[2] ?
>
Sorry, I missed the fact that the "video-firmware" subnode is already
documented for iris as well through qcom,venus-common.yaml (which is
included for qcom,sm8550-iris). I don't think it's strictly required to
add every possibility to the examples of the schema, since we'll also
have the actual DTBs later to test this part of the schema.
I would recommend to extend the description of the "video-firmware" node
in qcom,venus-common.yaml a bit. You do use the reset functionality of
TrustZone, so the description there doesn't fit for your use case.
I think we will also have to figure out how to handle the old
"ChromeOS"/"non_tz" use case (that resets Iris directly with the
registers) vs the EL2 PAS use case (that resets Iris in TZ but still
handles IOMMU from Linux). Simply checking for the presence of the
"video-firmware" node is not enough, because that doesn't tell us if the
PAS support is present in TZ.
I have been experimenting with a similar patch that copies the "non_tz"
code paths from Venus into Iris. We need this to upstream the Iris DT
patch for X1E without regressing the community-contributed x1-el2.dtso,
which doesn't have functional PAS when running in EL2.
Perhaps we could check for __qcom_scm_is_call_available() with the new
QCOM_SCM_PIL_PAS_GET_RSCTABLE to choose between invoking reset via PAS
or directly with the registers. I don't have a device with the new
firmware to verify if that works.
I'll try to send out my patch soon, so you can better see the context.
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-20 16:53 ` Stephan Gerhold
@ 2025-08-22 9:21 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 9:21 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Aug 20, 2025 at 06:53:36PM +0200, Stephan Gerhold wrote:
> On Wed, Aug 20, 2025 at 10:02:50PM +0530, Mukesh Ojha wrote:
> > On Wed, Aug 20, 2025 at 08:48:22PM +0530, Mukesh Ojha wrote:
> > > On Wed, Aug 20, 2025 at 10:12:15AM +0200, Stephan Gerhold wrote:
> > > > On Tue, Aug 19, 2025 at 10:24:41PM +0530, Mukesh Ojha wrote:
> > > > > The resource table data structure has traditionally been associated with
> > > > > the remoteproc framework, where the resource table is included as a
> > > > > section within the remote processor firmware binary. However, it is also
> > > > > possible to obtain the resource table through other means—such as from a
> > > > > reserved memory region populated by the boot firmware, statically
> > > > > maintained driver data, or via a secure SMC call—when it is not embedded
> > > > > in the firmware.
> > > > >
> > > > > There are multiple Qualcomm remote processors (e.g., Venus, Iris, GPU,
> > > > > etc.) in the upstream kernel that do not use the remoteproc framework to
> > > > > manage their lifecycle for various reasons.
> > > > >
> > > > > When Linux is running at EL2, similar to the Qualcomm PAS driver
> > > > > (qcom_q6v5_pas.c), client drivers for subsystems like video and GPU may
> > > > > also want to use the resource table SMC call to retrieve and map
> > > > > resources before they are used by the remote processor.
> > > > >
> > > >
> > > > All the examples you give here (Venus/Iris, GPU) have some sort of EL2
> > > > support already for older platforms:
> > >
> > > Example was taken from perspective of remote processor life-cycle management.
> > > You are right they have worked before in non-secure way for Chrome.
> > >
> > > >
> > > > - For GPU, we just skip loading the ZAP shader and access the protected
> > > > registers directly. I would expect the ZAP shader does effectively
> > > > the same, perhaps with some additional handling for secure mode. Is
> > > > this even a real remote processor that has a separate IOMMU domain?
> > > >
> > >
> > > I don't think it is the case and think the same that they can skip
> > > loading and Hence, I have not yet added support for it.
> > >
> > > Will check internally before doing anything on GPU.
> > >
> > > > - For Venus/Iris, there is code upstream similar to your PATCH 11/11
> > > > that maps the firmware with the IOMMU (but invokes reset directly
> > > > using the registers, without using PAS). There is no resource table
> > > > used for that either, so at least all Venus/Iris versions so far
> > > > apparently had no need for any mappings aside from the firmware
> > > > binary.
> > >
> > > You are absolutely right
> > >
> > > >
> > > > I understand that you want to continue using PAS for these, but I'm a
> > > > bit confused what kind of mappings we would expect to have in the
> > > > resource table for video and GPU. Could you give an example?
> > >
> > > We have some debug hw tracing available for video for lemans, which is
> > > optional However, I believe infra is good to have incase we need some
> > > required resources to be map for Video to work for a SoC.
> > >
> > > >
> > > > Thanks,
> > > > Stephan
> > >
> > > --
> > > -Mukesh Ojha
> >
> > Since I am not subscribed to any of the mailing lists to which this
> > series was sent, I am not receiving emails from the list. As a result,
> > your recent messages did not reach my inbox. Additionally, it seems your
> > reply inadvertently removed me from the To-list.
> >
> >
> > https://lore.kernel.org/lkml/aKXqSU-487b6Je2B@linaro.org/
> >
> > https://lore.kernel.org/lkml/aKXQAoXZyR6SRPAA@linaro.org/
> >
>
> Indeed, but I don't think this is my fault: You have a strange
> "Mail-Followup-To:" list in the email header of your reply [1] and my
> email client honors it when I press "group reply". Your email client or
> server seems to produce this header without including you in the follow
> up list, as if you don't want to receive any replies. :-)
>
> I fixed it up manually this time, but perhaps you should look into the
> source of this weird header in your replies, I'm probably not the only
> person using mutt and just hitting "group reply" all the time ...
Thanks for pointing out.
I am trying to fix this, let me see with this reply.
>
> Stephan
>
> [1]: https://lore.kernel.org/linux-arm-msm/20250820163250.hszey3i2gtd3o2i6@hu-mojha-hyd.qualcomm.com/raw
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header
2025-08-22 8:35 ` Krzysztof Kozlowski
@ 2025-08-22 9:30 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 9:30 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Stephan Gerhold, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, Bryan O'Donoghue, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On Fri, Aug 22, 2025 at 10:35:42AM +0200, Krzysztof Kozlowski wrote:
> On 20/08/2025 18:32, Mukesh Ojha wrote:
> >>
> >> --
> >> -Mukesh Ojha
> >
> > Since I am not subscribed to any of the mailing lists to which this
> > series was sent, I am not receiving emails from the list. As a result,
> > your recent messages did not reach my inbox. Additionally, it seems your
> > reply inadvertently removed me from the To-list.
>
>
> You decided to remove your address from replies via "Mail-Followup-To:"
> header you introduced. It's on your email client.
>
> Just like you will not receive this email (surprise!)...
This was not intentional and just a switch from mutt to neomutt where I
have added stuff unknowingly to filter things and showing inline replies
correctly that may have resulted into this.
>
>
> Best regards,
> Krzysztof
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-22 8:46 ` Stephan Gerhold
@ 2025-08-22 15:06 ` Mukesh Ojha
2025-08-22 16:26 ` Stephan Gerhold
0 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 15:06 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Vikash Garodia, Bjorn Andersson, Konrad Dybcio, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Fri, Aug 22, 2025 at 10:46:20AM +0200, Stephan Gerhold wrote:
> On Fri, Aug 22, 2025 at 09:56:49AM +0530, Vikash Garodia wrote:
> > On 8/20/2025 7:09 PM, Stephan Gerhold wrote:
> > >>>> +int iris_fw_init(struct iris_core *core)
> > >>>> +{
> > >>>> + struct platform_device_info info;
> > >>>> + struct iommu_domain *iommu_dom;
> > >>>> + struct platform_device *pdev;
> > >>>> + struct device_node *np;
> > >>>> + int ret;
> > >>>> +
> > >>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > >>>> + if (!np)
> > >>>> + return 0;
> > >>> You need a dt-bindings change for this as well. This is documented only
> > >>> for Venus.
> > >> You are right, wanted to send device tree and binding support separately.
> > >> But if required, will add with the series in the next version.
> > >>
> > > You can send device tree changes separately, but dt-binding changes
> > > always need to come before the driver changes.
> >
> > Do you mean to update the examples section[1] with the firmware subnode,
> > something similar to venus schema[2] ?
> >
>
> Sorry, I missed the fact that the "video-firmware" subnode is already
> documented for iris as well through qcom,venus-common.yaml (which is
> included for qcom,sm8550-iris). I don't think it's strictly required to
> add every possibility to the examples of the schema, since we'll also
> have the actual DTBs later to test this part of the schema.
>
> I would recommend to extend the description of the "video-firmware" node
> in qcom,venus-common.yaml a bit. You do use the reset functionality of
> TrustZone, so the description there doesn't fit for your use case.
>
> I think we will also have to figure out how to handle the old
> "ChromeOS"/"non_tz" use case (that resets Iris directly with the
> registers) vs the EL2 PAS use case (that resets Iris in TZ but still
> handles IOMMU from Linux). Simply checking for the presence of the
> "video-firmware" node is not enough, because that doesn't tell us if the
> PAS support is present in TZ.
>
> I have been experimenting with a similar patch that copies the "non_tz"
> code paths from Venus into Iris. We need this to upstream the Iris DT
> patch for X1E without regressing the community-contributed x1-el2.dtso,
> which doesn't have functional PAS when running in EL2.
>
> Perhaps we could check for __qcom_scm_is_call_available() with the new
> QCOM_SCM_PIL_PAS_GET_RSCTABLE to choose between invoking reset via PAS
> or directly with the registers. I don't have a device with the new
> firmware to verify if that works.
You can check QCOM_SCM_PIL_PAS_GET_RSCTABLE with __qcom_scm_is_call_available()
but there is a possibility that QCOM_SCM_PIL_PAS_GET_RSCTABLE SMC call will be
used even for Gunyah. So, I believe, __qcom_scm_is_call_available() and
video-firmware's iommu property is also important.
>
> I'll try to send out my patch soon, so you can better see the context.
Are you saying that you are going to send patch to support IRIS on
x1-el2.dtso in non-secure way i.e., non-PAS way.
>
> Thanks,
> Stephan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-22 8:45 ` Krzysztof Kozlowski
@ 2025-08-22 15:13 ` Mukesh Ojha
2025-08-23 15:41 ` Krzysztof Kozlowski
0 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 15:13 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Fri, Aug 22, 2025 at 10:45:50AM +0200, Krzysztof Kozlowski wrote:
> On 19/08/2025 18:54, Mukesh Ojha wrote:
> > +int iris_fw_init(struct iris_core *core)
> > +{
> > + struct platform_device_info info;
> > + struct iommu_domain *iommu_dom;
> > + struct platform_device *pdev;
> > + struct device_node *np;
> > + int ret;
> > +
> > + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
>
> Undocumented ABI.
>
> If you tested your DTS, you would notice warnings.
qcom,venus-common.yaml is documenting video-firmware and getting included in
Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
>
> Best regards,
> Krzysztof
>
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-22 15:06 ` Mukesh Ojha
@ 2025-08-22 16:26 ` Stephan Gerhold
2025-08-22 16:40 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-22 16:26 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Vikash Garodia, Bjorn Andersson, Konrad Dybcio, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Fri, Aug 22, 2025 at 08:36:11PM +0530, Mukesh Ojha wrote:
> On Fri, Aug 22, 2025 at 10:46:20AM +0200, Stephan Gerhold wrote:
> > On Fri, Aug 22, 2025 at 09:56:49AM +0530, Vikash Garodia wrote:
> > > On 8/20/2025 7:09 PM, Stephan Gerhold wrote:
> > > >>>> +int iris_fw_init(struct iris_core *core)
> > > >>>> +{
> > > >>>> + struct platform_device_info info;
> > > >>>> + struct iommu_domain *iommu_dom;
> > > >>>> + struct platform_device *pdev;
> > > >>>> + struct device_node *np;
> > > >>>> + int ret;
> > > >>>> +
> > > >>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > > >>>> + if (!np)
> > > >>>> + return 0;
> > > >>> You need a dt-bindings change for this as well. This is documented only
> > > >>> for Venus.
> > > >> You are right, wanted to send device tree and binding support separately.
> > > >> But if required, will add with the series in the next version.
> > > >>
> > > > You can send device tree changes separately, but dt-binding changes
> > > > always need to come before the driver changes.
> > >
> > > Do you mean to update the examples section[1] with the firmware subnode,
> > > something similar to venus schema[2] ?
> > >
> >
> > Sorry, I missed the fact that the "video-firmware" subnode is already
> > documented for iris as well through qcom,venus-common.yaml (which is
> > included for qcom,sm8550-iris). I don't think it's strictly required to
> > add every possibility to the examples of the schema, since we'll also
> > have the actual DTBs later to test this part of the schema.
> >
> > I would recommend to extend the description of the "video-firmware" node
> > in qcom,venus-common.yaml a bit. You do use the reset functionality of
> > TrustZone, so the description there doesn't fit for your use case.
> >
> > I think we will also have to figure out how to handle the old
> > "ChromeOS"/"non_tz" use case (that resets Iris directly with the
> > registers) vs the EL2 PAS use case (that resets Iris in TZ but still
> > handles IOMMU from Linux). Simply checking for the presence of the
> > "video-firmware" node is not enough, because that doesn't tell us if the
> > PAS support is present in TZ.
> >
> > I have been experimenting with a similar patch that copies the "non_tz"
> > code paths from Venus into Iris. We need this to upstream the Iris DT
> > patch for X1E without regressing the community-contributed x1-el2.dtso,
> > which doesn't have functional PAS when running in EL2.
> >
> > Perhaps we could check for __qcom_scm_is_call_available() with the new
> > QCOM_SCM_PIL_PAS_GET_RSCTABLE to choose between invoking reset via PAS
> > or directly with the registers. I don't have a device with the new
> > firmware to verify if that works.
>
> You can check QCOM_SCM_PIL_PAS_GET_RSCTABLE with __qcom_scm_is_call_available()
> but there is a possibility that QCOM_SCM_PIL_PAS_GET_RSCTABLE SMC call will be
> used even for Gunyah. So, I believe, __qcom_scm_is_call_available() and
> video-firmware's iommu property is also important.
>
Yeah, this sounds good.
> >
> > I'll try to send out my patch soon, so you can better see the context.
>
> Are you saying that you are going to send patch to support IRIS on
> x1-el2.dtso in non-secure way i.e., non-PAS way.
>
The background is the following: I have a pending patch to add iris to
x1e80100.dtsi, but that currently breaks x1-el2.dtso. My original plan
was to disable &iris in x1-el2.dtso (because the PAS way seems to be
just broken), but then I saw that e.g. sc7180-el2.dtso does have working
Venus with the "video-firmware" node. Copy-pasting the "no_tz"(/non-PAS)
code as-is from venus into iris works just fine for x1-el2.dtso, so
disabling &iris in x1-el2.dtso just because the "no_tz" code is
currently missing in iris doesn't sound right.
As far as I understand the approach you use in this series does not work
without the TZ changes for older platforms like X1E(?), so adding that
code in iris seems to be the best way to move forward.
I started working on a patch for this a while ago, it just needs a bit
more cleanup. I'll try to finish it up and post it so we can discuss it
further. I think the IOMMU management in my patch would even work as-is
for you, you would just need to toggle a boolean to use the PAS instead
of accessing the registers directly.
Thanks,
Stephan
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-22 16:26 ` Stephan Gerhold
@ 2025-08-22 16:40 ` Mukesh Ojha
2025-08-23 20:43 ` Stephan Gerhold
0 siblings, 1 reply; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 16:40 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Vikash Garodia, Bjorn Andersson, Konrad Dybcio, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Fri, Aug 22, 2025 at 06:26:19PM +0200, Stephan Gerhold wrote:
> On Fri, Aug 22, 2025 at 08:36:11PM +0530, Mukesh Ojha wrote:
> > On Fri, Aug 22, 2025 at 10:46:20AM +0200, Stephan Gerhold wrote:
> > > On Fri, Aug 22, 2025 at 09:56:49AM +0530, Vikash Garodia wrote:
> > > > On 8/20/2025 7:09 PM, Stephan Gerhold wrote:
> > > > >>>> +int iris_fw_init(struct iris_core *core)
> > > > >>>> +{
> > > > >>>> + struct platform_device_info info;
> > > > >>>> + struct iommu_domain *iommu_dom;
> > > > >>>> + struct platform_device *pdev;
> > > > >>>> + struct device_node *np;
> > > > >>>> + int ret;
> > > > >>>> +
> > > > >>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > > > >>>> + if (!np)
> > > > >>>> + return 0;
> > > > >>> You need a dt-bindings change for this as well. This is documented only
> > > > >>> for Venus.
> > > > >> You are right, wanted to send device tree and binding support separately.
> > > > >> But if required, will add with the series in the next version.
> > > > >>
> > > > > You can send device tree changes separately, but dt-binding changes
> > > > > always need to come before the driver changes.
> > > >
> > > > Do you mean to update the examples section[1] with the firmware subnode,
> > > > something similar to venus schema[2] ?
> > > >
> > >
> > > Sorry, I missed the fact that the "video-firmware" subnode is already
> > > documented for iris as well through qcom,venus-common.yaml (which is
> > > included for qcom,sm8550-iris). I don't think it's strictly required to
> > > add every possibility to the examples of the schema, since we'll also
> > > have the actual DTBs later to test this part of the schema.
> > >
> > > I would recommend to extend the description of the "video-firmware" node
> > > in qcom,venus-common.yaml a bit. You do use the reset functionality of
> > > TrustZone, so the description there doesn't fit for your use case.
> > >
> > > I think we will also have to figure out how to handle the old
> > > "ChromeOS"/"non_tz" use case (that resets Iris directly with the
> > > registers) vs the EL2 PAS use case (that resets Iris in TZ but still
> > > handles IOMMU from Linux). Simply checking for the presence of the
> > > "video-firmware" node is not enough, because that doesn't tell us if the
> > > PAS support is present in TZ.
> > >
> > > I have been experimenting with a similar patch that copies the "non_tz"
> > > code paths from Venus into Iris. We need this to upstream the Iris DT
> > > patch for X1E without regressing the community-contributed x1-el2.dtso,
> > > which doesn't have functional PAS when running in EL2.
> > >
> > > Perhaps we could check for __qcom_scm_is_call_available() with the new
> > > QCOM_SCM_PIL_PAS_GET_RSCTABLE to choose between invoking reset via PAS
> > > or directly with the registers. I don't have a device with the new
> > > firmware to verify if that works.
> >
> > You can check QCOM_SCM_PIL_PAS_GET_RSCTABLE with __qcom_scm_is_call_available()
> > but there is a possibility that QCOM_SCM_PIL_PAS_GET_RSCTABLE SMC call will be
> > used even for Gunyah. So, I believe, __qcom_scm_is_call_available() and
> > video-firmware's iommu property is also important.
> >
>
> Yeah, this sounds good.
>
> > >
> > > I'll try to send out my patch soon, so you can better see the context.
> >
> > Are you saying that you are going to send patch to support IRIS on
> > x1-el2.dtso in non-secure way i.e., non-PAS way.
> >
>
> The background is the following: I have a pending patch to add iris to
> x1e80100.dtsi, but that currently breaks x1-el2.dtso. My original plan
> was to disable &iris in x1-el2.dtso (because the PAS way seems to be
> just broken), but then I saw that e.g. sc7180-el2.dtso does have working
> Venus with the "video-firmware" node. Copy-pasting the "no_tz"(/non-PAS)
> code as-is from venus into iris works just fine for x1-el2.dtso, so
> disabling &iris in x1-el2.dtso just because the "no_tz" code is
> currently missing in iris doesn't sound right.
>
> As far as I understand the approach you use in this series does not work
> without the TZ changes for older platforms like X1E(?), so adding that
> code in iris seems to be the best way to move forward.
Yes, this series has dependency on firmware and will not work for older
platforms.
>
> I started working on a patch for this a while ago, it just needs a bit
> more cleanup. I'll try to finish it up and post it so we can discuss it
> further. I think the IOMMU management in my patch would even work as-is
> for you, you would just need to toggle a boolean to use the PAS instead
> of accessing the registers directly.
Sounds like a plan.
Thanks, please cc me when you send the patches; So, I could test along
with my changes and make dependency on it.
>
> Thanks,
> Stephan
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function
2025-08-21 17:03 ` Mukesh Ojha
@ 2025-08-22 16:52 ` Mukesh Ojha
2025-08-22 23:13 ` Bryan O'Donoghue
1 sibling, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-22 16:52 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
linux-kernel, linux-arm-msm, linux-media, linux-remoteproc
On Thu, Aug 21, 2025 at 10:33:37PM +0530, Mukesh Ojha wrote:
> On Thu, Aug 21, 2025 at 04:23:53PM +0100, Bryan O'Donoghue wrote:
> > On 19/08/2025 17:54, Mukesh Ojha wrote:
> > > Qualcomm SoCs running with QHEE (Qualcomm Hypervisor Execution
> > > Environment—a library present in the Gunyah hypervisor) utilize the
> > > Peripheral Authentication Service (PAS) from Qualcomm TrustZone (TZ)
> > > also called QTEE(Qualcomm Trusted Execution Environment firmware)
> > > to securely authenticate and reset remote processors via a sequence
> > > of SMC calls such as qcom_scm_pas_init_image(), qcom_scm_pas_mem_setup(),
> > > and qcom_scm_pas_auth_and_reset().
> > >
> > > For memory passed to Qualcomm TrustZone, it must either be part of a
> > > pool registered with TZ or be directly registered via SHMbridge SMC
> > > calls.
> > >
> > > When QHEE is present, PAS SMC calls from Linux running at EL1 are
> > > trapped by QHEE (running at EL2), which then creates or retrieves memory
> > > from the SHM bridge for both metadata and remoteproc carveout memory
> > > before passing them to TZ. However, when the SoC runs with a
> > > non-QHEE-based hypervisor, Linux must create the SHM bridge for both
> > > metadata (before it is passed to TZ in qcom_scm_pas_init_image()) and
> > > for remoteproc memory (before the call is made to TZ in
> > > qcom_scm_pas_auth_and_reset()).
> > >
> > > For the qcom_scm_pas_init_image() call, metadata content must be copied
> > > to a buffer allocated from the SHM bridge before making the SMC call.
> > > This buffer should be freed either immediately after the call or during
> > > the qcom_scm_pas_metadata_release() function, depending on the context
> > > parameter passed to qcom_scm_pas_init_image(). Convert the metadata
> > > context parameter to use PAS context data structure so that it will also
> > > be possible to decide whether to get memory from SHMbridge pool or not.
> > >
> > > When QHEE is present, it manages the IOMMU translation context so, in
> > > absence of it device driver will be aware through device tree that its
> > > translation context is managed by Linux and it need to create SHMbridge
> > > before passing any buffer to TZ, So, remote processor driver should
> > > appropriately set ctx->has_iommu to let PAS SMC function to take care of
> > > everything ready for the call to work.
> > >
> > > Lets convert qcom_scm_pas_init_image() and qcom_scm_pas_metadata_release()
> > > to have these awareness.
> >
> > I like the effort in the commit log here but its also a bit too long.
> >
> > Please go through these paragraphs and try to reduce down the amount of text
> > you are generating.
>
> I was writing to set context for each commit and for the record and hence, the
> repetition of text you would see in some of the lines used.
>
> I will take your suggestion and reduce it.
>
> >
> > >
> > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > > ---
> > > drivers/firmware/qcom/qcom_scm.c | 71 +++++++++++++++++++++-----
> > > drivers/remoteproc/qcom_q6v5_pas.c | 14 ++---
> > > drivers/soc/qcom/mdt_loader.c | 4 +-
> > > include/linux/firmware/qcom/qcom_scm.h | 9 ++--
> > > 4 files changed, 73 insertions(+), 25 deletions(-)
> > >
> > > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > > index 7827699e277c..301d440f62f3 100644
> > > --- a/drivers/firmware/qcom/qcom_scm.c
> > > +++ b/drivers/firmware/qcom/qcom_scm.c
> > > @@ -616,6 +616,35 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> > > return ret;
> > > }
> > > +static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_ctx *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->peripheral, mdata_phys, mdata_buf, size, &res);
> > > + if (ret < 0 || !mdt_ctx) {
> >
> > if ret is an error or mdt_ctx is null free the memory
> >
> > > + qcom_tzmem_free(mdata_buf);
> > > + } else if (mdt_ctx) {
> >
> > if mdt_ctx is valid do this
>
> Nothing change, it is similar to the earlier code.
>
> >
> > > + mdt_ctx->ptr = mdata_buf;
> > > + mdt_ctx->addr.phys_addr = mdata_phys;
> > > + mdt_ctx->size = size;
> > > + }
> > > +
> > > + return ret ? : res.result[0];
> >
> > so we can have ctx_mtd valid but return the value at ret but also mtd valid
> > and return the res.result[0]
> >
> > That seems like an odd choice - surely if you are enumerating the
> > data-structure the result code we care about is res.result[0] instead of ret
> > ?
> >
> > OK I see this return logic comes from below..
> >
> > But
> >
> > drivers/soc/qcom/mdt_loader.c::qcom_mdt_pas_init
> >
> > ret = qcom_scm_pas_init_image(pas_id, metadata, metadata_len, ctx);
> > kfree(metadata);
> > if (ret) {
> > /* Invalid firmware metadata */
> > dev_err(dev, "error %d initializing firmware %s\n", ret, fw_name);
> > goto out;
> > }
> >
> > So if ret as returned from your function is > 0 you will leak the memory
> > allocated @ mdata_buf ..
> >
> > Do you expect something else to come along and call
> > qcom_scm_pas_metadata_release() ?
>
> You just identified a bug in the existing code where qcom_mdt_pas_init()
> does not call qcom_scm_pas_metadata_release() for firmware image for
> failure case from qcom_q6v5_pas().
This could be bug only if some odd firmware return > 0 response code
even if the SMC was a success.
>
>
> >
> > > +}
> > > +
> > > /**
> > > * qcom_scm_pas_init_image() - Initialize peripheral authentication service
> > > * state machine for a given peripheral, using the
> > > @@ -625,7 +654,7 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> > > * 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.
> > > *
> > > @@ -634,13 +663,19 @@ static int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t mdata_phys,
> > > * qcom_scm_pas_metadata_release() by the caller.
> > > */
> > > int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> > > - struct qcom_scm_pas_metadata *ctx)
> > > + struct qcom_scm_pas_ctx *ctx)
> > > {
> > > + struct qcom_scm_pas_metadata *mdt_ctx;
> > > struct qcom_scm_res res;
> > > dma_addr_t mdata_phys;
> > > void *mdata_buf;
> > > int ret;
> > > + if (ctx && ctx->has_iommu) {
> > > + ret = qcom_scm_pas_prep_and_init_image(ctx, metadata, size);
> > > + return ret;
> > > + }
> > > +
> > > /*
> > > * During the scm call memory protection will be enabled for the meta
> > > * data blob, so make sure it's physically contiguous, 4K aligned and
> > > @@ -663,10 +698,11 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
> > > ret = __qcom_scm_pas_init_image(peripheral, mdata_phys, mdata_buf, size, &res);
> > > 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->metadata) {
> > > + mdt_ctx = ctx->metadata;
> > > + mdt_ctx->ptr = mdata_buf;
> > > + mdt_ctx->addr.dma_addr = mdata_phys;
> > > + mdt_ctx->size = size;
> > > }
> > > return ret ? : res.result[0];
> >
> > is this return path still valid now that you've functionally decomposed into
> > qcom_sm_pas_prep_and_init ?
Yes, should be the same as it was earlier.
I believe, there is a duplication but its worth it to avoid confusion to
among different allocators used here one is DMA and other is TZmem.
> >
> > > @@ -675,18 +711,27 @@ 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_ctx *ctx)
> > > {
> > > - if (!ctx->ptr)
> > > + struct qcom_scm_pas_metadata *mdt_ctx;
> > > +
> > > + mdt_ctx = ctx->metadata;
> > > + if (!mdt_ctx->ptr)
> > > return;
> > > - dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, 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;
> > > + }
> > > - ctx->ptr = NULL;
> > > - ctx->phys = 0;
> > > - ctx->size = 0;
> > > + mdt_ctx->ptr = NULL;
> > > + 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 e376c0338576..09cada92dfd5 100644
> > > --- a/drivers/remoteproc/qcom_q6v5_pas.c
> > > +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> > > @@ -209,9 +209,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_ctx->metadata);
> > > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > > if (pas->dtb_pas_id)
> > > - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > > return 0;
> > > }
> > > @@ -244,7 +244,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_ctx->metadata);
> > > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > > release_firmware(pas->dtb_firmware);
> > > return ret;
> > > @@ -313,9 +313,9 @@ static int qcom_pas_start(struct rproc *rproc)
> > > goto release_pas_metadata;
> > > }
> > > - qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
> > > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > > if (pas->dtb_pas_id)
> > > - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->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;
> > > @@ -323,9 +323,9 @@ static int qcom_pas_start(struct rproc *rproc)
> > > return 0;
> > > release_pas_metadata:
> > > - qcom_scm_pas_metadata_release(pas->pas_ctx->metadata);
> > > + qcom_scm_pas_metadata_release(pas->pas_ctx);
> > > if (pas->dtb_pas_id)
> > > - qcom_scm_pas_metadata_release(pas->dtb_pas_ctx->metadata);
> > > + qcom_scm_pas_metadata_release(pas->dtb_pas_ctx);
> > > disable_px_supply:
> > > if (pas->px_supply)
> > > regulator_disable(pas->px_supply);
> > > diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> > > index 509ff85d9bf6..a1718db91b3e 100644
> > > --- a/drivers/soc/qcom/mdt_loader.c
> > > +++ b/drivers/soc/qcom/mdt_loader.c
> > > @@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
> > > */
> > > 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_metadata *ctx)
> > > + struct qcom_scm_pas_ctx *ctx)
> > > {
> > > const struct elf32_phdr *phdrs;
> > > const struct elf32_phdr *phdr;
> > > @@ -491,7 +491,7 @@ int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *ctx, const struct firmware *fw,
> > > int ret;
> > > ret = __qcom_mdt_pas_init(ctx->dev, fw, firmware, ctx->peripheral,
> > > - ctx->mem_phys, ctx->metadata);
> > > + ctx->mem_phys, ctx);
> > > if (ret)
> > > return ret;
> > > diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> > > index a31006fe49a9..bd3417d9c3f9 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;
> > > };
> > > @@ -85,8 +88,8 @@ struct qcom_scm_pas_ctx {
> > > void *qcom_scm_pas_ctx_init(struct device *dev, u32 peripheral, phys_addr_t mem_phys,
> > > size_t mem_size, bool save_mdt_ctx);
> > > int qcom_scm_pas_init_image(u32 peripheral, 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_ctx *ctx);
> > > +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_ctx *ctx);
> > > int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
> > > int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_ctx *ctx);
> > > int qcom_scm_pas_auth_and_reset(u32 peripheral);
> >
> > Please review the error paths here especially WRT to qcom_mdt_pas_init();
>
> Sure, will send the fix patch for the existing bug.
For existing code, consider a bug only if it is buggy firmware.
>
> >
> > ---
> > bod
>
> --
> -Mukesh Ojha
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function
2025-08-21 17:03 ` Mukesh Ojha
2025-08-22 16:52 ` Mukesh Ojha
@ 2025-08-22 23:13 ` Bryan O'Donoghue
1 sibling, 0 replies; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-08-22 23:13 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Konrad Dybcio,
Vikash Garodia, Dikshita Agarwal, Mauro Carvalho Chehab,
Mathieu Poirier, Abhinav Kumar, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On 21/08/2025 18:03, Mukesh Ojha wrote:
>> Please review the error paths here especially WRT to qcom_mdt_pas_init();
> Sure, will send the fix patch for the existing bug.
In which case please structure your next submission with bugfixes coming
first in the series with Fixes: tags and then apply your changes on top
as a progressive set of changes so we can apply this fix to -stable.
Don't forget to Cc: stable
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-22 15:13 ` Mukesh Ojha
@ 2025-08-23 15:41 ` Krzysztof Kozlowski
2025-08-23 15:46 ` Krzysztof Kozlowski
0 siblings, 1 reply; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-23 15:41 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 22/08/2025 17:13, Mukesh Ojha wrote:
> On Fri, Aug 22, 2025 at 10:45:50AM +0200, Krzysztof Kozlowski wrote:
>> On 19/08/2025 18:54, Mukesh Ojha wrote:
>>> +int iris_fw_init(struct iris_core *core)
>>> +{
>>> + struct platform_device_info info;
>>> + struct iommu_domain *iommu_dom;
>>> + struct platform_device *pdev;
>>> + struct device_node *np;
>>> + int ret;
>>> +
>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
>>
>> Undocumented ABI.
>>
>> If you tested your DTS, you would notice warnings.
>
> qcom,venus-common.yaml is documenting video-firmware and getting included in
> Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
Uh, why? Why does qcom keep this legacy pattern also for iris?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-23 15:41 ` Krzysztof Kozlowski
@ 2025-08-23 15:46 ` Krzysztof Kozlowski
2025-08-23 15:52 ` Krzysztof Kozlowski
0 siblings, 1 reply; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-23 15:46 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 23/08/2025 17:41, Krzysztof Kozlowski wrote:
> On 22/08/2025 17:13, Mukesh Ojha wrote:
>> On Fri, Aug 22, 2025 at 10:45:50AM +0200, Krzysztof Kozlowski wrote:
>>> On 19/08/2025 18:54, Mukesh Ojha wrote:
>>>> +int iris_fw_init(struct iris_core *core)
>>>> +{
>>>> + struct platform_device_info info;
>>>> + struct iommu_domain *iommu_dom;
>>>> + struct platform_device *pdev;
>>>> + struct device_node *np;
>>>> + int ret;
>>>> +
>>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
>>>
>>> Undocumented ABI.
>>>
>>> If you tested your DTS, you would notice warnings.
>>
>> qcom,venus-common.yaml is documenting video-firmware and getting included in
>> Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
>
> Uh, why? Why does qcom keep this legacy pattern also for iris?
I will remove it btw, because it is a fake device node (not for a real
device).
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-23 15:46 ` Krzysztof Kozlowski
@ 2025-08-23 15:52 ` Krzysztof Kozlowski
0 siblings, 0 replies; 74+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-23 15:52 UTC (permalink / raw)
To: Mukesh Ojha
Cc: Bjorn Andersson, Konrad Dybcio, Vikash Garodia, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 23/08/2025 17:46, Krzysztof Kozlowski wrote:
> On 23/08/2025 17:41, Krzysztof Kozlowski wrote:
>> On 22/08/2025 17:13, Mukesh Ojha wrote:
>>> On Fri, Aug 22, 2025 at 10:45:50AM +0200, Krzysztof Kozlowski wrote:
>>>> On 19/08/2025 18:54, Mukesh Ojha wrote:
>>>>> +int iris_fw_init(struct iris_core *core)
>>>>> +{
>>>>> + struct platform_device_info info;
>>>>> + struct iommu_domain *iommu_dom;
>>>>> + struct platform_device *pdev;
>>>>> + struct device_node *np;
>>>>> + int ret;
>>>>> +
>>>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
>>>>
>>>> Undocumented ABI.
>>>>
>>>> If you tested your DTS, you would notice warnings.
>>>
>>> qcom,venus-common.yaml is documenting video-firmware and getting included in
>>> Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
>>
>> Uh, why? Why does qcom keep this legacy pattern also for iris?
>
> I will remove it btw, because it is a fake device node (not for a real
> device).
So also to clarify: drop it here, because it will be undocumented.
Anyway such fake node was NAKed in other context.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-22 16:40 ` Mukesh Ojha
@ 2025-08-23 20:43 ` Stephan Gerhold
2025-08-25 11:19 ` Mukesh Ojha
0 siblings, 1 reply; 74+ messages in thread
From: Stephan Gerhold @ 2025-08-23 20:43 UTC (permalink / raw)
To: Mukesh Ojha, Vikash Garodia
Cc: Bjorn Andersson, Konrad Dybcio, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Fri, Aug 22, 2025 at 10:10:30PM +0530, Mukesh Ojha wrote:
> On Fri, Aug 22, 2025 at 06:26:19PM +0200, Stephan Gerhold wrote:
> > On Fri, Aug 22, 2025 at 08:36:11PM +0530, Mukesh Ojha wrote:
> > > On Fri, Aug 22, 2025 at 10:46:20AM +0200, Stephan Gerhold wrote:
> > > > On Fri, Aug 22, 2025 at 09:56:49AM +0530, Vikash Garodia wrote:
> > > > > On 8/20/2025 7:09 PM, Stephan Gerhold wrote:
> > > > > >>>> +int iris_fw_init(struct iris_core *core)
> > > > > >>>> +{
> > > > > >>>> + struct platform_device_info info;
> > > > > >>>> + struct iommu_domain *iommu_dom;
> > > > > >>>> + struct platform_device *pdev;
> > > > > >>>> + struct device_node *np;
> > > > > >>>> + int ret;
> > > > > >>>> +
> > > > > >>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > > > > >>>> + if (!np)
> > > > > >>>> + return 0;
> > > > > >>> You need a dt-bindings change for this as well. This is documented only
> > > > > >>> for Venus.
> > > > > >> You are right, wanted to send device tree and binding support separately.
> > > > > >> But if required, will add with the series in the next version.
> > > > > >>
> > > > > > You can send device tree changes separately, but dt-binding changes
> > > > > > always need to come before the driver changes.
> > > > >
> > > > > Do you mean to update the examples section[1] with the firmware subnode,
> > > > > something similar to venus schema[2] ?
> > > > >
> > > >
> > > > Sorry, I missed the fact that the "video-firmware" subnode is already
> > > > documented for iris as well through qcom,venus-common.yaml (which is
> > > > included for qcom,sm8550-iris). I don't think it's strictly required to
> > > > add every possibility to the examples of the schema, since we'll also
> > > > have the actual DTBs later to test this part of the schema.
> > > >
> > > > I would recommend to extend the description of the "video-firmware" node
> > > > in qcom,venus-common.yaml a bit. You do use the reset functionality of
> > > > TrustZone, so the description there doesn't fit for your use case.
> > > >
> > > > I think we will also have to figure out how to handle the old
> > > > "ChromeOS"/"non_tz" use case (that resets Iris directly with the
> > > > registers) vs the EL2 PAS use case (that resets Iris in TZ but still
> > > > handles IOMMU from Linux). Simply checking for the presence of the
> > > > "video-firmware" node is not enough, because that doesn't tell us if the
> > > > PAS support is present in TZ.
> > > >
> > > > I have been experimenting with a similar patch that copies the "non_tz"
> > > > code paths from Venus into Iris. We need this to upstream the Iris DT
> > > > patch for X1E without regressing the community-contributed x1-el2.dtso,
> > > > which doesn't have functional PAS when running in EL2.
> > > >
> > > > Perhaps we could check for __qcom_scm_is_call_available() with the new
> > > > QCOM_SCM_PIL_PAS_GET_RSCTABLE to choose between invoking reset via PAS
> > > > or directly with the registers. I don't have a device with the new
> > > > firmware to verify if that works.
> > >
> > > You can check QCOM_SCM_PIL_PAS_GET_RSCTABLE with __qcom_scm_is_call_available()
> > > but there is a possibility that QCOM_SCM_PIL_PAS_GET_RSCTABLE SMC call will be
> > > used even for Gunyah. So, I believe, __qcom_scm_is_call_available() and
> > > video-firmware's iommu property is also important.
> > >
> >
> > Yeah, this sounds good.
> >
> > > >
> > > > I'll try to send out my patch soon, so you can better see the context.
> > >
> > > Are you saying that you are going to send patch to support IRIS on
> > > x1-el2.dtso in non-secure way i.e., non-PAS way.
> > >
> >
> > The background is the following: I have a pending patch to add iris to
> > x1e80100.dtsi, but that currently breaks x1-el2.dtso. My original plan
> > was to disable &iris in x1-el2.dtso (because the PAS way seems to be
> > just broken), but then I saw that e.g. sc7180-el2.dtso does have working
> > Venus with the "video-firmware" node. Copy-pasting the "no_tz"(/non-PAS)
> > code as-is from venus into iris works just fine for x1-el2.dtso, so
> > disabling &iris in x1-el2.dtso just because the "no_tz" code is
> > currently missing in iris doesn't sound right.
> >
> > As far as I understand the approach you use in this series does not work
> > without the TZ changes for older platforms like X1E(?), so adding that
> > code in iris seems to be the best way to move forward.
>
> Yes, this series has dependency on firmware and will not work for older
> platforms.
>
> >
> > I started working on a patch for this a while ago, it just needs a bit
> > more cleanup. I'll try to finish it up and post it so we can discuss it
> > further. I think the IOMMU management in my patch would even work as-is
> > for you, you would just need to toggle a boolean to use the PAS instead
> > of accessing the registers directly.
>
> Sounds like a plan.
> Thanks, please cc me when you send the patches; So, I could test along
> with my changes and make dependency on it.
>
Krzysztof raised the concern that we shouldn't model the IOMMU specifier
for the firmware using a "video-firmware" subnode [1], similar to the
discussion for the "non-pixel" subnode recently [2].
I mostly finished up the cleanup of my patch, but I don't see any point
in posting it without an alternative proposal for the dt-bindings. For
this case, I think a simple property like
firmware-iommus = <&apps_smmu ...>;
instead of
video-firmware {
iommus = <&apps_smmu ...>;
};
could perhaps work. (XYZ-iommus isn't standardized at the moment, but I
think something like XYZ-gpios would make sense in this case. There are
many other possible approaches as well though.)
Unfortunately, I won't have enough time in the next weeks to fully
implement and propose an alternative. I'm assuming you still have
ongoing work for supporting the "non-pixel" IOMMU, perhaps your new
approach can be adapted for video-firmware as well?
I've pushed my current patch to a branch in case it helps. It's similar
to yours, but it has no external dependencies except for a fix in iris
I sent recently ("media: iris: Fix firmware reference leak and unmap
memory after load" [3]). You could use the non-PAS use case as a basis
to add the initial implementation in iris independent of this larger
patch series.
https://git.codelinaro.org/stephan.gerhold/linux/-/commit/1e068f5864d958ab9e807e6e3772b778cd0edea8.patch
For the PAS+IOMMU use case, it should be enough to set core->use_tz to
true, plus any changes needed for the SHM bridge (and maybe resource
table). The IOMMU management is independent from core->use_tz.
I'm also happy to add the non-PAS approach later on top of your changes,
whatever works best for you. :)
Thanks,
Stephan
[1]: https://lore.kernel.org/r/20250823155349.22344-2-krzysztof.kozlowski@linaro.org/
[2]: https://lore.kernel.org/r/20250627-video_cb-v3-0-51e18c0ffbce@quicinc.com/T/
[3]: https://lore.kernel.org/r/20250818-iris-firmware-leak-v1-1-1e3f9b8d31ce@linaro.org/
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
2025-08-23 20:43 ` Stephan Gerhold
@ 2025-08-25 11:19 ` Mukesh Ojha
0 siblings, 0 replies; 74+ messages in thread
From: Mukesh Ojha @ 2025-08-25 11:19 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Vikash Garodia, Bjorn Andersson, Konrad Dybcio, Dikshita Agarwal,
Mauro Carvalho Chehab, Mathieu Poirier, Abhinav Kumar,
Bryan O'Donoghue, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Sat, Aug 23, 2025 at 10:43:52PM +0200, Stephan Gerhold wrote:
> On Fri, Aug 22, 2025 at 10:10:30PM +0530, Mukesh Ojha wrote:
> > On Fri, Aug 22, 2025 at 06:26:19PM +0200, Stephan Gerhold wrote:
> > > On Fri, Aug 22, 2025 at 08:36:11PM +0530, Mukesh Ojha wrote:
> > > > On Fri, Aug 22, 2025 at 10:46:20AM +0200, Stephan Gerhold wrote:
> > > > > On Fri, Aug 22, 2025 at 09:56:49AM +0530, Vikash Garodia wrote:
> > > > > > On 8/20/2025 7:09 PM, Stephan Gerhold wrote:
> > > > > > >>>> +int iris_fw_init(struct iris_core *core)
> > > > > > >>>> +{
> > > > > > >>>> + struct platform_device_info info;
> > > > > > >>>> + struct iommu_domain *iommu_dom;
> > > > > > >>>> + struct platform_device *pdev;
> > > > > > >>>> + struct device_node *np;
> > > > > > >>>> + int ret;
> > > > > > >>>> +
> > > > > > >>>> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> > > > > > >>>> + if (!np)
> > > > > > >>>> + return 0;
> > > > > > >>> You need a dt-bindings change for this as well. This is documented only
> > > > > > >>> for Venus.
> > > > > > >> You are right, wanted to send device tree and binding support separately.
> > > > > > >> But if required, will add with the series in the next version.
> > > > > > >>
> > > > > > > You can send device tree changes separately, but dt-binding changes
> > > > > > > always need to come before the driver changes.
> > > > > >
> > > > > > Do you mean to update the examples section[1] with the firmware subnode,
> > > > > > something similar to venus schema[2] ?
> > > > > >
> > > > >
> > > > > Sorry, I missed the fact that the "video-firmware" subnode is already
> > > > > documented for iris as well through qcom,venus-common.yaml (which is
> > > > > included for qcom,sm8550-iris). I don't think it's strictly required to
> > > > > add every possibility to the examples of the schema, since we'll also
> > > > > have the actual DTBs later to test this part of the schema.
> > > > >
> > > > > I would recommend to extend the description of the "video-firmware" node
> > > > > in qcom,venus-common.yaml a bit. You do use the reset functionality of
> > > > > TrustZone, so the description there doesn't fit for your use case.
> > > > >
> > > > > I think we will also have to figure out how to handle the old
> > > > > "ChromeOS"/"non_tz" use case (that resets Iris directly with the
> > > > > registers) vs the EL2 PAS use case (that resets Iris in TZ but still
> > > > > handles IOMMU from Linux). Simply checking for the presence of the
> > > > > "video-firmware" node is not enough, because that doesn't tell us if the
> > > > > PAS support is present in TZ.
> > > > >
> > > > > I have been experimenting with a similar patch that copies the "non_tz"
> > > > > code paths from Venus into Iris. We need this to upstream the Iris DT
> > > > > patch for X1E without regressing the community-contributed x1-el2.dtso,
> > > > > which doesn't have functional PAS when running in EL2.
> > > > >
> > > > > Perhaps we could check for __qcom_scm_is_call_available() with the new
> > > > > QCOM_SCM_PIL_PAS_GET_RSCTABLE to choose between invoking reset via PAS
> > > > > or directly with the registers. I don't have a device with the new
> > > > > firmware to verify if that works.
> > > >
> > > > You can check QCOM_SCM_PIL_PAS_GET_RSCTABLE with __qcom_scm_is_call_available()
> > > > but there is a possibility that QCOM_SCM_PIL_PAS_GET_RSCTABLE SMC call will be
> > > > used even for Gunyah. So, I believe, __qcom_scm_is_call_available() and
> > > > video-firmware's iommu property is also important.
> > > >
> > >
> > > Yeah, this sounds good.
> > >
> > > > >
> > > > > I'll try to send out my patch soon, so you can better see the context.
> > > >
> > > > Are you saying that you are going to send patch to support IRIS on
> > > > x1-el2.dtso in non-secure way i.e., non-PAS way.
> > > >
> > >
> > > The background is the following: I have a pending patch to add iris to
> > > x1e80100.dtsi, but that currently breaks x1-el2.dtso. My original plan
> > > was to disable &iris in x1-el2.dtso (because the PAS way seems to be
> > > just broken), but then I saw that e.g. sc7180-el2.dtso does have working
> > > Venus with the "video-firmware" node. Copy-pasting the "no_tz"(/non-PAS)
> > > code as-is from venus into iris works just fine for x1-el2.dtso, so
> > > disabling &iris in x1-el2.dtso just because the "no_tz" code is
> > > currently missing in iris doesn't sound right.
> > >
> > > As far as I understand the approach you use in this series does not work
> > > without the TZ changes for older platforms like X1E(?), so adding that
> > > code in iris seems to be the best way to move forward.
> >
> > Yes, this series has dependency on firmware and will not work for older
> > platforms.
> >
> > >
> > > I started working on a patch for this a while ago, it just needs a bit
> > > more cleanup. I'll try to finish it up and post it so we can discuss it
> > > further. I think the IOMMU management in my patch would even work as-is
> > > for you, you would just need to toggle a boolean to use the PAS instead
> > > of accessing the registers directly.
> >
> > Sounds like a plan.
> > Thanks, please cc me when you send the patches; So, I could test along
> > with my changes and make dependency on it.
> >
>
> Krzysztof raised the concern that we shouldn't model the IOMMU specifier
> for the firmware using a "video-firmware" subnode [1], similar to the
> discussion for the "non-pixel" subnode recently [2].
>
> I mostly finished up the cleanup of my patch, but I don't see any point
> in posting it without an alternative proposal for the dt-bindings. For
> this case, I think a simple property like
>
> firmware-iommus = <&apps_smmu ...>;
>
> instead of
>
> video-firmware {
> iommus = <&apps_smmu ...>;
> };
>
> could perhaps work. (XYZ-iommus isn't standardized at the moment, but I
> think something like XYZ-gpios would make sense in this case. There are
> many other possible approaches as well though.)
>
> Unfortunately, I won't have enough time in the next weeks to fully
> implement and propose an alternative. I'm assuming you still have
> ongoing work for supporting the "non-pixel" IOMMU, perhaps your new
> approach can be adapted for video-firmware as well?
I believe, non-pixel case a bit different and thats not depends on whether
it is PAS or non-PAS.
However, I liked the idea about introducing something similar to -gpios
for -iommus as could pottentially solves at least this issue. Here, we need
to create a platform device and its domain based on firmware-iommu
property.
So, its required change in device link to put supplier/consumer dependency
and addition of firmware-iommu binding for IRIS and little of changes
over your existing changes.
But I have doubt, whether @Krzysztof would be fine with it ?
>
> I've pushed my current patch to a branch in case it helps. It's similar
> to yours, but it has no external dependencies except for a fix in iris
> I sent recently ("media: iris: Fix firmware reference leak and unmap
> memory after load" [3]). You could use the non-PAS use case as a basis
> to add the initial implementation in iris independent of this larger
> patch series.
Thanks.
>
> https://git.codelinaro.org/stephan.gerhold/linux/-/commit/1e068f5864d958ab9e807e6e3772b778cd0edea8.patch
>
> For the PAS+IOMMU use case, it should be enough to set core->use_tz to
> true, plus any changes needed for the SHM bridge (and maybe resource
> table). The IOMMU management is independent from core->use_tz.
>
> I'm also happy to add the non-PAS approach later on top of your changes,
> whatever works best for you. :)
>
> Thanks,
> Stephan
>
> [1]: https://lore.kernel.org/r/20250823155349.22344-2-krzysztof.kozlowski@linaro.org/
> [2]: https://lore.kernel.org/r/20250627-video_cb-v3-0-51e18c0ffbce@quicinc.com/T/
> [3]: https://lore.kernel.org/r/20250818-iris-firmware-leak-v1-1-1e3f9b8d31ce@linaro.org/
--
-Mukesh Ojha
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-08-20 11:22 ` Mukesh Ojha
@ 2025-09-03 11:56 ` Konrad Dybcio
2025-09-03 13:31 ` Bryan O'Donoghue
0 siblings, 1 reply; 74+ messages in thread
From: Konrad Dybcio @ 2025-09-03 11:56 UTC (permalink / raw)
To: Bryan O'Donoghue, Bjorn Andersson, Konrad Dybcio,
Vikash Garodia, Dikshita Agarwal, Mauro Carvalho Chehab,
Mathieu Poirier, Abhinav Kumar, linux-kernel, linux-arm-msm,
linux-media, linux-remoteproc
On 8/20/25 1:22 PM, Mukesh Ojha wrote:
> On Wed, Aug 20, 2025 at 12:03:16PM +0100, Bryan O'Donoghue wrote:
>> On 19/08/2025 17:54, Mukesh Ojha wrote:
>>> This is a further continuation with a new approach to the topic
>>> discussed in [1] regarding the enablement of Secure Peripheral Image
>>> Loader support on Qualcomm SoCs when Linux runs at EL2.
>>>
>>> A few months ago, we also discussed the challenges at Linaro Connect
>>> 2025 [2] related to enabling remoteproc when Linux is running at EL2.
>>>
>>> [1]
>>> https://lore.kernel.org/lkml/20241004212359.2263502-1-quic_mojha@quicinc.com/
>>>
>>> [2]
>>> https://resources.linaro.org/en/resource/sF8jXifdb9V1mUefdbfafa
>>>
>>> Below, is the summary of the discussion.
>>
>> Which tree does this apply to exactly ?
>>
>> git-log-graph linux-stable/master
>> * c17b750b3ad9f - (tag: v6.17-rc2, linux-stable/master, linux-stable/HEAD)
>> Linux 6.17-rc2 (3 days ago)
>> * 8d561baae505b - Merge tag 'x86_urgent_for_v6.17_rc2' of
>> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip (3 days ago)
>>
>> b4 shazam 20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com
>>
>> b4 shazam 20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com
>>
>> Grabbing thread from lore.kernel.org/all/20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com/t.mbox.gz
>> Checking for newer revisions
>> Grabbing search results from lore.kernel.org
>> Analyzing 18 messages in the thread
>> Analyzing 0 code-review messages
>> Checking attestation on all messages, may take a moment...
>> ---
>> ✓ [PATCH v2 1/11] firmware: qcom_scm: Introduce PAS context initialization
>> helper
>> ✓ [PATCH v2 2/11] soc: qcom: mdtloader: Add context aware
>> qcom_mdt_pas_load() helper
>> ✓ [PATCH v2 3/11] firmware: qcom_scm: Add a prep version of auth_and_reset
>> function
>> ✓ [PATCH v2 4/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
>> ✓ [PATCH v2 5/11] firmware: qcom_scm: Add shmbridge support to
>> pas_init/release function
>> ✓ [PATCH v2 6/11] remoteproc: Move resource table data structure to its
>> own header
>> ✓ [PATCH v2 7/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to
>> get resource table
>> ✓ [PATCH v2 8/11] soc: qcom: mdt_loader: Add helper functions to map and
>> unmap resources
>> ✓ [PATCH v2 9/11] remoteproc: pas: Extend parse_fw callback to parse
>> resource table
>> ✓ [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with
>> IOMMU managed by Linux
>> ✓ [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU
>> managed by Linux
>> ---
>> ✓ Signed: DKIM/qualcomm.com (From: mukesh.ojha@oss.qualcomm.com)
>> ---
>> Total patches: 11
>> ---
>> Applying: firmware: qcom_scm: Introduce PAS context initialization helper
>> Applying: soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
>> Patch failed at 0002 soc: qcom: mdtloader: Add context aware
>> qcom_mdt_pas_load() helper
>> error: patch failed: drivers/remoteproc/qcom_q6v5_pas.c:235
>> error: drivers/remoteproc/qcom_q6v5_pas.c: patch does not apply
>> error: patch failed: drivers/soc/qcom/mdt_loader.c:302
>> error: drivers/soc/qcom/mdt_loader.c: patch does not apply
>> error: patch failed: include/linux/soc/qcom/mdt_loader.h:10
>> error: include/linux/soc/qcom/mdt_loader.h: patch does not apply
>> hint: Use 'git am --show-current-patch=diff' to see the failed patch
>> hint: When you have resolved this problem, run "git am --continue".
>> hint: If you prefer to skip this patch, run "git am --skip" instead.
>> hint: To restore the original branch and stop patching, run "git am
>> --abort".
>> hint: Disable this message with "git config set advice.mergeConflict false"
>
> Very sorry for the error.
>
> Can you try with this next-20250814 tag ?
You sent it on the 19th, so it's in your best interest to run a quick
git rebase --onto linux-next/master $(git describe --abbrev=0)
and giving the series a prompt re-test before sending, because there might have
been incompatible changes, whether ones that would prevent applying, or break
things functionally
Konrad
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-09-03 11:56 ` Konrad Dybcio
@ 2025-09-03 13:31 ` Bryan O'Donoghue
2025-09-03 14:02 ` Dmitry Baryshkov
0 siblings, 1 reply; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-09-03 13:31 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 03/09/2025 12:56, Konrad Dybcio wrote:
>> Can you try with this next-20250814 tag ?
> You sent it on the 19th, so it's in your best interest to run a quick
>
> git rebase --onto linux-next/master $(git describe --abbrev=0)
>
> and giving the series a prompt re-test before sending, because there might have
> been incompatible changes, whether ones that would prevent applying, or break
> things functionally
I can't even find that tag next-20250814 closets thing is
| * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 00062ea01d35e - Merge
tag 'drm-xe-fixes-2025-08-14' of
https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes (3 weeks ago)
but patch #9 in this series stubbornly won't apply to any SHA I've tried.
meh
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-09-03 13:31 ` Bryan O'Donoghue
@ 2025-09-03 14:02 ` Dmitry Baryshkov
2025-09-03 14:05 ` Bryan O'Donoghue
2025-09-03 14:13 ` Bryan O'Donoghue
0 siblings, 2 replies; 74+ messages in thread
From: Dmitry Baryshkov @ 2025-09-03 14:02 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Sep 03, 2025 at 02:31:55PM +0100, Bryan O'Donoghue wrote:
> On 03/09/2025 12:56, Konrad Dybcio wrote:
> > > Can you try with this next-20250814 tag ?
> > You sent it on the 19th, so it's in your best interest to run a quick
> >
> > git rebase --onto linux-next/master $(git describe --abbrev=0)
> >
> > and giving the series a prompt re-test before sending, because there might have
> > been incompatible changes, whether ones that would prevent applying, or break
> > things functionally
>
> I can't even find that tag next-20250814 closets thing is
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tag/?h=next-20250814
>
> | * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 00062ea01d35e - Merge tag
> 'drm-xe-fixes-2025-08-14' of https://gitlab.freedesktop.org/drm/xe/kernel
> into drm-fixes (3 weeks ago)
>
> but patch #9 in this series stubbornly won't apply to any SHA I've tried.
>
> meh
>
> ---
> bod
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-09-03 14:02 ` Dmitry Baryshkov
@ 2025-09-03 14:05 ` Bryan O'Donoghue
2025-09-03 14:13 ` Bryan O'Donoghue
1 sibling, 0 replies; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-09-03 14:05 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 03/09/2025 15:02, Dmitry Baryshkov wrote:
> On Wed, Sep 03, 2025 at 02:31:55PM +0100, Bryan O'Donoghue wrote:
>> On 03/09/2025 12:56, Konrad Dybcio wrote:
>>>> Can you try with this next-20250814 tag ?
>>> You sent it on the 19th, so it's in your best interest to run a quick
>>>
>>> git rebase --onto linux-next/master $(git describe --abbrev=0)
>>>
>>> and giving the series a prompt re-test before sending, because there might have
>>> been incompatible changes, whether ones that would prevent applying, or break
>>> things functionally
>>
>> I can't even find that tag next-20250814 closets thing is
>
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tag/?h=next-20250814
>
>>
>> | * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 00062ea01d35e - Merge tag
>> 'drm-xe-fixes-2025-08-14' of https://gitlab.freedesktop.org/drm/xe/kernel
>> into drm-fixes (3 weeks ago)
>>
>> but patch #9 in this series stubbornly won't apply to any SHA I've tried.
>>
>> meh
>>
>> ---
>> bod
>
ah..
I fetched -stable
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-09-03 14:02 ` Dmitry Baryshkov
2025-09-03 14:05 ` Bryan O'Donoghue
@ 2025-09-03 14:13 ` Bryan O'Donoghue
2025-09-03 14:21 ` Bryan O'Donoghue
2025-09-03 14:28 ` Dmitry Baryshkov
1 sibling, 2 replies; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-09-03 14:13 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 03/09/2025 15:02, Dmitry Baryshkov wrote:
> On Wed, Sep 03, 2025 at 02:31:55PM +0100, Bryan O'Donoghue wrote:
>> On 03/09/2025 12:56, Konrad Dybcio wrote:
>>>> Can you try with this next-20250814 tag ?
>>> You sent it on the 19th, so it's in your best interest to run a quick
>>>
>>> git rebase --onto linux-next/master $(git describe --abbrev=0)
>>>
>>> and giving the series a prompt re-test before sending, because there might have
>>> been incompatible changes, whether ones that would prevent applying, or break
>>> things functionally
>>
>> I can't even find that tag next-20250814 closets thing is
>
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tag/?h=next-20250814
>
>>
>> | * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 00062ea01d35e - Merge tag
>> 'drm-xe-fixes-2025-08-14' of https://gitlab.freedesktop.org/drm/xe/kernel
>> into drm-fixes (3 weeks ago)
>>
>> but patch #9 in this series stubbornly won't apply to any SHA I've tried.
>>
>> meh
>>
>> ---
>> bod
>
Unfortunately that's not the right SHA though
git checkout -b next-20250814-test next-20250814
Switched to a new branch 'next-20250814-test'
b4 shazam
20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com
Grabbing thread from
lore.kernel.org/all/20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com/t.mbox.gz
Checking for newer revisions
Grabbing search results from lore.kernel.org
Added from v8: 12 patches
Added from v9: 12 patches
Analyzing 60 messages in the thread
Analyzing 163 code-review messages
Will use the latest revision: v9
You can pick other revisions using the -vN flag
Checking attestation on all messages, may take a moment...
---
✓ [PATCH v9 1/11] tee: allow a driver to allocate a tee_device
without a pool
✓ [PATCH v9 2/11] tee: add close_context to TEE driver operation
✓ [PATCH v9 3/11] tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
✓ [PATCH v9 4/11] tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
✓ [PATCH v9 5/11] tee: increase TEE_MAX_ARG_SIZE to 4096
✓ [PATCH v9 6/11] firmware: qcom: scm: add support for object invocation
✓ [PATCH v9 7/11] firmware: qcom: tzmem: export shm_bridge create/delete
✓ [PATCH v9 8/11] tee: add Qualcomm TEE driver
✓ [PATCH v9 9/11] tee: qcom: add primordial object
✓ [PATCH v9 10/11] tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl
✓ [PATCH v9 11/11] Documentation: tee: Add Qualcomm TEE driver
---
✓ Signed: DKIM/qualcomm.com (From: amirreza.zarrabi@oss.qualcomm.com)
---
Total patches: 11
---
Base: using specified base-commit 33bcf93b9a6b028758105680f8b538a31bc563cf
Applying: tee: allow a driver to allocate a tee_device without a pool
Applying: tee: add close_context to TEE driver operation
Applying: tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
Applying: tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
Applying: tee: increase TEE_MAX_ARG_SIZE to 4096
Applying: firmware: qcom: scm: add support for object invocation
Applying: firmware: qcom: tzmem: export shm_bridge create/delete
Applying: tee: add Qualcomm TEE driver
Applying: tee: qcom: add primordial object
Applying: tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl
Applying: Documentation: tee: Add Qualcomm TEE driver
b4 shazam 20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com
Grabbing thread from
lore.kernel.org/all/20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com/t.mbox.gz
Checking for newer revisions
Grabbing search results from lore.kernel.org
Analyzing 70 messages in the thread
Looking for additional code-review trailers on lore.kernel.org
Analyzing 0 code-review messages
Checking attestation on all messages, may take a moment...
---
✓ [PATCH v2 1/11] firmware: qcom_scm: Introduce PAS context
initialization helper
✓ [PATCH v2 2/11] soc: qcom: mdtloader: Add context aware
qcom_mdt_pas_load() helper
✓ [PATCH v2 3/11] firmware: qcom_scm: Add a prep version of
auth_and_reset function
✓ [PATCH v2 4/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
+ Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> (✗
DKIM/linaro.org)
✓ [PATCH v2 5/11] firmware: qcom_scm: Add shmbridge support to
pas_init/release function
✓ [PATCH v2 6/11] remoteproc: Move resource table data structure to
its own header
✓ [PATCH v2 7/11] firmware: qcom_scm: Add
qcom_scm_pas_get_rsc_table() to get resource table
✓ [PATCH v2 8/11] soc: qcom: mdt_loader: Add helper functions to map
and unmap resources
✓ [PATCH v2 9/11] remoteproc: pas: Extend parse_fw callback to parse
resource table
✓ [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support
with IOMMU managed by Linux
✓ [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU
managed by Linux
---
✓ Signed: DKIM/qualcomm.com (From: mukesh.ojha@oss.qualcomm.com)
---
Total patches: 11
---
Applying: firmware: qcom_scm: Introduce PAS context initialization helper
Applying: soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
Applying: firmware: qcom_scm: Add a prep version of auth_and_reset function
Applying: firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
Applying: firmware: qcom_scm: Add shmbridge support to pas_init/release
function
Applying: remoteproc: Move resource table data structure to its own header
Applying: firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get
resource table
Applying: soc: qcom: mdt_loader: Add helper functions to map and unmap
resources
Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse
resource table
error: patch failed: drivers/soc/qcom/mdt_loader.c:22
error: drivers/soc/qcom/mdt_loader.c: patch does not apply
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am
--abort".
hint: Disable this message with "git config set advice.mergeConflict false"
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-09-03 14:13 ` Bryan O'Donoghue
@ 2025-09-03 14:21 ` Bryan O'Donoghue
2025-09-03 14:28 ` Dmitry Baryshkov
1 sibling, 0 replies; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-09-03 14:21 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 03/09/2025 15:13, Bryan O'Donoghue wrote:
> On 03/09/2025 15:02, Dmitry Baryshkov wrote:
>> On Wed, Sep 03, 2025 at 02:31:55PM +0100, Bryan O'Donoghue wrote:
>>> On 03/09/2025 12:56, Konrad Dybcio wrote:
>>>>> Can you try with this next-20250814 tag ?
>>>> You sent it on the 19th, so it's in your best interest to run a quick
>>>>
>>>> git rebase --onto linux-next/master $(git describe --abbrev=0)
>>>>
>>>> and giving the series a prompt re-test before sending, because there
>>>> might have
>>>> been incompatible changes, whether ones that would prevent applying,
>>>> or break
>>>> things functionally
>>>
>>> I can't even find that tag next-20250814 closets thing is
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/
>> tag/?h=next-20250814
>>
>>>
>>> | * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 00062ea01d35e - Merge
>>> tag
>>> 'drm-xe-fixes-2025-08-14' of https://gitlab.freedesktop.org/drm/xe/
>>> kernel
>>> into drm-fixes (3 weeks ago)
>>>
>>> but patch #9 in this series stubbornly won't apply to any SHA I've
>>> tried.
>>>
>>> meh
>>>
>>> ---
>>> bod
>>
>
> Unfortunately that's not the right SHA though
>
> git checkout -b next-20250814-test next-20250814
> Switched to a new branch 'next-20250814-test'
>
> b4 shazam 20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-
> ce7a1a774803@oss.qualcomm.com
> Grabbing thread from lore.kernel.org/all/20250812-qcom-tee-using-tee-ss-
> without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com/t.mbox.gz
> Checking for newer revisions
> Grabbing search results from lore.kernel.org
> Added from v8: 12 patches
> Added from v9: 12 patches
> Analyzing 60 messages in the thread
> Analyzing 163 code-review messages
> Will use the latest revision: v9
> You can pick other revisions using the -vN flag
> Checking attestation on all messages, may take a moment...
> ---
> ✓ [PATCH v9 1/11] tee: allow a driver to allocate a tee_device
> without a pool
> ✓ [PATCH v9 2/11] tee: add close_context to TEE driver operation
> ✓ [PATCH v9 3/11] tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
> ✓ [PATCH v9 4/11] tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
> ✓ [PATCH v9 5/11] tee: increase TEE_MAX_ARG_SIZE to 4096
> ✓ [PATCH v9 6/11] firmware: qcom: scm: add support for object invocation
> ✓ [PATCH v9 7/11] firmware: qcom: tzmem: export shm_bridge create/delete
> ✓ [PATCH v9 8/11] tee: add Qualcomm TEE driver
> ✓ [PATCH v9 9/11] tee: qcom: add primordial object
> ✓ [PATCH v9 10/11] tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl
> ✓ [PATCH v9 11/11] Documentation: tee: Add Qualcomm TEE driver
> ---
> ✓ Signed: DKIM/qualcomm.com (From: amirreza.zarrabi@oss.qualcomm.com)
> ---
> Total patches: 11
> ---
> Base: using specified base-commit
> 33bcf93b9a6b028758105680f8b538a31bc563cf
> Applying: tee: allow a driver to allocate a tee_device without a pool
> Applying: tee: add close_context to TEE driver operation
> Applying: tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
> Applying: tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
> Applying: tee: increase TEE_MAX_ARG_SIZE to 4096
> Applying: firmware: qcom: scm: add support for object invocation
> Applying: firmware: qcom: tzmem: export shm_bridge create/delete
> Applying: tee: add Qualcomm TEE driver
> Applying: tee: qcom: add primordial object
> Applying: tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl
> Applying: Documentation: tee: Add Qualcomm TEE driver
>
> b4 shazam 20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com
> Grabbing thread from lore.kernel.org/all/20250819165447.4149674-1-
> mukesh.ojha@oss.qualcomm.com/t.mbox.gz
> Checking for newer revisions
> Grabbing search results from lore.kernel.org
> Analyzing 70 messages in the thread
> Looking for additional code-review trailers on lore.kernel.org
> Analyzing 0 code-review messages
> Checking attestation on all messages, may take a moment...
> ---
> ✓ [PATCH v2 1/11] firmware: qcom_scm: Introduce PAS context
> initialization helper
> ✓ [PATCH v2 2/11] soc: qcom: mdtloader: Add context aware
> qcom_mdt_pas_load() helper
> ✓ [PATCH v2 3/11] firmware: qcom_scm: Add a prep version of
> auth_and_reset function
> ✓ [PATCH v2 4/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
> + Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> (✗
> DKIM/linaro.org)
> ✓ [PATCH v2 5/11] firmware: qcom_scm: Add shmbridge support to
> pas_init/release function
> ✓ [PATCH v2 6/11] remoteproc: Move resource table data structure to
> its own header
> ✓ [PATCH v2 7/11] firmware: qcom_scm: Add
> qcom_scm_pas_get_rsc_table() to get resource table
> ✓ [PATCH v2 8/11] soc: qcom: mdt_loader: Add helper functions to map
> and unmap resources
> ✓ [PATCH v2 9/11] remoteproc: pas: Extend parse_fw callback to parse
> resource table
> ✓ [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support
> with IOMMU managed by Linux
> ✓ [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU
> managed by Linux
> ---
> ✓ Signed: DKIM/qualcomm.com (From: mukesh.ojha@oss.qualcomm.com)
> ---
> Total patches: 11
> ---
> Applying: firmware: qcom_scm: Introduce PAS context initialization helper
> Applying: soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load()
> helper
> Applying: firmware: qcom_scm: Add a prep version of auth_and_reset function
> Applying: firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
> Applying: firmware: qcom_scm: Add shmbridge support to pas_init/release
> function
> Applying: remoteproc: Move resource table data structure to its own header
> Applying: firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get
> resource table
> Applying: soc: qcom: mdt_loader: Add helper functions to map and unmap
> resources
> Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
> Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse
> resource table
> error: patch failed: drivers/soc/qcom/mdt_loader.c:22
> error: drivers/soc/qcom/mdt_loader.c: patch does not apply
> hint: Use 'git am --show-current-patch=diff' to see the failed patch
> hint: When you have resolved this problem, run "git am --continue".
> hint: If you prefer to skip this patch, run "git am --skip" instead.
> hint: To restore the original branch and stop patching, run "git am --
> abort".
> hint: Disable this message with "git config set advice.mergeConflict false"
>
Its also possible to apply it manually ...
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c
b/drivers/remoteproc/qcom_q6v5_pas.c
index 09cada92dfd56..1e0f09bf1ef29 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -408,6 +408,35 @@ 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)
+{
+ struct qcom_pas *pas = rproc->priv;
+ size_t output_rt_size = MAX_RSCTABLE_SIZE;
+ void *output_rt;
+ 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 = qcom_scm_pas_get_rsc_table(pas->pas_id, NULL, 0,
&output_rt, &output_rt_size);
+ if (ret) {
+ dev_err(pas->dev, "error %d getting resource_table\n", ret);
+ return ret;
+ }
+
+ 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;
@@ -420,7 +449,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,
};
@@ -430,7 +459,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,
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index 3ac19e85d71df..a754e513cd541 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -22,7 +22,6 @@
#include <linux/slab.h>
#include <linux/soc/qcom/mdt_loader.h>
-#define MAX_RSCTABLE_SIZE SZ_16K
#define RSC_TABLE_HASH_BITS 5 // 32 buckets
DEFINE_HASHTABLE(qcom_pas_rsc_table_map, RSC_TABLE_HASH_BITS);
diff --git a/include/linux/soc/qcom/mdt_loader.h
b/include/linux/soc/qcom/mdt_loader.h
index 38475fd528d62..8fb3309d2a71a 100644
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -8,6 +8,8 @@
#define QCOM_MDT_TYPE_HASH (2 << 24)
#define QCOM_MDT_RELOCATABLE BIT(27)
+#define MAX_RSCTABLE_SIZE SZ_16K
+
struct device;
struct firmware;
struct qcom_scm_pas_ctx;
^ permalink raw reply related [flat|nested] 74+ messages in thread
* Re: [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2
2025-09-03 14:13 ` Bryan O'Donoghue
2025-09-03 14:21 ` Bryan O'Donoghue
@ 2025-09-03 14:28 ` Dmitry Baryshkov
1 sibling, 0 replies; 74+ messages in thread
From: Dmitry Baryshkov @ 2025-09-03 14:28 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier,
Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On Wed, Sep 03, 2025 at 03:13:18PM +0100, Bryan O'Donoghue wrote:
> On 03/09/2025 15:02, Dmitry Baryshkov wrote:
> > On Wed, Sep 03, 2025 at 02:31:55PM +0100, Bryan O'Donoghue wrote:
> > > On 03/09/2025 12:56, Konrad Dybcio wrote:
> > > > > Can you try with this next-20250814 tag ?
> > > > You sent it on the 19th, so it's in your best interest to run a quick
> > > >
> > > > git rebase --onto linux-next/master $(git describe --abbrev=0)
> > > >
> > > > and giving the series a prompt re-test before sending, because there might have
> > > > been incompatible changes, whether ones that would prevent applying, or break
> > > > things functionally
> > >
> > > I can't even find that tag next-20250814 closets thing is
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tag/?h=next-20250814
> >
> > >
> > > | * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 00062ea01d35e - Merge tag
> > > 'drm-xe-fixes-2025-08-14' of https://gitlab.freedesktop.org/drm/xe/kernel
> > > into drm-fixes (3 weeks ago)
> > >
> > > but patch #9 in this series stubbornly won't apply to any SHA I've tried.
> > >
> > > meh
> > >
> > > ---
> > > bod
> >
>
> Unfortunately that's not the right SHA though
Then let's wait for Mukesh to switch to b4 (and use b4 --edit-deps) or
to use a proper git format-patch arguments.
>
> git checkout -b next-20250814-test next-20250814
>
> Switched to a new branch 'next-20250814-test'
>
> b4 shazam 20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com
> Grabbing thread from lore.kernel.org/all/20250812-qcom-tee-using-tee-ss-without-mem-obj-v7-7-ce7a1a774803@oss.qualcomm.com/t.mbox.gz
> Checking for newer revisions
> Grabbing search results from lore.kernel.org
> Added from v8: 12 patches
> Added from v9: 12 patches
> Analyzing 60 messages in the thread
> Analyzing 163 code-review messages
> Will use the latest revision: v9
> You can pick other revisions using the -vN flag
> Checking attestation on all messages, may take a moment...
> ---
> ✓ [PATCH v9 1/11] tee: allow a driver to allocate a tee_device without a
> pool
> ✓ [PATCH v9 2/11] tee: add close_context to TEE driver operation
> ✓ [PATCH v9 3/11] tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
> ✓ [PATCH v9 4/11] tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
> ✓ [PATCH v9 5/11] tee: increase TEE_MAX_ARG_SIZE to 4096
> ✓ [PATCH v9 6/11] firmware: qcom: scm: add support for object invocation
> ✓ [PATCH v9 7/11] firmware: qcom: tzmem: export shm_bridge create/delete
> ✓ [PATCH v9 8/11] tee: add Qualcomm TEE driver
> ✓ [PATCH v9 9/11] tee: qcom: add primordial object
> ✓ [PATCH v9 10/11] tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl
> ✓ [PATCH v9 11/11] Documentation: tee: Add Qualcomm TEE driver
> ---
> ✓ Signed: DKIM/qualcomm.com (From: amirreza.zarrabi@oss.qualcomm.com)
> ---
> Total patches: 11
> ---
> Base: using specified base-commit 33bcf93b9a6b028758105680f8b538a31bc563cf
> Applying: tee: allow a driver to allocate a tee_device without a pool
> Applying: tee: add close_context to TEE driver operation
> Applying: tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
> Applying: tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
> Applying: tee: increase TEE_MAX_ARG_SIZE to 4096
> Applying: firmware: qcom: scm: add support for object invocation
> Applying: firmware: qcom: tzmem: export shm_bridge create/delete
> Applying: tee: add Qualcomm TEE driver
> Applying: tee: qcom: add primordial object
> Applying: tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl
> Applying: Documentation: tee: Add Qualcomm TEE driver
>
> b4 shazam 20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com
> Grabbing thread from lore.kernel.org/all/20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com/t.mbox.gz
> Checking for newer revisions
> Grabbing search results from lore.kernel.org
> Analyzing 70 messages in the thread
> Looking for additional code-review trailers on lore.kernel.org
> Analyzing 0 code-review messages
> Checking attestation on all messages, may take a moment...
> ---
> ✓ [PATCH v2 1/11] firmware: qcom_scm: Introduce PAS context initialization
> helper
> ✓ [PATCH v2 2/11] soc: qcom: mdtloader: Add context aware
> qcom_mdt_pas_load() helper
> ✓ [PATCH v2 3/11] firmware: qcom_scm: Add a prep version of auth_and_reset
> function
> ✓ [PATCH v2 4/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
> + Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> (✗
> DKIM/linaro.org)
> ✓ [PATCH v2 5/11] firmware: qcom_scm: Add shmbridge support to
> pas_init/release function
> ✓ [PATCH v2 6/11] remoteproc: Move resource table data structure to its
> own header
> ✓ [PATCH v2 7/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to
> get resource table
> ✓ [PATCH v2 8/11] soc: qcom: mdt_loader: Add helper functions to map and
> unmap resources
> ✓ [PATCH v2 9/11] remoteproc: pas: Extend parse_fw callback to parse
> resource table
> ✓ [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with
> IOMMU managed by Linux
> ✓ [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU
> managed by Linux
> ---
> ✓ Signed: DKIM/qualcomm.com (From: mukesh.ojha@oss.qualcomm.com)
> ---
> Total patches: 11
> ---
> Applying: firmware: qcom_scm: Introduce PAS context initialization helper
> Applying: soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
> Applying: firmware: qcom_scm: Add a prep version of auth_and_reset function
> Applying: firmware: qcom_scm: Simplify qcom_scm_pas_init_image()
> Applying: firmware: qcom_scm: Add shmbridge support to pas_init/release
> function
> Applying: remoteproc: Move resource table data structure to its own header
> Applying: firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get
> resource table
> Applying: soc: qcom: mdt_loader: Add helper functions to map and unmap
> resources
> Applying: remoteproc: pas: Extend parse_fw callback to parse resource table
> Patch failed at 0009 remoteproc: pas: Extend parse_fw callback to parse
> resource table
> error: patch failed: drivers/soc/qcom/mdt_loader.c:22
> error: drivers/soc/qcom/mdt_loader.c: patch does not apply
> hint: Use 'git am --show-current-patch=diff' to see the failed patch
> hint: When you have resolved this problem, run "git am --continue".
> hint: If you prefer to skip this patch, run "git am --skip" instead.
> hint: To restore the original branch and stop patching, run "git am
> --abort".
> hint: Disable this message with "git config set advice.mergeConflict false"
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 74+ messages in thread
* Re: [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper
2025-08-19 16:54 ` [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper Mukesh Ojha
2025-08-20 11:48 ` Bryan O'Donoghue
@ 2025-09-03 15:03 ` Bryan O'Donoghue
1 sibling, 0 replies; 74+ messages in thread
From: Bryan O'Donoghue @ 2025-09-03 15:03 UTC (permalink / raw)
To: Mukesh Ojha, Bjorn Andersson, Konrad Dybcio, Vikash Garodia,
Dikshita Agarwal, Mauro Carvalho Chehab, Mathieu Poirier
Cc: Abhinav Kumar, linux-kernel, linux-arm-msm, linux-media,
linux-remoteproc
On 19/08/2025 17:54, Mukesh Ojha wrote:
> Currently, remoteproc and non-remoteproc subsystems use different
> variants of the MDT loader helper API, primarily due to the handling of
> the metadata context. Remoteproc subsystems retain this context until
> authentication and reset, while non-remoteproc subsystems (e.g., video,
> graphics) do not require it.
>
> Add context aware qcom_mdt_pas_load() function which uses context
> returned from qcom_scm_pas_ctx_init() and use it till subsystems
> is out of set. This will also help in unifying the API used by
> remoteproc and non-remoteproc subsystems drivers.
>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
I'm struggling with the logic here a little bit.
You take this function which calls qcom_mtd_load_no_init();
>
> - 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);
> - 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);
and then turn it into
> +int qcom_mdt_pas_load(struct qcom_scm_pas_ctx *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->peripheral,
> + 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);
Surely you want to qcom_mdt_load_no_init ?
On current kernel
return __qcom_mdt_load(ctx->dev, fw, firmware, mem_region, ctx,
mem_phys, ctx->mem_size,
reloc_base, true);
but that's a functional change
> +}
> +EXPORT_SYMBOL_GPL(qcom_mdt_pas_load);
the no_init version of this looks like this:
int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
const char *firmware, int pas_id,
void *mem_region, phys_addr_t mem_phys,
size_t mem_size, phys_addr_t *reloc_base)
{
return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region,
mem_phys, mem_size, reloc_base, false);
}
EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init);
So is it really the intention of this patch to change the callsites
where qcom_mdt_pas_load() away from the init version to the no_init
version ?
Maybe its a symptom of patch collision but hmm, having a hard time
cherry-picking this to test.
---
bod
^ permalink raw reply [flat|nested] 74+ messages in thread
end of thread, other threads:[~2025-09-03 15:03 UTC | newest]
Thread overview: 74+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-19 16:54 [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 01/11] firmware: qcom_scm: Introduce PAS context initialization helper Mukesh Ojha
2025-08-19 17:17 ` Pavan Kondeti
2025-08-20 6:19 ` Mukesh Ojha
2025-08-20 11:40 ` Bryan O'Donoghue
2025-08-20 12:28 ` Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 02/11] soc: qcom: mdtloader: Add context aware qcom_mdt_pas_load() helper Mukesh Ojha
2025-08-20 11:48 ` Bryan O'Donoghue
2025-08-20 12:25 ` Mukesh Ojha
2025-09-03 15:03 ` Bryan O'Donoghue
2025-08-19 16:54 ` [PATCH v2 03/11] firmware: qcom_scm: Add a prep version of auth_and_reset function Mukesh Ojha
2025-08-20 12:03 ` Bryan O'Donoghue
2025-08-20 12:24 ` Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 04/11] firmware: qcom_scm: Simplify qcom_scm_pas_init_image() Mukesh Ojha
2025-08-21 14:36 ` Bryan O'Donoghue
2025-08-21 16:29 ` Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 05/11] firmware: qcom_scm: Add shmbridge support to pas_init/release function Mukesh Ojha
2025-08-21 15:23 ` Bryan O'Donoghue
2025-08-21 17:03 ` Mukesh Ojha
2025-08-22 16:52 ` Mukesh Ojha
2025-08-22 23:13 ` Bryan O'Donoghue
2025-08-19 16:54 ` [PATCH v2 06/11] remoteproc: Move resource table data structure to its own header Mukesh Ojha
2025-08-20 8:12 ` Stephan Gerhold
2025-08-20 15:18 ` Mukesh Ojha
2025-08-20 15:31 ` Stephan Gerhold
2025-08-22 7:56 ` Mukesh Ojha
2025-08-20 16:32 ` Mukesh Ojha
2025-08-20 16:53 ` Stephan Gerhold
2025-08-22 9:21 ` Mukesh Ojha
2025-08-22 8:35 ` Krzysztof Kozlowski
2025-08-22 9:30 ` Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 07/11] firmware: qcom_scm: Add qcom_scm_pas_get_rsc_table() to get resource table Mukesh Ojha
2025-08-21 15:05 ` Krzysztof Kozlowski
2025-08-21 17:20 ` Mukesh Ojha
2025-08-22 6:22 ` Krzysztof Kozlowski
2025-08-22 7:21 ` Mukesh Ojha
2025-08-22 8:30 ` Krzysztof Kozlowski
2025-08-19 16:54 ` [PATCH v2 08/11] soc: qcom: mdt_loader: Add helper functions to map and unmap resources Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 09/11] remoteproc: pas: Extend parse_fw callback to parse resource table Mukesh Ojha
2025-08-20 8:36 ` Stephan Gerhold
2025-08-20 11:14 ` Mukesh Ojha
2025-08-20 13:07 ` Stephan Gerhold
2025-08-21 14:49 ` Krzysztof Kozlowski
2025-08-21 17:41 ` Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 10/11] remoteproc: qcom: pas: Enable Secure PAS support with IOMMU managed by Linux Mukesh Ojha
2025-08-20 8:40 ` Stephan Gerhold
2025-08-20 12:03 ` Mukesh Ojha
2025-08-19 16:54 ` [PATCH v2 11/11] media: iris: " Mukesh Ojha
2025-08-20 8:46 ` Stephan Gerhold
2025-08-20 11:56 ` Mukesh Ojha
2025-08-20 13:39 ` Stephan Gerhold
2025-08-22 4:26 ` Vikash Garodia
2025-08-22 8:46 ` Stephan Gerhold
2025-08-22 15:06 ` Mukesh Ojha
2025-08-22 16:26 ` Stephan Gerhold
2025-08-22 16:40 ` Mukesh Ojha
2025-08-23 20:43 ` Stephan Gerhold
2025-08-25 11:19 ` Mukesh Ojha
2025-08-20 11:33 ` Bryan O'Donoghue
2025-08-20 12:00 ` Mukesh Ojha
2025-08-22 8:45 ` Krzysztof Kozlowski
2025-08-22 15:13 ` Mukesh Ojha
2025-08-23 15:41 ` Krzysztof Kozlowski
2025-08-23 15:46 ` Krzysztof Kozlowski
2025-08-23 15:52 ` Krzysztof Kozlowski
2025-08-20 11:03 ` [PATCH v2 00/11] Peripheral Image Loader support for Qualcomm SoCs running Linux host at EL2 Bryan O'Donoghue
2025-08-20 11:22 ` Mukesh Ojha
2025-09-03 11:56 ` Konrad Dybcio
2025-09-03 13:31 ` Bryan O'Donoghue
2025-09-03 14:02 ` Dmitry Baryshkov
2025-09-03 14:05 ` Bryan O'Donoghue
2025-09-03 14:13 ` Bryan O'Donoghue
2025-09-03 14:21 ` Bryan O'Donoghue
2025-09-03 14:28 ` Dmitry Baryshkov
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).