]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/iommu/intel-iommu.c
iommu/vt-d: Fix dev iotlb pfsid use
[linux.git] / drivers / iommu / intel-iommu.c
index 14e4b37224284976a1cb8890e5d13ae5337350cc..497ef94c5a8c1e9ad3a0dc9b8296c5daa46445e2 100644 (file)
@@ -422,6 +422,7 @@ struct device_domain_info {
        struct list_head global; /* link to global list */
        u8 bus;                 /* PCI bus number */
        u8 devfn;               /* PCI devfn number */
+       u16 pfsid;              /* SRIOV physical function source ID */
        u8 pasid_supported:3;
        u8 pasid_enabled:1;
        u8 pri_supported:1;
@@ -1474,6 +1475,20 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info)
                return;
 
        pdev = to_pci_dev(info->dev);
+       /* For IOMMU that supports device IOTLB throttling (DIT), we assign
+        * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
+        * queue depth at PF level. If DIT is not set, PFSID will be treated as
+        * reserved, which should be set to 0.
+        */
+       if (!ecap_dit(info->iommu->ecap))
+               info->pfsid = 0;
+       else {
+               struct pci_dev *pf_pdev;
+
+               /* pdev will be returned if device is not a vf */
+               pf_pdev = pci_physfn(pdev);
+               info->pfsid = PCI_DEVID(pf_pdev->bus->number, pf_pdev->devfn);
+       }
 
 #ifdef CONFIG_INTEL_IOMMU_SVM
        /* The PCIe spec, in its wisdom, declares that the behaviour of
@@ -1539,7 +1554,8 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
 
                sid = info->bus << 8 | info->devfn;
                qdep = info->ats_qdep;
-               qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
+               qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
+                               qdep, addr, mask);
        }
        spin_unlock_irqrestore(&device_domain_lock, flags);
 }