diff options
author | Lu Baolu <baolu.lu@linux.intel.com> | 2024-04-24 09:16:33 +0200 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2024-04-26 11:57:40 +0200 |
commit | 3b1d9e2b2d6856eabf5faa12d20c97fef657999f (patch) | |
tree | 3f8a1683e5eea40ad1df5f3d7d1ce7782967d6ed /drivers/iommu/intel/svm.c | |
parent | iommu/vt-d: Remove caching mode check before device TLB flush (diff) | |
download | linux-3b1d9e2b2d6856eabf5faa12d20c97fef657999f.tar.xz linux-3b1d9e2b2d6856eabf5faa12d20c97fef657999f.zip |
iommu/vt-d: Add cache tag assignment interface
Caching tag is a combination of tags used by the hardware to cache various
translations. Whenever a mapping in a domain is changed, the IOMMU driver
should invalidate the caches with the caching tags. The VT-d specification
describes caching tags in section 6.2.1, Tagging of Cached Translations.
Add interface to assign caching tags to an IOMMU domain when attached to a
RID or PASID, and unassign caching tags when a domain is detached from a
RID or PASID. All caching tags are listed in the per-domain tag list and
are protected by a dedicated lock.
In addition to the basic IOTLB and devTLB caching tag types, NESTING_IOTLB
and NESTING_DEVTLB tag types are also introduced. These tags are used for
caches that store translations for DMA accesses through a nested user
domain. They are affected by changes to mappings in the parent domain.
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Link: https://lore.kernel.org/r/20240416080656.60968-2-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/intel/svm.c')
-rw-r--r-- | drivers/iommu/intel/svm.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index e05c6c4cb8c3..2e627fbd5adb 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -366,17 +366,23 @@ static int intel_svm_set_dev_pasid(struct iommu_domain *domain, sdev->qdep = 0; } + ret = cache_tag_assign_domain(to_dmar_domain(domain), dev, pasid); + if (ret) + goto free_sdev; + /* Setup the pasid table: */ sflags = cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0; ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, pasid, FLPT_DEFAULT_DID, sflags); if (ret) - goto free_sdev; + goto unassign_tag; list_add_rcu(&sdev->list, &svm->devs); return 0; +unassign_tag: + cache_tag_unassign_domain(to_dmar_domain(domain), dev, pasid); free_sdev: kfree(sdev); free_svm: @@ -741,6 +747,8 @@ struct iommu_domain *intel_svm_domain_alloc(void) if (!domain) return NULL; domain->domain.ops = &intel_svm_domain_ops; + INIT_LIST_HEAD(&domain->cache_tags); + spin_lock_init(&domain->cache_lock); return &domain->domain; } |