All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Matlack <dmatlack@google.com>
To: iommu@lists.linux.dev, linux-kernel@vger.kernel.org
Cc: Alex Williamson <alex@shazbot.org>,
	Bjorn Helgaas <bhelgaas@google.com>,
	 Jason Gunthorpe <jgg@ziepe.ca>,
	"Joerg Roedel (AMD)" <joro@8bytes.org>,
	Joerg Roedel <joerg.roedel@amd.com>,
	 Kevin Tian <kevin.tian@intel.com>,
	Nicolin Chen <nicolinc@nvidia.com>,
	 Robin Murphy <robin.murphy@arm.com>,
	Will Deacon <will@kernel.org>,
	 David Matlack <dmatlack@google.com>,
	Vipin Sharma <vipinsh@google.com>
Subject: [PATCH] iommu: Introduce reset_mutex to avoid circular locking dependency
Date: Thu, 27 Aug 2026 17:35:11 +0000	[thread overview]
Message-ID: <20260827173511.2322549-1-dmatlack@google.com> (raw)

Introduce a dedicated reset_mutex inside struct iommu_group to serialize
device reset operations and domain resetting state without acquiring
group->mutex.

Commit f5b16b802174 ("PCI: Suspend iommu function prior to resetting a
device") introduced pci_dev_reset_iommu_prepare() and
pci_dev_reset_iommu_done(), which acquire group->mutex during PCI device
resets. In drivers such as VFIO, device reset handlers (e.g.
pci_try_reset_function()) are executed while holding driver locks such
as vdev->memory_lock.

This introduces a circular locking dependency that can lead to tasks
being permanently stuck in a deadlock:

[vdev->memory_lock]  ──────(1. VFIO Reset)──────>  [iommu_group->mutex]
         ▲
         │                                                    │
 (3. VFIO BAR Page Fault)                                    ... [*]
         │                                                    │
         │                                                    │
         └───────────  [mm->mmap_lock]  <─────────────────────┘

Fix this by using group->reset_mutex instead of group->mutex in
pci_dev_reset_iommu_prepare() and pci_dev_reset_iommu_done(). To ensure
other iommu_group operations stay properly synchronized with resets,
also take group->reset_mutex when checking group->recovery_cnt.

[*] The iommu_group->mutex --> mm->mmap_lock dependency was reported as
a transitive chain: iommu_group->mutex --> cpu_hotplug_lock -->
i_mutex_dir_key --> mm->mmap_lock.

Reported-by: Vipin Sharma <vipinsh@google.com>
Closes: https://lore.kernel.org/kvm/20260821193502.92431-1-vipinsh@google.com/
Fixes: f5b16b802174 ("PCI: Suspend iommu function prior to resetting a device")
Signed-off-by: David Matlack <dmatlack@google.com>
---
Cc: Alex Williamson <alex@shazbot.org>

 drivers/iommu/iommu.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index e8f13dcebbde..29e63697211f 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -56,6 +56,7 @@ struct iommu_group {
 	struct list_head devices;
 	struct xarray pasid_array;
 	struct mutex mutex;
+	struct mutex reset_mutex;
 	void *iommu_data;
 	void (*iommu_data_release)(void *iommu_data);
 	char *name;
@@ -1080,6 +1081,7 @@ struct iommu_group *iommu_group_alloc(void)
 
 	group->kobj.kset = iommu_group_kset;
 	mutex_init(&group->mutex);
+	mutex_init(&group->reset_mutex);
 	INIT_LIST_HEAD(&group->devices);
 	INIT_LIST_HEAD(&group->entry);
 	xa_init(&group->pasid_array);
@@ -2476,6 +2478,7 @@ static int __iommu_group_set_domain_internal(struct iommu_group *group,
 	 * pci_dev_reset_iommu_done() attaches the device to group->domain, if
 	 * IOMMU_SET_DOMAIN_MUST_SUCCEED is not set.
 	 */
+	guard(mutex)(&group->reset_mutex);
 	if (group->recovery_cnt && !(flags & IOMMU_SET_DOMAIN_MUST_SUCCEED))
 		return -EBUSY;
 
@@ -3652,6 +3655,7 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
 	 * This is a concurrent attach during device recovery. Reject it until
 	 * pci_dev_reset_iommu_done() attaches the device to group->domain.
 	 */
+	guard(mutex)(&group->reset_mutex);
 	if (group->recovery_cnt) {
 		ret = -EBUSY;
 		goto out_unlock;
@@ -3745,6 +3749,7 @@ int iommu_replace_device_pasid(struct iommu_domain *domain,
 	 * This is a concurrent attach during device recovery. Reject it until
 	 * pci_dev_reset_iommu_done() attaches the device to group->domain.
 	 */
+	guard(mutex)(&group->reset_mutex);
 	if (group->recovery_cnt) {
 		ret = -EBUSY;
 		goto out_unlock;
@@ -4042,7 +4047,7 @@ int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
 	if (!pci_ats_supported(pdev) || !dev_has_iommu(&pdev->dev))
 		return 0;
 
-	guard(mutex)(&group->mutex);
+	guard(mutex)(&group->reset_mutex);
 
 	gdev = __dev_to_gdev(&pdev->dev);
 	if (WARN_ON(!gdev))
@@ -4153,7 +4158,7 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev)
 	if (!pci_ats_supported(pdev) || !dev_has_iommu(&pdev->dev))
 		return;
 
-	guard(mutex)(&group->mutex);
+	guard(mutex)(&group->reset_mutex);
 
 	gdev = __dev_to_gdev(&pdev->dev);
 	if (WARN_ON(!gdev))

base-commit: 37ffa24c9d07edcd414d34283e02af3f3866cf12
-- 
2.55.0.897.gb25b4bd76c-goog


             reply	other threads:[~2026-08-27 17:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27 17:35 David Matlack [this message]
2026-08-27 18:53 ` [PATCH] iommu: Introduce reset_mutex to avoid circular locking dependency David Matlack

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=20260827173511.2322549-1-dmatlack@google.com \
    --to=dmatlack@google.com \
    --cc=alex@shazbot.org \
    --cc=bhelgaas@google.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=joerg.roedel@amd.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nicolinc@nvidia.com \
    --cc=robin.murphy@arm.com \
    --cc=vipinsh@google.com \
    --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.