All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicolin Chen <nicolinc@nvidia.com>
To: <agross@kernel.org>, <bjorn.andersson@linaro.org>,
	<konrad.dybcio@somainline.org>, <joro@8bytes.org>,
	<will@kernel.org>, <robin.murphy@arm.com>,
	<sricharan@codeaurora.org>
Cc: <jgg@nvidia.com>, <kevin.tian@intel.com>,
	<linux-arm-msm@vger.kernel.org>, <iommu@lists.linux.dev>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH v4 1/6] iommu/msm: Fix error-out routine in msm_iommu_attach_dev()
Date: Wed, 21 Sep 2022 01:22:53 -0700	[thread overview]
Message-ID: <0ec6d333a98bb6a11e254ba49ecb385e50a52588.1663744983.git.nicolinc@nvidia.com> (raw)
In-Reply-To: <cover.1663744983.git.nicolinc@nvidia.com>

The error-out routine is missing all the reverting pieces for the iop and
attached-ctx allocations. And clock enable/disable is unbalanced too.

Fix it by adding __disable_clocks() and calling msm_iommu_detach_dev() at
the end of the msm_iommu_attach_dev() if "ret" is non-zero. Also set the
master->num to 0 in the detach_dev() since attach_dev() would check it.

Fixes: 109bd48ea2e1 ("iommu/msm: Add DT adaptation")
Cc: stable@vger.kernel.org
Cc: Sricharan R <sricharan@codeaurora.org>
Cc: Andy Gross <agross@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Konrad Dybcio <konrad.dybcio@somainline.org>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
 drivers/iommu/msm_iommu.c | 59 +++++++++++++++++++++------------------
 1 file changed, 32 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 6a24aa804ea3..14df722f0060 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -394,6 +394,34 @@ static struct iommu_device *msm_iommu_probe_device(struct device *dev)
 	return &iommu->iommu;
 }
 
+static void msm_iommu_detach_dev(struct iommu_domain *domain,
+				 struct device *dev)
+{
+	struct msm_priv *priv = to_msm_priv(domain);
+	unsigned long flags;
+	struct msm_iommu_dev *iommu;
+	struct msm_iommu_ctx_dev *master;
+	int ret;
+
+	free_io_pgtable_ops(priv->iop);
+
+	spin_lock_irqsave(&msm_iommu_lock, flags);
+	list_for_each_entry(iommu, &priv->list_attached, dom_node) {
+		ret = __enable_clocks(iommu);
+		if (ret)
+			goto fail;
+
+		list_for_each_entry(master, &iommu->ctx_list, list) {
+			msm_iommu_free_ctx(iommu->context_map, master->num);
+			__reset_context(iommu->base, master->num);
+			master->num = 0;
+		}
+		__disable_clocks(iommu);
+	}
+fail:
+	spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
 static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
 	int ret = 0;
@@ -418,6 +446,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			list_for_each_entry(master, &iommu->ctx_list, list) {
 				if (master->num) {
 					dev_err(dev, "domain already attached");
+					__disable_clocks(iommu);
 					ret = -EEXIST;
 					goto fail;
 				}
@@ -425,6 +454,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 					msm_iommu_alloc_ctx(iommu->context_map,
 							    0, iommu->ncb);
 				if (IS_ERR_VALUE(master->num)) {
+					__disable_clocks(iommu);
 					ret = -ENODEV;
 					goto fail;
 				}
@@ -439,37 +469,12 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
 fail:
 	spin_unlock_irqrestore(&msm_iommu_lock, flags);
+	if (ret)
+		msm_iommu_detach_dev(domain, dev);
 
 	return ret;
 }
 
-static void msm_iommu_detach_dev(struct iommu_domain *domain,
-				 struct device *dev)
-{
-	struct msm_priv *priv = to_msm_priv(domain);
-	unsigned long flags;
-	struct msm_iommu_dev *iommu;
-	struct msm_iommu_ctx_dev *master;
-	int ret;
-
-	free_io_pgtable_ops(priv->iop);
-
-	spin_lock_irqsave(&msm_iommu_lock, flags);
-	list_for_each_entry(iommu, &priv->list_attached, dom_node) {
-		ret = __enable_clocks(iommu);
-		if (ret)
-			goto fail;
-
-		list_for_each_entry(master, &iommu->ctx_list, list) {
-			msm_iommu_free_ctx(iommu->context_map, master->num);
-			__reset_context(iommu->base, master->num);
-		}
-		__disable_clocks(iommu);
-	}
-fail:
-	spin_unlock_irqrestore(&msm_iommu_lock, flags);
-}
-
 static int msm_iommu_map(struct iommu_domain *domain, unsigned long iova,
 			 phys_addr_t pa, size_t len, int prot, gfp_t gfp)
 {
-- 
2.17.1


  reply	other threads:[~2022-09-21  8:24 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-21  8:22 [PATCH v4 0/6] Define EINVAL as device/domain incompatibility Nicolin Chen
2022-09-21  8:22 ` Nicolin Chen
2022-09-21  8:22 ` Nicolin Chen [this message]
2022-09-22  8:08   ` [PATCH v4 1/6] iommu/msm: Fix error-out routine in msm_iommu_attach_dev() Tian, Kevin
2022-09-21  8:23 ` [PATCH v4 2/6] iommu/amd: Drop unnecessary checks in amd_iommu_attach_device() Nicolin Chen
2022-09-21  8:23 ` [PATCH v4 3/6] iommu: Add return value rules to attach_dev op and APIs Nicolin Chen
2022-09-21  8:23   ` Nicolin Chen
2022-09-22  2:02   ` Baolu Lu
2022-09-22  2:02     ` Baolu Lu
2022-09-22  5:09     ` Nicolin Chen
2022-09-22  5:09       ` Nicolin Chen
2022-09-22  8:17   ` Tian, Kevin
2022-09-22  8:17     ` Tian, Kevin
2022-09-22  8:17     ` Tian, Kevin
2022-09-22  8:38     ` Nicolin Chen
2022-09-22  8:38       ` Nicolin Chen
2022-09-21  8:23 ` [PATCH v4 4/6] iommu: Regulate EINVAL in ->attach_dev callback functions Nicolin Chen
2022-09-21  8:23   ` Nicolin Chen
2022-09-22  2:14   ` Baolu Lu
2022-09-22  2:14     ` Baolu Lu
2022-09-22  8:18   ` Tian, Kevin
2022-09-22  8:18     ` Tian, Kevin
2022-09-21  8:23 ` [PATCH v4 5/6] iommu: Use EINVAL for incompatible device/domain in ->attach_dev Nicolin Chen
2022-09-21  8:23   ` Nicolin Chen
2022-09-22  2:16   ` Baolu Lu
2022-09-22  2:16     ` Baolu Lu
2022-09-22  8:19   ` Tian, Kevin
2022-09-22  8:19     ` Tian, Kevin
2022-09-22  8:19     ` Tian, Kevin
2022-09-21  8:23 ` [PATCH v4 6/6] iommu: Propagate return value in ->attach_dev callback functions Nicolin Chen
2022-09-21  8:23   ` Nicolin Chen
2022-09-21  8:55 ` [PATCH v4 0/6] Define EINVAL as device/domain incompatibility Jean-Philippe Brucker
2022-09-21  8:55   ` Jean-Philippe Brucker
2022-09-21  8:55   ` Jean-Philippe Brucker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0ec6d333a98bb6a11e254ba49ecb385e50a52588.1663744983.git.nicolinc@nvidia.com \
    --to=nicolinc@nvidia.com \
    --cc=agross@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=konrad.dybcio@somainline.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=sricharan@codeaurora.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.