]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/base/dd.c
driver core: Partially revert "driver core: correct device's shutdown order"
[mirror_ubuntu-bionic-kernel.git] / drivers / base / dd.c
index 2c964f56dafe2a98706ca9cd5520e50bacf551f6..0d5ac66d16086a883aa4ad365206263df57fb4d2 100644 (file)
@@ -412,14 +412,6 @@ re_probe:
                        goto probe_failed;
        }
 
-       /*
-        * Ensure devices are listed in devices_kset in correct order
-        * It's important to move Dev to the end of devices_kset before
-        * calling .probe, because it could be recursive and parent Dev
-        * should always go first
-        */
-       devices_kset_move_last(dev);
-
        if (dev->bus->probe) {
                ret = dev->bus->probe(dev);
                if (ret)
@@ -820,6 +812,9 @@ int driver_attach(struct device_driver *drv)
 }
 EXPORT_SYMBOL_GPL(driver_attach);
 
+void *vfio_pci_driver_ptr = (void *)0xdeadfeed;
+EXPORT_SYMBOL(vfio_pci_driver_ptr);
+
 /*
  * __device_release_driver() must be called with @dev lock held.
  * When called for a USB interface, @dev->parent lock must be held as well.
@@ -868,6 +863,18 @@ static void __device_release_driver(struct device *dev, struct device *parent)
                        dev->bus->remove(dev);
                else if (drv->remove)
                        drv->remove(dev);
+               /*
+                * A concurrent invocation of the same function might
+                * have released the driver successfully while this one
+                * was waiting, so check for that.
+                * LP: #1792099
+                *
+                * Limit this to the vfio_pci_driver as some drivers NULL
+                * out this pointer in their remove() function.
+                * LP: #1803942
+                */
+               if (drv == vfio_pci_driver_ptr && dev->driver != drv)
+                       return;
 
                device_links_driver_cleanup(dev);
                dma_deconfigure(dev);