The PAS image initialization path retains metadata whenever a valid qcom_pas_context is supplied, although callers may not need the metadata after initialization. This leaves ownership implicit and causes unused metadata buffers to remain allocated.
Add keep_mdt_buf to struct qcom_pas_context and have the generic PAS wrapper release metadata unless the caller requests retention. This applies uniformly to SCM and OP-TEE backends, while qcom_q6v5_pas keeps metadata for subsequent PAS operations. Signed-off-by: Mukesh Ojha <[email protected]> --- Changes in v8: - Commit rephrased a bit. - Make the commit aware of all present backends(scm and tee). - Link to v7: https://lore.kernel.org/lkml/[email protected]/ Changes in v7: - Since qcom_scm_pas_context is removed, v6 needs to be rebased removing the changes related to it. - Link to v6: https://lore.kernel.org/lkml/[email protected]/ Changes in v6: - Other patches from the series is merged. - Removed dependency on below series by adding keep_mdt_buf into qcom_scm_pas_context structure as well. https://lore.kernel.org/lkml/[email protected]/ - Addressed minor comment on the documentationi. - Link to v5: 6/6 of https://lore.kernel.org/lkml/[email protected]/ drivers/firmware/qcom/qcom_pas.c | 12 +++++++++--- drivers/firmware/qcom/qcom_scm.c | 2 +- drivers/remoteproc/qcom_q6v5_pas.c | 3 +++ include/linux/firmware/qcom/qcom_pas.h | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c index 24485dd0fa10..93d78a5c1201 100644 --- a/drivers/firmware/qcom/qcom_pas.c +++ b/drivers/firmware/qcom/qcom_pas.c @@ -60,17 +60,23 @@ EXPORT_SYMBOL_GPL(devm_qcom_pas_context_alloc); * * Return: 0 on success. * - * Upon successful return, the PAS metadata context (@ctx) will be used to - * track the metadata allocation, this needs to be released by invoking + * If @ctx requests metadata retention, the PAS metadata context will track + * the allocation, which needs to be released by invoking * qcom_pas_metadata_release() by the caller. */ int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size, struct qcom_pas_context *ctx) { + int ret; + if (!ops_ptr) return -ENODEV; - return ops_ptr->init_image(ops_ptr->dev, pas_id, metadata, size, ctx); + ret = ops_ptr->init_image(ops_ptr->dev, pas_id, metadata, size, ctx); + if (!ret && ctx && !ctx->keep_mdt_buf) + qcom_pas_metadata_release(ctx); + + return ret; } EXPORT_SYMBOL_GPL(qcom_pas_init_image); diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index df20773dd754..dc57c87870cf 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -666,7 +666,7 @@ static int qcom_scm_pas_init_image(struct device *dev, u32 pas_id, ret = __qcom_scm_pas_init_image(dev, pas_id, mdata_phys, &res); if (ret < 0 || !ctx) { dma_free_coherent(dev, size, mdata_buf, mdata_phys); - } else if (ctx) { + } else { ctx->ptr = mdata_buf; ctx->phys = mdata_phys; ctx->size = size; diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 879c465c4a7a..ae93f693358c 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -733,6 +733,7 @@ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) if (IS_ERR(pas->pas_ctx)) return PTR_ERR(pas->pas_ctx); + pas->pas_ctx->keep_mdt_buf = true; if (!pas->dtb_pas_id) return 0; @@ -751,6 +752,8 @@ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) if (IS_ERR(pas->dtb_pas_ctx)) return PTR_ERR(pas->dtb_pas_ctx); + pas->dtb_pas_ctx->keep_mdt_buf = true; + return 0; } diff --git a/include/linux/firmware/qcom/qcom_pas.h b/include/linux/firmware/qcom/qcom_pas.h index fb2ec3be6a16..1d132e89536e 100644 --- a/include/linux/firmware/qcom/qcom_pas.h +++ b/include/linux/firmware/qcom/qcom_pas.h @@ -22,6 +22,7 @@ struct qcom_pas_context { dma_addr_t phys; ssize_t size; bool use_tzmem; + bool keep_mdt_buf; }; static inline void __iomem *qcom_pas_ctx_map(struct qcom_pas_context *ctx) -- 2.55.0

