[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] [RFC] xen/vpci: modify pci_get_pdev_by_domain() & pci_get_pdev()



pci_get_pdev_by_domain() and pci_get_pdev() functions find the pdev in
the pseg list. If pdev is not in the pseg list, the functions will try
to find the pdev in the next segment. It is not right to find the pdev
in the next segment as this will result in the corruption of another
device in a different segment with the same BDF.

An issue that was observed when implementing the PCI passthrough on ARM.
When we deassign the device from domU guest, the device is assigned
to dom_io and not to dom0, but the tool stack that runs in dom0 will try
to configure the device from dom0. vpci will find the device based on
conversion of GPA to SBDF and will try to find the device in dom0, but
because device is assigned to dom_io, pci_get_pdev_by_domain() will
return pdev with same BDF from next segment.

Signed-off-by: Rahul Singh <rahul.singh@xxxxxxx>
---
 xen/drivers/passthrough/pci.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 938821e593..29356d59a7 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -593,13 +593,10 @@ struct pci_dev *pci_get_pdev(int seg, int bus, int devfn)
             return NULL;
     }
 
-    do {
-        list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-            if ( (pdev->bus == bus || bus == -1) &&
-                 (pdev->devfn == devfn || devfn == -1) )
-                return pdev;
-    } while ( radix_tree_gang_lookup(&pci_segments, (void **)&pseg,
-                                     pseg->nr + 1, 1) );
+    list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
+        if ( (pdev->bus == bus || bus == -1) &&
+             (pdev->devfn == devfn || devfn == -1) )
+            return pdev;
 
     return NULL;
 }
@@ -642,14 +639,11 @@ struct pci_dev *pci_get_pdev_by_domain(const struct 
domain *d, int seg,
             return NULL;
     }
 
-    do {
-        list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-            if ( (pdev->bus == bus || bus == -1) &&
-                 (pdev->devfn == devfn || devfn == -1) &&
-                 (pdev->domain == d) )
-                return pdev;
-    } while ( radix_tree_gang_lookup(&pci_segments, (void **)&pseg,
-                                     pseg->nr + 1, 1) );
+    list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
+        if ( (pdev->bus == bus || bus == -1) &&
+             (pdev->devfn == devfn || devfn == -1) &&
+             (pdev->domain == d) )
+            return pdev;
 
     return NULL;
 }
-- 
2.25.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.