Skip to content

Commit 5e54e86

Browse files
yiliu1765joergroedel
authored andcommitted
iommu/vt-d: Add missing device iotlb flush for parent domain
ATS-capable devices cache the result of nested translation. This result relies on the mappings in s2 domain (a.k.a. parent). When there are modifications in the s2 domain, the related nested translation caches on the device should be flushed. This includes the devices that are attached to the s1 domain. However, the existing code ignores this fact to only loops its own devices. As there is no easy way to identify the exact set of nested translations affected by the change of s2 domain. So, this just flushes the entire device iotlb on the device. As above, driver loops the s2 domain's s1_domains list and loops the devices list of each s1_domain to flush the entire device iotlb on the devices. Fixes: b41e38e ("iommu/vt-d: Add nested domain allocation") Signed-off-by: Yi Liu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 29e1048 commit 5e54e86

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,12 +1461,30 @@ static void parent_domain_flush(struct dmar_domain *domain,
14611461

14621462
spin_lock(&domain->s1_lock);
14631463
list_for_each_entry(s1_domain, &domain->s1_domains, s2_link) {
1464+
struct device_domain_info *device_info;
14641465
struct iommu_domain_info *info;
1466+
unsigned long flags;
14651467
unsigned long i;
14661468

14671469
xa_for_each(&s1_domain->iommu_array, i, info)
14681470
__iommu_flush_iotlb_psi(info->iommu, info->did,
14691471
pfn, pages, ih);
1472+
1473+
if (!s1_domain->has_iotlb_device)
1474+
continue;
1475+
1476+
spin_lock_irqsave(&s1_domain->lock, flags);
1477+
list_for_each_entry(device_info, &s1_domain->devices, link)
1478+
/*
1479+
* Address translation cache in device side caches the
1480+
* result of nested translation. There is no easy way
1481+
* to identify the exact set of nested translations
1482+
* affected by a change in S2. So just flush the entire
1483+
* device cache.
1484+
*/
1485+
__iommu_flush_dev_iotlb(device_info, 0,
1486+
MAX_AGAW_PFN_WIDTH);
1487+
spin_unlock_irqrestore(&s1_domain->lock, flags);
14701488
}
14711489
spin_unlock(&domain->s1_lock);
14721490
}

0 commit comments

Comments
 (0)