On Mon, Apr 08, 2019 at 04:59:33PM -0700, Jacob Pan wrote:
> When Shared Virtual Address (SVA) is enabled for a guest OS via
> vIOMMU, we need to provide invalidation support at IOMMU API and driver
> level. This patch adds Intel VT-d specific function to implement
> iommu passdown invalidate API for shared virtual address.
> 
> The use case is for supporting caching structure invalidation
> of assigned SVM capable devices. Emulated IOMMU exposes queue
> invalidation capability and passes down all descriptors from the guest
> to the physical IOMMU.
> 
> The assumption is that guest to host device ID mapping should be
> resolved prior to calling IOMMU driver. Based on the device handle,
> host IOMMU driver can replace certain fields before submit to the
> invalidation queue.

> +static int intel_iommu_sva_invalidate(struct iommu_domain *domain,
> +             struct device *dev, struct iommu_cache_invalidate_info 
> *inv_info)
> +{
> +     struct dmar_domain *dmar_domain = to_dmar_domain(domain);
> +     struct device_domain_info *info;
> +     struct intel_iommu *iommu;
> +     unsigned long flags;
> +     int cache_type;
> +     u8 bus, devfn;
> +     u16 did, sid;
> +     int ret = 0;
> +     u64 granu;
> +     u64 size;
> +
> +     if (!inv_info || !dmar_domain ||
> +             inv_info->version != IOMMU_CACHE_INVALIDATE_INFO_VERSION_1)
> +             return -EINVAL;
> +
> +     iommu = device_to_iommu(dev, &bus, &devfn);
> +     if (!iommu)
> +             return -ENODEV;
> +

> +     if (!dev || !dev_is_pci(dev))
> +             return -ENODEV;

How dev is used in above call? Can be dev NULL there optional and give non-NULL
iommu?

> +             switch (1 << cache_type) {

BIT() ?

> +             case IOMMU_CACHE_INV_TYPE_IOTLB:
> +                     if (size && (inv_info->addr_info.addr & ((1 << 
> (VTD_PAGE_SHIFT + size)) - 1))) {

BIT() ?

> +                             pr_err("Address out of range, 0x%llx, size 
> order %llu\n",
> +                                     inv_info->addr_info.addr, size);
> +                             ret = -ERANGE;
> +                             goto out_unlock;
> +                     }
> +
> +                     qi_flush_piotlb(iommu, did, 
> mm_to_dma_pfn(inv_info->addr_info.addr),
> +                                     inv_info->addr_info.pasid,
> +                                     size, granu);
> +
> +                     /*
> +                      * Always flush device IOTLB if ATS is enabled since 
> guest
> +                      * vIOMMU exposes CM = 1, no device IOTLB flush will be 
> passed
> +                      * down. REVISIT: cannot assume Linux guest
> +                      */
> +                     if (info->ats_enabled) {
> +                             qi_flush_dev_piotlb(iommu, sid, info->pfsid,
> +                                             inv_info->addr_info.pasid, 
> info->ats_qdep,
> +                                             inv_info->addr_info.addr, size,
> +                                             granu);
> +                     }
> +                     break;
> +             case IOMMU_CACHE_INV_TYPE_DEV_IOTLB:
> +                     if (info->ats_enabled) {
> +                             qi_flush_dev_piotlb(iommu, sid, info->pfsid,
> +                                             inv_info->addr_info.pasid, 
> info->ats_qdep,
> +                                             inv_info->addr_info.addr, size,
> +                                             granu);
> +                     } else
> +                             pr_warn("Passdown device IOTLB flush w/o 
> ATS!\n");
> +
> +                     break;
> +             case IOMMU_CACHE_INV_TYPE_PASID:
> +                     qi_flush_pasid_cache(iommu, did, granu, 
> inv_info->pasid);
> +
> +                     break;
> +             default:
> +                     dev_err(dev, "Unsupported IOMMU invalidation type %d\n",
> +                             cache_type);
> +                     ret = -EINVAL;
> +             }

> +out_unlock:
> +     spin_unlock(&iommu->lock);
> +     spin_unlock_irqrestore(&device_domain_lock, flags);
> +
> +     return ret;
> +}

-- 
With Best Regards,
Andy Shevchenko


_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to