[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 4/4] vpci: resolve possible clash while removing BAR overlaps
From: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> modify_bars checks if the mapping of the BAR memory has already been done when mapping other device's BARs or, while unmapping, are still in use by other devices. With the existing locking scheme it is possible that there are other devices trying to do the same in parallel with us, but on other CPUs as we only hold a read lock without acquiring _pcidevs_lock recursive lock. To prevent that upgrade the read lock to normal pcidevs_lock during BAR overlapping check. Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> --- xen/drivers/vpci/header.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index 75e972740106..c80a8bb5e3e0 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -281,7 +281,11 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_only) /* * Check for overlaps with other BARs. Note that only BARs that are * currently mapped (enabled) are checked for overlaps. + * We are holding pcidevs_read_lock here, but we need to access + * different devices at a time. So, upgrade our current read lock to normal + * pcidevs_lock. */ + pcidevs_lock(); for_each_pdev ( pdev->domain, tmp ) { if ( tmp == pdev ) @@ -321,10 +325,12 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_only) printk(XENLOG_G_WARNING "Failed to remove [%lx, %lx]: %d\n", start, end, rc); rangeset_destroy(mem); + pcidevs_unlock(); return rc; } } } + pcidevs_unlock(); ASSERT(dev); -- 2.25.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |