linux/drivers/iommu/intel
Jinhui Guo 9813306610 iommu/vt-d: Flush dev-IOTLB only when PCIe device is accessible in scalable mode
[ Upstream commit 10e60d8781 ]

Commit 4fc82cd907 ("iommu/vt-d: Don't issue ATS Invalidation
request when device is disconnected") relies on
pci_dev_is_disconnected() to skip ATS invalidation for
safely-removed devices, but it does not cover link-down caused
by faults, which can still hard-lock the system.

For example, if a VM fails to connect to the PCIe device,
"virsh destroy" is executed to release resources and isolate
the fault, but a hard-lockup occurs while releasing the group fd.

Call Trace:
 qi_submit_sync
 qi_flush_dev_iotlb
 intel_pasid_tear_down_entry
 device_block_translation
 blocking_domain_attach_dev
 __iommu_attach_device
 __iommu_device_set_domain
 __iommu_group_set_domain_internal
 iommu_detach_group
 vfio_iommu_type1_detach_group
 vfio_group_detach_container
 vfio_group_fops_release
 __fput

Although pci_device_is_present() is slower than
pci_dev_is_disconnected(), it still takes only ~70 µs on a
ConnectX-5 (8 GT/s, x2) and becomes even faster as PCIe speed
and width increase.

Besides, devtlb_invalidation_with_pasid() is called only in the
paths below, which are far less frequent than memory map/unmap.

1. mm-struct release
2. {attach,release}_dev
3. set/remove PASID
4. dirty-tracking setup

The gain in system stability far outweighs the negligible cost
of using pci_device_is_present() instead of pci_dev_is_disconnected()
to decide when to skip ATS invalidation, especially under GDR
high-load conditions.

Fixes: 4fc82cd907 ("iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected")
Cc: stable@vger.kernel.org
Signed-off-by: Jinhui Guo <guojinhui.liam@bytedance.com>
Link: https://lore.kernel.org/r/20251211035946.2071-3-guojinhui.liam@bytedance.com
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2026-03-04 07:21:47 -05:00
..
cache.c iommu/vt-d: Fix qi_batch NULL pointer with nested parent domain 2024-12-19 18:13:06 +01:00
cap_audit.c iommu/vt-d: Remove virtual command interface 2023-03-31 10:03:21 +02:00
cap_audit.h iommu/vt-d: Check FL and SL capability sanity in scalable mode 2021-10-18 12:31:48 +02:00
debugfs.c iommu/vt-d: Replace snprintf with scnprintf in dmar_latency_snapshot() 2025-11-13 15:34:27 -05:00
dmar.c iommu/vt-d: Fix suspicious RCU usage 2025-03-07 18:25:42 +01:00
iommu.c iommu/vt-d: Drain PRQs when domain removed from RID 2026-03-04 07:20:03 -05:00
iommu.h iommu/vt-d: Separate page request queue from SVM 2026-03-04 07:20:03 -05:00
irq_remapping.c x86/msi: Make irq_retrigger() functional for posted MSI 2026-01-08 10:14:31 +01:00
Kconfig dma-mapping: direct calls for dma-iommu 2024-08-22 06:18:11 +02:00
Makefile iommu/vt-d: Separate page request queue from SVM 2026-03-04 07:20:03 -05:00
nested.c iommu/vt-d: Restore context entry setup order for aliased devices 2025-06-27 11:11:21 +01:00
pasid.c iommu/vt-d: Flush dev-IOTLB only when PCIe device is accessible in scalable mode 2026-03-04 07:21:47 -05:00
pasid.h iommu/vt-d: Clear Present bit before tearing down PASID entry 2026-03-04 07:20:04 -05:00
perf.c iommu/vt-d: Replace snprintf with scnprintf in dmar_latency_snapshot() 2025-11-13 15:34:27 -05:00
perf.h iommu/vt-d: Replace snprintf with scnprintf in dmar_latency_snapshot() 2025-11-13 15:34:27 -05:00
perfmon.c iommu/vt-d: Clean up cpumask and hotplug for perfmon 2024-09-10 11:44:13 +02:00
perfmon.h iommu/vt-d: Add IOMMU perfmon support 2023-02-03 11:06:06 +01:00
prq.c iommu/vt-d: Drain PRQs when domain removed from RID 2026-03-04 07:20:03 -05:00
svm.c iommu/vt-d: Separate page request queue from SVM 2026-03-04 07:20:03 -05:00
trace.c iommu/vt-d: Move trace/events/intel_iommu.h under iommu 2022-07-15 10:21:28 +02:00
trace.h tracing/treewide: Remove second parameter of __assign_str() 2024-05-22 20:14:47 -04:00