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 19/19] iommu/vt-d: Flush context cache with correct SID when tearing down aliases
Date: Wed,  5 Aug 2026 07:43:13 +0800	[thread overview]
Message-ID: <20260804234314.3087110-20-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <20260804234314.3087110-1-baolu.lu@linux.intel.com>

domain_context_clear_one() and device_pasid_table_teardown() are both
invoked once per DMA alias of a device. Each function locates the context
entry using the bus/devfn pair provided by the pci_for_each_dma_alias()
callback, then calls intel_context_flush_no_pasid(), which constructs a
device-selective context-cache invalidation from info->bus and
info->devfn (that is, always the requester ID of the device itself).

As a result, for every alias other than the device’s own RID, the context
entry that was just cleared in memory is never invalidated in the context
cache. Hardware may continue using that stale cached entry. In the
scalable-mode teardown path, intel_pasid_free_table() can then free the
PASID directory still referenced by that stale entry, allowing the IOMMU
to walk freed memory.

Fix this by passing the source ID of the entry being torn down to
intel_context_flush_no_pasid(), instead of deriving it from @info.

Fixes: f90584f4beb84 ("iommu/vt-d: Add helper to flush caches for context change")
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>
Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
---
 drivers/iommu/intel/iommu.h | 2 +-
 drivers/iommu/intel/iommu.c | 2 +-
 drivers/iommu/intel/pasid.c | 9 ++++++---
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index c00f44db0020..23dbe6c24439 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1241,7 +1241,7 @@ void cache_tag_flush_range_np(struct dmar_domain *domain, unsigned long start,
 			      unsigned long end);
 
 void intel_context_flush_no_pasid(struct device_domain_info *info,
-				  struct context_entry *context, u16 did);
+				  struct context_entry *context, u16 did, u16 sid);
 
 int intel_iommu_enable_prq(struct intel_iommu *iommu);
 int intel_iommu_finish_prq(struct intel_iommu *iommu);
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 489bab4999fb..6d81644c66bc 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1251,7 +1251,7 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8
 	context_clear_present(context);
 	__iommu_flush_cache(iommu, context, sizeof(*context));
 	spin_unlock(&iommu->lock);
-	intel_context_flush_no_pasid(info, context, did);
+	intel_context_flush_no_pasid(info, context, did, PCI_DEVID(bus, devfn));
 	context_clear_entry(context);
 	__iommu_flush_cache(iommu, context, sizeof(*context));
 }
diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index 81353fd46b37..e4f24d3f19a6 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -751,7 +751,7 @@ static void device_pasid_table_teardown(struct device *dev, u8 bus, u8 devfn)
 	context_clear_present(context);
 	__iommu_flush_cache(iommu, context, sizeof(*context));
 	spin_unlock(&iommu->lock);
-	intel_context_flush_no_pasid(info, context, did);
+	intel_context_flush_no_pasid(info, context, did, PCI_DEVID(bus, devfn));
 	context_clear_entry(context);
 	__iommu_flush_cache(iommu, context, sizeof(*context));
 }
@@ -955,9 +955,12 @@ static void __context_flush_dev_iotlb(struct device_domain_info *info)
  * This helper can only be used when IOMMU is working in the legacy mode or
  * IOMMU is in scalable mode but all PASID table entries of the device are
  * non-present.
+ *
+ * @sid identifies the context entry that was modified, which may be a DMA
+ * alias of @info->dev rather than its own requester ID.
  */
 void intel_context_flush_no_pasid(struct device_domain_info *info,
-				  struct context_entry *context, u16 did)
+				  struct context_entry *context, u16 did, u16 sid)
 {
 	struct intel_iommu *iommu = info->iommu;
 
@@ -967,7 +970,7 @@ void intel_context_flush_no_pasid(struct device_domain_info *info,
 	 * when operating in scalable mode. Therefore the @did value doesn't
 	 * matter in scalable mode.
 	 */
-	iommu->flush.flush_context(iommu, did, PCI_DEVID(info->bus, info->devfn),
+	iommu->flush.flush_context(iommu, did, sid,
 				   DMA_CCMD_MASK_NOBIT, DMA_CCMD_DEVICE_INVL);
 
 	/*
-- 
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 ` [PATCH v2 17/19] iommu/vt-d: Fix iopf_refcount leak on RID domain replacement Lu Baolu
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 ` Lu Baolu [this message]

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-20-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