Commit a83919e0 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Bjorn Helgaas

xen/pcifront: Use global PCI rescan-remove locking

Multiple race conditions are possible between the Xen pcifront device
addition and removal and the generic PCI device addition and removal that
can be triggered via sysfs.

To avoid those race conditions make the Xen pcifront code use global PCI
rescan-remove locking.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 1c2042c8
...@@ -471,12 +471,15 @@ static int pcifront_scan_root(struct pcifront_device *pdev, ...@@ -471,12 +471,15 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
} }
pcifront_init_sd(sd, domain, bus, pdev); pcifront_init_sd(sd, domain, bus, pdev);
pci_lock_rescan_remove();
b = pci_scan_bus_parented(&pdev->xdev->dev, bus, b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
&pcifront_bus_ops, sd); &pcifront_bus_ops, sd);
if (!b) { if (!b) {
dev_err(&pdev->xdev->dev, dev_err(&pdev->xdev->dev,
"Error creating PCI Frontend Bus!\n"); "Error creating PCI Frontend Bus!\n");
err = -ENOMEM; err = -ENOMEM;
pci_unlock_rescan_remove();
goto err_out; goto err_out;
} }
...@@ -494,6 +497,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev, ...@@ -494,6 +497,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
/* Create SysFS and notify udev of the devices. Aka: "going live" */ /* Create SysFS and notify udev of the devices. Aka: "going live" */
pci_bus_add_devices(b); pci_bus_add_devices(b);
pci_unlock_rescan_remove();
return err; return err;
err_out: err_out:
...@@ -556,6 +560,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev) ...@@ -556,6 +560,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev)
dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n"); dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
pci_lock_rescan_remove();
list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) { list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
list_del(&bus_entry->list); list_del(&bus_entry->list);
...@@ -568,6 +573,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev) ...@@ -568,6 +573,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev)
kfree(bus_entry); kfree(bus_entry);
} }
pci_unlock_rescan_remove();
} }
static pci_ers_result_t pcifront_common_process(int cmd, static pci_ers_result_t pcifront_common_process(int cmd,
...@@ -1043,8 +1049,10 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) ...@@ -1043,8 +1049,10 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
domain, bus, slot, func); domain, bus, slot, func);
continue; continue;
} }
pci_lock_rescan_remove();
pci_stop_and_remove_bus_device(pci_dev); pci_stop_and_remove_bus_device(pci_dev);
pci_dev_put(pci_dev); pci_dev_put(pci_dev);
pci_unlock_rescan_remove();
dev_dbg(&pdev->xdev->dev, dev_dbg(&pdev->xdev->dev,
"PCI device %04x:%02x:%02x.%d removed.\n", "PCI device %04x:%02x:%02x.%d removed.\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment