From: Johan Hovold Date: Mon, 5 Jan 2026 16:22:27 +0000 (-0500) Subject: iommu/qcom: fix device leak on of_xlate() X-Git-Tag: v5.10.248~77 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c104478fc92c21f412ed338bf8d451a3f2f94f0a;p=thirdparty%2Fkernel%2Fstable.git iommu/qcom: fix device leak on of_xlate() [ Upstream commit 6a3908ce56e6879920b44ef136252b2f0c954194 ] Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate(). Note that commit e2eae09939a8 ("iommu/qcom: add missing put_device() call in qcom_iommu_of_xlate()") fixed the leak in a couple of error paths, but the reference is still leaking on success and late failures. Fixes: 0ae349a0f33f ("iommu/qcom: Add qcom_iommu") Cc: stable@vger.kernel.org # 4.14: e2eae09939a8 Cc: Rob Clark Cc: Yu Kuai Acked-by: Robin Murphy Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel [ adapted validation logic from max_asid to num_ctxs ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index 37c8f75a35801..369a34cb75b51 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -586,15 +586,15 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args) qcom_iommu = platform_get_drvdata(iommu_pdev); + put_device(&iommu_pdev->dev); + /* make sure the asid specified in dt is valid, so we don't have * to sanity check this elsewhere, since 'asid - 1' is used to * index into qcom_iommu->ctxs: */ if (WARN_ON(asid < 1) || - WARN_ON(asid > qcom_iommu->num_ctxs)) { - put_device(&iommu_pdev->dev); + WARN_ON(asid > qcom_iommu->num_ctxs)) return -EINVAL; - } if (!dev_iommu_priv_get(dev)) { dev_iommu_priv_set(dev, qcom_iommu); @@ -603,10 +603,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args) * multiple different iommu devices. Multiple context * banks are ok, but multiple devices are not: */ - if (WARN_ON(qcom_iommu != dev_iommu_priv_get(dev))) { - put_device(&iommu_pdev->dev); + if (WARN_ON(qcom_iommu != dev_iommu_priv_get(dev))) return -EINVAL; - } } return iommu_fwspec_add_ids(dev, &asid, 1);