On Tue, 23 Jun 2020 08:43:14 -0700 Jacob Pan <jacob.jun....@linux.intel.com> wrote:
> From: Liu Yi L <yi.l....@intel.com> > > For guest SVA usage, in order to optimize for less VMEXIT, guest > request of IOTLB flush also includes device TLB. > > On the host side, IOMMU driver performs IOTLB and implicit devTLB > invalidation. When PASID-selective granularity is requested by the > guest we need to derive the equivalent address range for devTLB > instead of using the address information in the UAPI data. The reason > for that is, unlike IOTLB flush, devTLB flush does not support > PASID-selective granularity. This is to say, we need to set the > following in the PASID based devTLB invalidation descriptor: > - entire 64 bit range in address ~(0x1 << 63) > - S bit = 1 (VT-d CH 6.5.2.6). > > Without this fix, device TLB flush range is not set properly for PASID > selective granularity. This patch also merged devTLB flush code for > both implicit and explicit cases. > > Fixes: 6ee1b77ba3ac ("iommu/vt-d: Add svm/sva invalidate function") > Signed-off-by: Liu Yi L <yi.l....@intel.com> > Signed-off-by: Jacob Pan <jacob.jun....@linux.intel.com> > --- > drivers/iommu/intel/iommu.c | 25 +++++++++++++++++-------- > 1 file changed, 17 insertions(+), 8 deletions(-) > > diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c > index 96340da57075..5ea5732d5ec4 100644 > --- a/drivers/iommu/intel/iommu.c > +++ b/drivers/iommu/intel/iommu.c > @@ -5408,7 +5408,7 @@ intel_iommu_sva_invalidate(struct iommu_domain > *domain, struct device *dev, sid = PCI_DEVID(bus, devfn); > > /* Size is only valid in address selective invalidation */ > - if (inv_info->granularity != IOMMU_INV_GRANU_PASID) > + if (inv_info->granularity == IOMMU_INV_GRANU_ADDR) > size = to_vtd_size(inv_info->addr_info.granule_size, > inv_info->addr_info.nb_granules); > > @@ -5417,6 +5417,7 @@ intel_iommu_sva_invalidate(struct iommu_domain > *domain, struct device *dev, IOMMU_CACHE_INV_TYPE_NR) { > int granu = 0; > u64 pasid = 0; > + u64 addr = 0; > > granu = to_vtd_granularity(cache_type, > inv_info->granularity); if (granu == -EINVAL) { > @@ -5456,19 +5457,27 @@ intel_iommu_sva_invalidate(struct > iommu_domain *domain, struct device *dev, (granu == > QI_GRAN_NONG_PASID) ? -1 : 1 << size, inv_info->addr_info.flags & > IOMMU_INV_ADDR_FLAGS_LEAF); > + if (!info->ats_enabled) > + break; > /* > * Always flush device IOTLB if ATS is > enabled. vIOMMU > * in the guest may assume IOTLB flush is > inclusive, > * which is more efficient. > */ > - if (info->ats_enabled) > - qi_flush_dev_iotlb_pasid(iommu, sid, > - info->pfsid, pasid, > - info->ats_qdep, > - > inv_info->addr_info.addr, > - size); > - break; > + fallthrough; > case IOMMU_CACHE_INV_TYPE_DEV_IOTLB: > + /* > + * There is no PASID selective flush for > device TLB, so > + * the equivalent of that is we set the size > to be the > + * entire range of 64 bit. User only > provides PASID info > + * without address info. So we set addr to 0. > + */ > + if (inv_info->granularity == > IOMMU_INV_GRANU_PASID) { > + size = 64 - VTD_PAGE_SHIFT; > + addr = 0; > + } else if (inv_info->granularity == > IOMMU_INV_GRANU_ADDR) > + addr = inv_info->addr_info.addr; > + > if (info->ats_enabled) > qi_flush_dev_iotlb_pasid(iommu, sid, > info->pfsid, pasid, addr should be used here. will fix in the next version. Baolu has pointed out this before but missed it here. Jacob _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu