From nobody Sat Oct 4 08:15:28 2025 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 453F7305E24 for ; Tue, 19 Aug 2025 16:56:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755622569; cv=none; b=Ng5UM/vs3Fd9ywF/b1Axnbto8vuyJ85b3D2NaP1xfn//8vpSIgRcfN8Bj9aJkKAC3jV0pLr+i9oyNGsswxVnHSO9aPueAihIZzz/flsLTgEzANKFn9cBxnA1B8E+q/21uQjgMlwG0HaTNvd3jwabVN0uNLFXggAUCCEtUOtIWN8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755622569; c=relaxed/simple; bh=4ddIxvA0hH2mxKgfv6MJY3eyB2GVx5N6CjAeCWH79KI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ga5C30aSozi9gaVDiQJEdqBIwTYq3w+NxrQJCcwUDulO1X30oHp1TH3Jhw5ch70LBFpR1eJFQBO4lbMnv/2BjxhetO6QHrAy8dAKFfFp6351jKCyq6QvEjSArGdWmluXpFvo4IcIxHwiDVYTsb5hR0EEoUlIGQQITMdHa/0Nf1M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=SobHllPW; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="SobHllPW" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 57J90YSm021768 for ; Tue, 19 Aug 2025 16:56:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=fwtoFh3kbTj shFkNb7Zh2kYEycwDTbRcgDbn16CiXI0=; b=SobHllPW2sSiKrpl/VQRv+jiiRS kZROaXacbWCM1uLOgoRb4YoqbVCHOdSUkXTGHppfrX2FvG4g25dFUM+AoKILMRAD xBxGVwXMlhtF8s4PVvLM3wqD2D1wiEX8YPXapJiDtrfrIT+FLBVRRhksUiyM5VJM DpEQrMm2iuuwkI3K9n9e2nToInUH/Ap2hKiQenhh+7hhv+1AARmmnPsTjzFd7+3W asRmqiVANYvdNpEtNEdAZC0QPvEpOnj0o3MflbCiuEccJK6CdegHpVJyTSLLNnSc AXIW6Z4S1HOlzWmxX45mmD0hcQbacVNxO1CJEP06LtBKps4p1RD3inQQzJw== Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 48m71cm23p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 19 Aug 2025 16:56:07 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2445806b2beso136932765ad.1 for ; Tue, 19 Aug 2025 09:56:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755622567; x=1756227367; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fwtoFh3kbTjshFkNb7Zh2kYEycwDTbRcgDbn16CiXI0=; b=Qlj0BsMhGXqg+cwDAQT9ysQHN5fyeF6T3BBEk3Hc+ZKqhNOdOY8Xjak/OG6U38vFvV 4emvxI4WVHVfnwjIKgfyIxveYWwKNEZf8Gg52IqDu289NR5PfluHCMwoIn7Hv4/buY4W jxZQc63wJRupt0rECIqgKhNO0vNstrs9MDM8dkM4YJYIRog55j9UIZvUKHmwBL/bBV3K kE29k//KHKZhAvQNvPAMIE2uqcZVeeZxeVVMX2H1xsoeFhZgNfOTzxt9ME7oeYTbb4/X 3WkITfuXhK1fResScz7j4mpqNf2UKUJCdf2thyMobK+9jzUIzG9rgN46mi6EsquIrB8z vjqQ== X-Forwarded-Encrypted: i=1; AJvYcCW2pHnXdOANA0KD1XH8C+sC20HKPxh6gFGzirRjCh+VrxDTN0whFnd0rUFTWXZcz3F+dcDwc4g7tDZ5HTg=@vger.kernel.org X-Gm-Message-State: AOJu0Yy/Ra5+IANj7FJAH+6KcQtu7eMuEIBGRsosKH1aIu6mjWuSHgw/ 1mrIzZXLLJnV2vqxKbkkhT2PTF4XvpC3Rdx3Be5trplS4bK5W0z3e7PLUvbaq9q8YeUE7wAd5zl 55KN2znoq+OUmadEXtLg6U02mBNtPMWgbwFuk6uOcKJIG1UvoE1k8pTW4DR7UWLcpH3w= X-Gm-Gg: ASbGnctVDij49xbjhpCXMmD6ZWdy9bftsdr3C6joici1Gg+Eqt+fgJjmTGPvKOUm5NN sSUJaM+dHRLyF+aROQdvdWCNqzxZjSyl2t+61nq/4a3rYHTiMLvfyG5zCphmAGP+/lcYHwBU1bf vbr3CVa1jiaPcOTXj1UPD+a0y+ikd6Dz36tgS9vSKgeK9YyoGwxUXhf4rw26FooicqY9zM4zWjQ ACsOnnirH2DUHzci2pCHfKAk1eD+kfy+NqLGwf0bsfe2RFZVtHjrNFNfiv+uM7h9MzG/oN6mBrs FGAgIM8sSSHJ2/kjrtknFOpCg0pfTUp9JB5Hn5yM2lrCrAWrNQOEjT/abdOYaMIOdjw= X-Received: by 2002:a17:902:ea11:b0:242:9bbc:6018 with SMTP id d9443c01a7336-245e051092bmr51315345ad.56.1755622566636; Tue, 19 Aug 2025 09:56:06 -0700 (PDT) X-Google-Smtp-Source: AGHT+IECdBDJr9BaOa9/J98OCpO/ByhVvfRXLinprKgpMUZLUWytix2y9gTMERA8CUJSmYI74CBLNw== X-Received: by 2002:a17:902:ea11:b0:242:9bbc:6018 with SMTP id d9443c01a7336-245e051092bmr51314965ad.56.1755622566169; Tue, 19 Aug 2025 09:56:06 -0700 (PDT) Received: from hu-mojha-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-245ed33aa3esm2273885ad.24.2025.08.19.09.56.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Aug 2025 09:56:05 -0700 (PDT) From: Mukesh Ojha To: Bjorn Andersson , Konrad Dybcio , Vikash Garodia , Dikshita Agarwal , Mauro Carvalho Chehab , Mathieu Poirier Cc: Abhinav Kumar , "Bryan O'Donoghue" , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, linux-remoteproc@vger.kernel.org, Mukesh Ojha Subject: [PATCH v2 11/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux Date: Tue, 19 Aug 2025 22:24:46 +0530 Message-ID: <20250819165447.4149674-12-mukesh.ojha@oss.qualcomm.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com> References: <20250819165447.4149674-1-mukesh.ojha@oss.qualcomm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-ORIG-GUID: 8FY34prqD5-lIMW5CqhXBEZfUkXROJgD X-Proofpoint-GUID: 8FY34prqD5-lIMW5CqhXBEZfUkXROJgD X-Authority-Analysis: v=2.4 cv=IvQecK/g c=1 sm=1 tr=0 ts=68a4aca7 cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=2OwXVqhp2XgA:10 a=COk6AnOGAAAA:8 a=EUspDBNiAAAA:8 a=BWwITLIJPpf_DTsiswIA:9 a=1OuFwYUASf3TG4hYMiVC:22 a=TjNXssC_j7lpFel5tvFf:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwODE4MDE0NyBTYWx0ZWRfX+srdmmMigvEt CsYjCTCBrFBNeNtwjgrX7xbPH2nIOx8oI43Y8Mu5YJ5vTXg/ZOVIJ8gtG1QisFPdXKLyfIa+HjO wUI6oAJAZ9OM32dp5jftMpkg+rLaTzgXXgWfuaV2WM4fMH+eLl/kUMfOQbzpxROddoGZUXqgwY0 LirifSDhCB0s1xIMHEsKlMko/IjIYDfKadtNmt+q+WXE0Qau+gsN0Uxi1U/hRYit7Ak5PdXBh4B 20IImSRsyG4sRswC+ob5CJsz2aSi2XtkfTwPFCyYj0nJ5afMC81SaWTp0NFu3rIVvI4vudgBNVf g8ylWH9hSZrTIPHKylulVknMN4L82rTUxVSCMiIaga3bSY0sw+gQ3Hxq+5SwPpWWN1YEJ4Ls1sK kD44E7kD X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-08-19_02,2025-08-14_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 adultscore=0 malwarescore=0 priorityscore=1501 clxscore=1015 phishscore=0 bulkscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2507300000 definitions=main-2508180147 Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Vikash Garodia Signed-off-by: Mukesh Ojha --- 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/p= latform/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 =3D 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; =20 - ret =3D iris_fw_load(core); + ret =3D iris_fw_init(core); if (ret) goto error_power_off; =20 + ret =3D iris_fw_load(core); + if (ret) + goto error_firmware_deinit; + ret =3D iris_vpu_boot_firmware(core); if (ret) goto error_unload_fw; @@ -83,6 +88,8 @@ int iris_core_init(struct iris_core *core) =20 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/p= latform/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/med= ia/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 res= erved. */ =20 +#include #include -#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include =20 #include "iris_core.h" @@ -17,15 +25,14 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_n= ame) { u32 pas_id =3D core->iris_platform_data->pas_id; + struct qcom_scm_pas_ctx *ctx; const struct firmware *firmware =3D NULL; struct device *dev =3D 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 =3D NULL; + struct device_node *node =3D NULL; + ssize_t fw_size =3D 0; + void *mem_virt =3D NULL; + int ret =3D 0; =20 if (strlen(fw_name) >=3D MAX_FIRMWARE_NAME_SIZE - 4) return -EINVAL; @@ -39,36 +46,64 @@ static int iris_load_fw_to_memory(struct iris_core *cor= e, const char *fw_name) if (!rmem) return -EINVAL; =20 - mem_phys =3D rmem->base; - res_size =3D rmem->size; + if (core->has_iommu) + dev =3D core->fw.dev; =20 + ctx =3D qcom_scm_pas_ctx_init(dev, pas_id, rmem->base, rmem->size, false); + if (!ctx) + return -ENOMEM; + + ctx->has_iommu =3D core->has_iommu; ret =3D request_firmware(&firmware, fw_name, dev); if (ret) return ret; =20 fw_size =3D 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 =3D -EINVAL; goto err_release_fw; } =20 - mem_virt =3D memremap(mem_phys, res_size, MEMREMAP_WC); + mem_virt =3D memremap(rmem->base, rmem->size, MEMREMAP_WC); if (!mem_virt) { ret =3D -ENOMEM; goto err_release_fw; } =20 - ret =3D qcom_mdt_load(dev, firmware, fw_name, - pas_id, mem_virt, mem_phys, res_size, NULL); + ret =3D qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL); if (ret) goto err_mem_unmap; =20 - ret =3D qcom_scm_pas_auth_and_reset(pas_id); + if (core->has_iommu) { + ret =3D 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 =3D qcom_mdt_pas_map_devmem_rscs(ctx, core->fw.iommu_domain, NULL, 0= ); + if (ret) + goto err_unmap_carveout; + } + + ret =3D qcom_scm_pas_prepare_and_auth_reset(ctx); if (ret) - goto err_mem_unmap; + goto err_unmap_devmem_rscs; + + core->fw.ctx =3D ctx; =20 return ret; =20 +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) =20 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 =3D core->fw.ctx; + ret =3D 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; } =20 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 =3D of_get_child_by_name(core->dev->of_node, "video-firmware"); + if (!np) + return 0; + + core->has_iommu =3D true; + memset(&info, 0, sizeof(info)); + info.fwnode =3D &np->fwnode; + info.parent =3D core->dev; + info.name =3D np->name; + info.dma_mask =3D DMA_BIT_MASK(32); + + pdev =3D platform_device_register_full(&info); + if (IS_ERR(pdev)) { + of_node_put(np); + return PTR_ERR(pdev); + } + + pdev->dev.of_node =3D np; + + ret =3D of_dma_configure(&pdev->dev, np, true); + if (ret) { + dev_err(core->dev, "failed to allocate domain\n"); + goto err_unregister; + } + + core->fw.dev =3D &pdev->dev; + + iommu_dom =3D iommu_get_domain_for_dev(core->fw.dev); + if (!iommu_dom) { + dev_err(core->fw.dev, "Failed to get iommu domain\n"); + ret =3D -EINVAL; + goto err_iommu_free; + } + + ret =3D 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 =3D 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 =3D core->fw.iommu_domain; + iommu_detach_device(iommu_dom, core->fw.dev); + iommu_domain_free(iommu_dom); + + core->fw.iommu_domain =3D NULL; + platform_device_unregister(to_platform_device(core->fw.dev)); +} diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/med= ia/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); =20 #endif --=20 2.50.1