amd iommu: support device add and remove for recent dom0 kernel
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jul 2008 11:46:52 +0000 (12:46 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jul 2008 11:46:52 +0000 (12:46 +0100)
Signed-off-by: Wei Wang <wei.wang2@amd.com>
xen/drivers/passthrough/amd/pci_amd_iommu.c

index cd3ea8e5fc99cb4866d3b9d7cbe987a224423937..4c57af774733778d5597415e951642559ecb79c7 100644 (file)
@@ -620,11 +620,49 @@ static int amd_iommu_return_device(
 
 static int amd_iommu_add_device(struct pci_dev *pdev)
 {
+    struct amd_iommu *iommu;
+    u16 bdf;
+    if ( !pdev->domain )
+        return -EINVAL;
+
+    bdf = (pdev->bus << 8) | pdev->devfn;
+    iommu = (bdf < ivrs_bdf_entries) ?
+    find_iommu_for_device(pdev->bus, pdev->devfn) : NULL;
+
+    if ( !iommu )
+    {
+        amd_iov_error("Fail to find iommu."
+            " %x:%x.%x cannot be assigned to domain %d\n", 
+            pdev->bus, PCI_SLOT(pdev->devfn),
+            PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
+        return -ENODEV;
+    }
+
+    amd_iommu_setup_domain_device(pdev->domain, iommu, bdf);
     return 0;
 }
 
 static int amd_iommu_remove_device(struct pci_dev *pdev)
 {
+    struct amd_iommu *iommu;
+    u16 bdf;
+    if ( !pdev->domain )
+        return -EINVAL;
+
+    bdf = (pdev->bus << 8) | pdev->devfn;
+    iommu = (bdf < ivrs_bdf_entries) ?
+    find_iommu_for_device(pdev->bus, pdev->devfn) : NULL;
+
+    if ( !iommu )
+    {
+        amd_iov_error("Fail to find iommu."
+            " %x:%x.%x cannot be removed from domain %d\n", 
+            pdev->bus, PCI_SLOT(pdev->devfn),
+            PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
+        return -ENODEV;
+    }
+
+    amd_iommu_disable_domain_device(pdev->domain, iommu, bdf);
     return 0;
 }