When scanning an already plugged device, the virtual address
of mapped PCI resource in rte_pci_device will be overridden
with 0, that may cause driver does not work correctly.
The fix is not to update any rte_pci_device's field if the being
scanned device's driver is already probed.

Bugzilla ID: 85
Fixes: c752998b5e2e ("pci: introduce library and driver")
Cc: sta...@dpdk.org

Reported-by: Lv Geoffrey <geoffrey...@gmail.com>
Signed-off-by: Qi Zhang <qi.z.zh...@intel.com>
---
 drivers/bus/pci/linux/pci.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index 04648ac93..b94eb7401 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -348,11 +348,35 @@ pci_scan_one(const char *dirname, const struct 
rte_pci_addr *addr)
                        if (ret < 0) {
                                rte_pci_insert_device(dev2, dev);
                        } else { /* already registered */
-                               dev2->kdrv = dev->kdrv;
-                               dev2->max_vfs = dev->max_vfs;
-                               pci_name_set(dev2);
-                               memmove(dev2->mem_resource, dev->mem_resource,
-                                       sizeof(dev->mem_resource));
+                               if (dev2->driver == NULL) {
+                                       dev2->kdrv = dev->kdrv;
+                                       dev2->max_vfs = dev->max_vfs;
+                                       pci_name_set(dev2);
+                                       memmove(dev2->mem_resource,
+                                               dev->mem_resource,
+                                               sizeof(dev->mem_resource));
+                               } else {
+                                       /**
+                                        * If device is plugged and driver is
+                                        * probed already, we don't need to do
+                                        * anything here. (This happens when we
+                                        * call rte_eal_hotplug_add)
+                                        */
+                                       if (dev2->kdrv != dev->kdrv ||
+                                               dev2->max_vfs != dev->max_vfs)
+                                               /*
+                                                * This should not happens.
+                                                * But it is still possible if
+                                                * we unbind a device from
+                                                * vfio or uio before hotplug
+                                                * remove and rebind it with
+                                                * a different configure.
+                                                * So we just print out the
+                                                * error as an alarm.
+                                                */
+                                               RTE_LOG(ERR, EAL, "Unexpected 
device scan at %s!\n",
+                                                       filename);
+                               }
                                free(dev);
                        }
                        return 0;
-- 
2.13.6

Reply via email to