Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

authored by

Rafael J. Wysocki and committed by
Bjorn Helgaas
a83919e0 1c2042c8

+8
+8
drivers/pci/xen-pcifront.c
··· 471 471 } 472 472 pcifront_init_sd(sd, domain, bus, pdev); 473 473 474 + pci_lock_rescan_remove(); 475 + 474 476 b = pci_scan_bus_parented(&pdev->xdev->dev, bus, 475 477 &pcifront_bus_ops, sd); 476 478 if (!b) { 477 479 dev_err(&pdev->xdev->dev, 478 480 "Error creating PCI Frontend Bus!\n"); 479 481 err = -ENOMEM; 482 + pci_unlock_rescan_remove(); 480 483 goto err_out; 481 484 } 482 485 ··· 497 494 /* Create SysFS and notify udev of the devices. Aka: "going live" */ 498 495 pci_bus_add_devices(b); 499 496 497 + pci_unlock_rescan_remove(); 500 498 return err; 501 499 502 500 err_out: ··· 560 556 561 557 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n"); 562 558 559 + pci_lock_rescan_remove(); 563 560 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) { 564 561 list_del(&bus_entry->list); 565 562 ··· 573 568 574 569 kfree(bus_entry); 575 570 } 571 + pci_unlock_rescan_remove(); 576 572 } 577 573 578 574 static pci_ers_result_t pcifront_common_process(int cmd, ··· 1049 1043 domain, bus, slot, func); 1050 1044 continue; 1051 1045 } 1046 + pci_lock_rescan_remove(); 1052 1047 pci_stop_and_remove_bus_device(pci_dev); 1053 1048 pci_dev_put(pci_dev); 1049 + pci_unlock_rescan_remove(); 1054 1050 1055 1051 dev_dbg(&pdev->xdev->dev, 1056 1052 "PCI device %04x:%02x:%02x.%d removed.\n",