diff options
author | Jakub Kicinski <kuba@kernel.org> | 2021-02-03 01:21:31 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2021-02-03 01:21:31 +0300 |
commit | d1e1355aefcc0cbda750a8931e93e1e04a5b0b6a (patch) | |
tree | f43b81751cb5c5736268057ecdbcdb99dd00e826 /drivers/iommu/intel/iommu.c | |
parent | 9ae4bdc6e4c1281ddf8d6335bea35864d086cbf9 (diff) | |
parent | 3aaf0a27ffc29b19a62314edd684b9bc6346f9a8 (diff) | |
download | linux-d1e1355aefcc0cbda750a8931e93e1e04a5b0b6a.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/iommu/intel/iommu.c')
-rw-r--r-- | drivers/iommu/intel/iommu.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index f665322a0991..06b00b5363d8 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -5440,6 +5440,36 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain, return ret; } +static bool domain_use_flush_queue(void) +{ + struct dmar_drhd_unit *drhd; + struct intel_iommu *iommu; + bool r = true; + + if (intel_iommu_strict) + return false; + + /* + * The flush queue implementation does not perform page-selective + * invalidations that are required for efficient TLB flushes in virtual + * environments. The benefit of batching is likely to be much lower than + * the overhead of synchronizing the virtual and physical IOMMU + * page-tables. + */ + rcu_read_lock(); + for_each_active_iommu(iommu, drhd) { + if (!cap_caching_mode(iommu->cap)) + continue; + + pr_warn_once("IOMMU batching is disabled due to virtualization"); + r = false; + break; + } + rcu_read_unlock(); + + return r; +} + static int intel_iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) @@ -5450,7 +5480,7 @@ intel_iommu_domain_get_attr(struct iommu_domain *domain, case IOMMU_DOMAIN_DMA: switch (attr) { case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE: - *(int *)data = !intel_iommu_strict; + *(int *)data = domain_use_flush_queue(); return 0; default: return -ENODEV; |