Linux IOMMU Development
 help / color / mirror / Atom feed
From: Lu Baolu <baolu.lu@linux.intel.com>
To: Joerg Roedel <joro@8bytes.org>
Cc: ZhaoJinming <zhaojinming@uniontech.com>,
	Kevin Tian <kevin.tian@intel.com>,
	Dmitry Antipov <dmantipov@yandex.ru>,
	Guanghui Feng <guanghuifeng@linux.alibaba.com>,
	Li RongQing <lirongqing@baidu.com>,
	Desnes Nunes <desnesn@redhat.com>,
	iommu@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [PATCH v2 17/19] iommu/vt-d: Fix iopf_refcount leak on RID domain replacement
Date: Wed,  5 Aug 2026 07:43:11 +0800	[thread overview]
Message-ID: <20260804234314.3087110-18-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <20260804234314.3087110-1-baolu.lu@linux.intel.com>

intel_iommu_attach_device() enables IOPF for the new domain but never
disables it for the old one.  device_block_translation(), called at the
start of the function, tears down translation but does not touch any IOPF
state; blocking_domain_attach_dev() has to call iopf_for_domain_remove()
explicitly before invoking it for exactly this reason.

identity_domain_attach_dev() has the same problem.  Its comment claims
that no PRI handling is needed because the device has been put in the
blocking state, but the blocking state and the IOPF reference count are
independent of each other.

As a result, replacing a domain that has an iopf_handler with another
domain at RID level leaks a reference in info->iopf_refcount.  The count
never drops back to zero, so iopf_queue_remove_device() is never called
and iommu_disable_pci_pri() triggers its WARN_ON(info->iopf_refcount)
when the device is released.

The PASID paths already handle this correctly by way of
iopf_for_domain_replace(); convert the two RID paths to do the same.
Using the replace helper rather than a bare remove keeps the enable
before the disable, so the reference count does not transiently reach
zero and evict the device from the IOPF queue.

Fixes: 17fce9d2336d ("iommu/vt-d: Put iopf enablement in domain attach path")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260602233426.357499-1-baolu.lu%40linux.intel.com
Assisted-by: Claude:claude-opus-5
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/iommu/intel/iommu.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 000b81cf4a7a..9003783d02bc 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -3152,13 +3152,13 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 	if (ret)
 		return ret;
 
-	ret = iopf_for_domain_set(domain, dev);
+	ret = iopf_for_domain_replace(domain, old, dev);
 	if (ret)
 		return ret;
 
 	ret = dmar_domain_attach_device(to_dmar_domain(domain), dev);
 	if (ret)
-		iopf_for_domain_remove(domain, dev);
+		iopf_for_domain_replace(old, domain, dev);
 
 	return ret;
 }
@@ -3861,10 +3861,13 @@ static int identity_domain_attach_dev(struct iommu_domain *domain,
 		return 0;
 
 	/*
-	 * No PRI support with the global identity domain. No need to enable or
-	 * disable PRI in this path as the iommu has been put in the blocking
-	 * state.
+	 * The identity domain has no iopf_handler, so no IOPF reference is
+	 * taken for it.  The reference held by the old domain must still be
+	 * released here; putting the device in the blocking state above does
+	 * not affect the IOPF reference count.
 	 */
+	iopf_for_domain_remove(old, dev);
+
 	if (sm_supported(iommu))
 		ret = intel_pasid_setup_pass_through(iommu, dev, IOMMU_NO_PASID);
 	else
-- 
2.43.0


  parent reply	other threads:[~2026-08-04 23:55 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-04 23:42 [PATCH v2 00/19][PULL REQUEST] Intel IOMMU updates for v7.3 Lu Baolu
2026-08-04 23:42 ` [PATCH v2 01/19] iommu/vt-d: Fix UCTP context table slot when copying root entries Lu Baolu
2026-08-04 23:42 ` [PATCH v2 02/19] iommu/vt-d: Use logical OR operator for privilege mode check Lu Baolu
2026-08-04 23:42 ` [PATCH v2 03/19] iommu/vt-d: Fix CACHE_TAG_NESTING_DEVTLB polluting shared variables in flush loop Lu Baolu
2026-08-04 23:42 ` [PATCH v2 04/19] iommu/vt-d: Use kstrtoint_from_user() in dmar_perf_latency_write() Lu Baolu
2026-08-04 23:42 ` [PATCH v2 05/19] iommu/vt-d: Fix no_iommu to disable platform opt-in Lu Baolu
2026-08-04 23:43 ` [PATCH v2 06/19] iommu/vt-d: Force requesting ACS when tboot is enabled Lu Baolu
2026-08-04 23:43 ` [PATCH v2 07/19] iommu/vt-d: Remove dead code when CONFIG_INTEL_IOMMU is not set Lu Baolu
2026-08-04 23:43 ` [PATCH v2 08/19] iommu/vt-d: Consolidate dmar policy management and force_on logic Lu Baolu
2026-08-04 23:43 ` [PATCH v2 09/19] iommu/vt-d: Use dmar_can_force_on() for platform opt-in Lu Baolu
2026-08-04 23:43 ` [PATCH v2 10/19] iommu/vt-d: Call dmar_can_force_on() for tboot opt-in Lu Baolu
2026-08-04 23:43 ` [PATCH v2 11/19] iommu/vt-d: Remove the 'force_on' variable Lu Baolu
2026-08-04 23:43 ` [PATCH v2 12/19] iommu/vt-d: Remove dmar_disabled Lu Baolu
2026-08-04 23:43 ` [PATCH v2 13/19] iommu/vt-d: Support the new DMA_REMAP_OPT_OUT flag bit Lu Baolu
2026-08-04 23:43 ` [PATCH v2 14/19] iommu/vt-d: Cache max domain ID to avoid redundant calculation Lu Baolu
2026-08-04 23:43 ` [PATCH v2 15/19] iommu/vt-d: Fix copied_tables bitmap leak on error in copy_translation_tables Lu Baolu
2026-08-04 23:43 ` [PATCH v2 16/19] iommu/vt-d: Clear Present bit before tearing down copied context entry Lu Baolu
2026-08-04 23:43 ` Lu Baolu [this message]
2026-08-04 23:43 ` [PATCH v2 18/19] iommu/vt-d: Tear down scalable-mode context on probe failure Lu Baolu
2026-08-04 23:43 ` [PATCH v2 19/19] iommu/vt-d: Flush context cache with correct SID when tearing down aliases Lu Baolu

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=20260804234314.3087110-18-baolu.lu@linux.intel.com \
    --to=baolu.lu@linux.intel.com \
    --cc=desnesn@redhat.com \
    --cc=dmantipov@yandex.ru \
    --cc=guanghuifeng@linux.alibaba.com \
    --cc=iommu@lists.linux.dev \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lirongqing@baidu.com \
    --cc=zhaojinming@uniontech.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox