diff options
| author | Dave Airlie <airlied@redhat.com> | 2024-12-19 11:59:43 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2024-12-19 12:00:02 +1000 |
| commit | 38e961097e04e7adfe1d3335e3371e97c1723064 (patch) | |
| tree | 40ffe2d6d45d668ed42fa28c270760f8967fcfba /drivers/iommu/intel/cache.c | |
| parent | 301e2772295e8de0cf8acdd9ddb1824b546375a5 (diff) | |
| parent | 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8 (diff) | |
Merge tag 'v6.13-rc3' into drm-next
Backmerge linux 6.13-rc3 as amd next has some dependencies on fixes in it.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/iommu/intel/cache.c')
| -rw-r--r-- | drivers/iommu/intel/cache.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/iommu/intel/cache.c b/drivers/iommu/intel/cache.c index e5b89f728ad3..09694cca8752 100644 --- a/drivers/iommu/intel/cache.c +++ b/drivers/iommu/intel/cache.c @@ -105,12 +105,35 @@ static void cache_tag_unassign(struct dmar_domain *domain, u16 did, spin_unlock_irqrestore(&domain->cache_lock, flags); } +/* domain->qi_batch will be freed in iommu_free_domain() path. */ +static int domain_qi_batch_alloc(struct dmar_domain *domain) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&domain->cache_lock, flags); + if (domain->qi_batch) + goto out_unlock; + + domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_ATOMIC); + if (!domain->qi_batch) + ret = -ENOMEM; +out_unlock: + spin_unlock_irqrestore(&domain->cache_lock, flags); + + return ret; +} + static int __cache_tag_assign_domain(struct dmar_domain *domain, u16 did, struct device *dev, ioasid_t pasid) { struct device_domain_info *info = dev_iommu_priv_get(dev); int ret; + ret = domain_qi_batch_alloc(domain); + if (ret) + return ret; + ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_IOTLB); if (ret || !info->ats_enabled) return ret; @@ -139,6 +162,10 @@ static int __cache_tag_assign_parent_domain(struct dmar_domain *domain, u16 did, struct device_domain_info *info = dev_iommu_priv_get(dev); int ret; + ret = domain_qi_batch_alloc(domain); + if (ret) + return ret; + ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_NESTING_IOTLB); if (ret || !info->ats_enabled) return ret; @@ -190,13 +217,6 @@ int cache_tag_assign_domain(struct dmar_domain *domain, u16 did = domain_get_id_for_dev(domain, dev); int ret; - /* domain->qi_bach will be freed in iommu_free_domain() path. */ - if (!domain->qi_batch) { - domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_KERNEL); - if (!domain->qi_batch) - return -ENOMEM; - } - ret = __cache_tag_assign_domain(domain, did, dev, pasid); if (ret || domain->domain.type != IOMMU_DOMAIN_NESTED) return ret; |
