]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommu/vt-d: Assign devtlb cache tag on ATS enablement
authorLu Baolu <baolu.lu@linux.intel.com>
Sat, 28 Jun 2025 10:03:51 +0000 (18:03 +0800)
committerJoerg Roedel <joerg.roedel@amd.com>
Fri, 4 Jul 2025 08:33:56 +0000 (10:33 +0200)
Commit <4f1492efb495> ("iommu/vt-d: Revert ATS timing change to fix boot
failure") placed the enabling of ATS in the probe_finalize callback. This
occurs after the default domain attachment, which is when the ATS cache
tag is assigned. Consequently, the device TLB cache tag is missed when the
domain is attached, leading to the device TLB not being invalidated in the
iommu_unmap paths.

Fix this by assigning the CACHE_TAG_DEVTLB cache tag when ATS is enabled.

Fixes: 4f1492efb495 ("iommu/vt-d: Revert ATS timing change to fix boot failure")
Cc: stable@vger.kernel.org
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Tested-by: Shuicheng Lin <shuicheng.lin@intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Link: https://lore.kernel.org/r/20250625050135.3129955-1-baolu.lu@linux.intel.com
Link: https://lore.kernel.org/r/20250628100351.3198955-2-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
drivers/iommu/intel/cache.c
drivers/iommu/intel/iommu.c
drivers/iommu/intel/iommu.h

index fc35cba5914532ab45cbee5e91eb5aec8e1a4f6e..47692cbfaabdb35da8c662d390a92cc789a07420 100644 (file)
@@ -40,9 +40,8 @@ static bool cache_tage_match(struct cache_tag *tag, u16 domain_id,
 }
 
 /* Assign a cache tag with specified type to domain. */
-static int cache_tag_assign(struct dmar_domain *domain, u16 did,
-                           struct device *dev, ioasid_t pasid,
-                           enum cache_tag_type type)
+int cache_tag_assign(struct dmar_domain *domain, u16 did, struct device *dev,
+                    ioasid_t pasid, enum cache_tag_type type)
 {
        struct device_domain_info *info = dev_iommu_priv_get(dev);
        struct intel_iommu *iommu = info->iommu;
index 7aa3932251b2fd6d632f5040cac4ba21d474a3f5..148b944143b81ef87b4c6824ab27b69dec99fa68 100644 (file)
@@ -3780,8 +3780,17 @@ static void intel_iommu_probe_finalize(struct device *dev)
            !pci_enable_pasid(to_pci_dev(dev), info->pasid_supported & ~1))
                info->pasid_enabled = 1;
 
-       if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev))
+       if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
                iommu_enable_pci_ats(info);
+               /* Assign a DEVTLB cache tag to the default domain. */
+               if (info->ats_enabled && info->domain) {
+                       u16 did = domain_id_iommu(info->domain, iommu);
+
+                       if (cache_tag_assign(info->domain, did, dev,
+                                            IOMMU_NO_PASID, CACHE_TAG_DEVTLB))
+                               iommu_disable_pci_ats(info);
+               }
+       }
        iommu_enable_pci_pri(info);
 }
 
index 3ddbcc603de23b704fd5c2ac5e5764e802f2a882..2d1afab5eedcc7f1662eb5d9857e1e68bc79f256 100644 (file)
@@ -1289,6 +1289,8 @@ struct cache_tag {
        unsigned int users;
 };
 
+int cache_tag_assign(struct dmar_domain *domain, u16 did, struct device *dev,
+                    ioasid_t pasid, enum cache_tag_type type);
 int cache_tag_assign_domain(struct dmar_domain *domain,
                            struct device *dev, ioasid_t pasid);
 void cache_tag_unassign_domain(struct dmar_domain *domain,