aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 21:15:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 21:15:33 -0500
commit9d050966e2eb37a643ac15904b6a8fda7fcfabe9 (patch)
treef3a6f9cc93f6dde2e0cd6f4114b8258afb596bc1 /drivers/xen
parentc0222ac086669a631814bbf857f8c8023452a4d7 (diff)
parent4ef8e3f3504808621e594f01852476a1d4e7ef93 (diff)
Merge tag 'stable/for-linus-3.19-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen features and fixes from David Vrabel: - Fully support non-coherent devices on ARM by introducing the mechanisms to request the hypervisor to perform the required cache maintainance operations. - A number of pciback bug fixes and cleanups. Notably a deadlock fix if a PCI device was manually uunbound and a fix for incorrectly restoring state after a function reset. - In x86 PVHVM guests, use the APIC for interrupts if this has been virtualized by the hardware. This reduces the number of interrupt- related VM exits on such hardware. * tag 'stable/for-linus-3.19-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: (26 commits) Revert "swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single" xen/pci: Use APIC directly when APIC virtualization hardware is available xen/pci: Defer initialization of MSI ops on HVM guests xen-pciback: drop SR-IOV VFs when PF driver unloads xen/pciback: Restore configuration space when detaching from a guest. PCI: Expose pci_load_saved_state for public consumption. xen/pciback: Remove tons of dereferences xen/pciback: Print out the domain owning the device. xen/pciback: Include the domain id if removing the device whilst still in use driver core: Provide an wrapper around the mutex to do lockdep warnings xen/pciback: Don't deadlock when unbinding. swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single swiotlb-xen: call xen_dma_sync_single_for_device when appropriate swiotlb-xen: remove BUG_ON in xen_bus_to_phys swiotlb-xen: pass dev_addr to xen_dma_unmap_page and xen_dma_sync_single_for_cpu xen/arm: introduce GNTTABOP_cache_flush xen/arm/arm64: introduce xen_arch_need_swiotlb xen/arm/arm64: merge xen/mm32.c into xen/mm.c xen/arm: use hypercall to flush caches in map_page xen: add a dma_addr_t dev_addr argument to xen_dma_map_page ...
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/swiotlb-xen.c19
-rw-r--r--drivers/xen/xen-pciback/passthrough.c14
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c112
-rw-r--r--drivers/xen/xen-pciback/pciback.h7
-rw-r--r--drivers/xen/xen-pciback/vpci.c14
-rw-r--r--drivers/xen/xen-pciback/xenbus.c4
6 files changed, 130 insertions, 40 deletions
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index ebd8f218a788..810ad419e34c 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -96,8 +96,6 @@ static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
96 dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT; 96 dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT;
97 phys_addr_t paddr = dma; 97 phys_addr_t paddr = dma;
98 98
99 BUG_ON(paddr != dma); /* truncation has occurred, should never happen */
100
101 paddr |= baddr & ~PAGE_MASK; 99 paddr |= baddr & ~PAGE_MASK;
102 100
103 return paddr; 101 return paddr;
@@ -399,11 +397,13 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
399 * buffering it. 397 * buffering it.
400 */ 398 */
401 if (dma_capable(dev, dev_addr, size) && 399 if (dma_capable(dev, dev_addr, size) &&
402 !range_straddles_page_boundary(phys, size) && !swiotlb_force) { 400 !range_straddles_page_boundary(phys, size) &&
401 !xen_arch_need_swiotlb(dev, PFN_DOWN(phys), PFN_DOWN(dev_addr)) &&
402 !swiotlb_force) {
403 /* we are not interested in the dma_addr returned by 403 /* we are not interested in the dma_addr returned by
404 * xen_dma_map_page, only in the potential cache flushes executed 404 * xen_dma_map_page, only in the potential cache flushes executed
405 * by the function. */ 405 * by the function. */
406 xen_dma_map_page(dev, page, offset, size, dir, attrs); 406 xen_dma_map_page(dev, page, dev_addr, offset, size, dir, attrs);
407 return dev_addr; 407 return dev_addr;
408 } 408 }
409 409
@@ -417,7 +417,7 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
417 return DMA_ERROR_CODE; 417 return DMA_ERROR_CODE;
418 418
419 xen_dma_map_page(dev, pfn_to_page(map >> PAGE_SHIFT), 419 xen_dma_map_page(dev, pfn_to_page(map >> PAGE_SHIFT),
420 map & ~PAGE_MASK, size, dir, attrs); 420 dev_addr, map & ~PAGE_MASK, size, dir, attrs);
421 dev_addr = xen_phys_to_bus(map); 421 dev_addr = xen_phys_to_bus(map);
422 422
423 /* 423 /*
@@ -447,7 +447,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
447 447
448 BUG_ON(dir == DMA_NONE); 448 BUG_ON(dir == DMA_NONE);
449 449
450 xen_dma_unmap_page(hwdev, paddr, size, dir, attrs); 450 xen_dma_unmap_page(hwdev, dev_addr, size, dir, attrs);
451 451
452 /* NOTE: We use dev_addr here, not paddr! */ 452 /* NOTE: We use dev_addr here, not paddr! */
453 if (is_xen_swiotlb_buffer(dev_addr)) { 453 if (is_xen_swiotlb_buffer(dev_addr)) {
@@ -495,14 +495,14 @@ xen_swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
495 BUG_ON(dir == DMA_NONE); 495 BUG_ON(dir == DMA_NONE);
496 496
497 if (target == SYNC_FOR_CPU) 497 if (target == SYNC_FOR_CPU)
498 xen_dma_sync_single_for_cpu(hwdev, paddr, size, dir); 498 xen_dma_sync_single_for_cpu(hwdev, dev_addr, size, dir);
499 499
500 /* NOTE: We use dev_addr here, not paddr! */ 500 /* NOTE: We use dev_addr here, not paddr! */
501 if (is_xen_swiotlb_buffer(dev_addr)) 501 if (is_xen_swiotlb_buffer(dev_addr))
502 swiotlb_tbl_sync_single(hwdev, paddr, size, dir, target); 502 swiotlb_tbl_sync_single(hwdev, paddr, size, dir, target);
503 503
504 if (target == SYNC_FOR_DEVICE) 504 if (target == SYNC_FOR_DEVICE)
505 xen_dma_sync_single_for_cpu(hwdev, paddr, size, dir); 505 xen_dma_sync_single_for_device(hwdev, dev_addr, size, dir);
506 506
507 if (dir != DMA_FROM_DEVICE) 507 if (dir != DMA_FROM_DEVICE)
508 return; 508 return;
@@ -557,6 +557,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
557 dma_addr_t dev_addr = xen_phys_to_bus(paddr); 557 dma_addr_t dev_addr = xen_phys_to_bus(paddr);
558 558
559 if (swiotlb_force || 559 if (swiotlb_force ||
560 xen_arch_need_swiotlb(hwdev, PFN_DOWN(paddr), PFN_DOWN(dev_addr)) ||
560 !dma_capable(hwdev, dev_addr, sg->length) || 561 !dma_capable(hwdev, dev_addr, sg->length) ||
561 range_straddles_page_boundary(paddr, sg->length)) { 562 range_straddles_page_boundary(paddr, sg->length)) {
562 phys_addr_t map = swiotlb_tbl_map_single(hwdev, 563 phys_addr_t map = swiotlb_tbl_map_single(hwdev,
@@ -574,6 +575,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
574 return 0; 575 return 0;
575 } 576 }
576 xen_dma_map_page(hwdev, pfn_to_page(map >> PAGE_SHIFT), 577 xen_dma_map_page(hwdev, pfn_to_page(map >> PAGE_SHIFT),
578 dev_addr,
577 map & ~PAGE_MASK, 579 map & ~PAGE_MASK,
578 sg->length, 580 sg->length,
579 dir, 581 dir,
@@ -584,6 +586,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
584 * xen_dma_map_page, only in the potential cache flushes executed 586 * xen_dma_map_page, only in the potential cache flushes executed
585 * by the function. */ 587 * by the function. */
586 xen_dma_map_page(hwdev, pfn_to_page(paddr >> PAGE_SHIFT), 588 xen_dma_map_page(hwdev, pfn_to_page(paddr >> PAGE_SHIFT),
589 dev_addr,
587 paddr & ~PAGE_MASK, 590 paddr & ~PAGE_MASK,
588 sg->length, 591 sg->length,
589 dir, 592 dir,
diff --git a/drivers/xen/xen-pciback/passthrough.c b/drivers/xen/xen-pciback/passthrough.c
index 828dddc360df..f16a30e2a110 100644
--- a/drivers/xen/xen-pciback/passthrough.c
+++ b/drivers/xen/xen-pciback/passthrough.c
@@ -69,7 +69,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
69} 69}
70 70
71static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, 71static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
72 struct pci_dev *dev) 72 struct pci_dev *dev, bool lock)
73{ 73{
74 struct passthrough_dev_data *dev_data = pdev->pci_dev_data; 74 struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
75 struct pci_dev_entry *dev_entry, *t; 75 struct pci_dev_entry *dev_entry, *t;
@@ -87,8 +87,13 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
87 87
88 mutex_unlock(&dev_data->lock); 88 mutex_unlock(&dev_data->lock);
89 89
90 if (found_dev) 90 if (found_dev) {
91 if (lock)
92 device_lock(&found_dev->dev);
91 pcistub_put_pci_dev(found_dev); 93 pcistub_put_pci_dev(found_dev);
94 if (lock)
95 device_unlock(&found_dev->dev);
96 }
92} 97}
93 98
94static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev) 99static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
@@ -156,8 +161,11 @@ static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
156 struct pci_dev_entry *dev_entry, *t; 161 struct pci_dev_entry *dev_entry, *t;
157 162
158 list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) { 163 list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
164 struct pci_dev *dev = dev_entry->dev;
159 list_del(&dev_entry->list); 165 list_del(&dev_entry->list);
160 pcistub_put_pci_dev(dev_entry->dev); 166 device_lock(&dev->dev);
167 pcistub_put_pci_dev(dev);
168 device_unlock(&dev->dev);
161 kfree(dev_entry); 169 kfree(dev_entry);
162 } 170 }
163 171
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 017069a455d4..cc3cbb4435f8 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -105,7 +105,7 @@ static void pcistub_device_release(struct kref *kref)
105 */ 105 */
106 __pci_reset_function_locked(dev); 106 __pci_reset_function_locked(dev);
107 if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state)) 107 if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state))
108 dev_dbg(&dev->dev, "Could not reload PCI state\n"); 108 dev_info(&dev->dev, "Could not reload PCI state\n");
109 else 109 else
110 pci_restore_state(dev); 110 pci_restore_state(dev);
111 111
@@ -250,11 +250,15 @@ struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev,
250 * - 'echo BDF > unbind' with a guest still using it. See pcistub_remove 250 * - 'echo BDF > unbind' with a guest still using it. See pcistub_remove
251 * 251 *
252 * As such we have to be careful. 252 * As such we have to be careful.
253 *
254 * To make this easier, the caller has to hold the device lock.
253 */ 255 */
254void pcistub_put_pci_dev(struct pci_dev *dev) 256void pcistub_put_pci_dev(struct pci_dev *dev)
255{ 257{
256 struct pcistub_device *psdev, *found_psdev = NULL; 258 struct pcistub_device *psdev, *found_psdev = NULL;
257 unsigned long flags; 259 unsigned long flags;
260 struct xen_pcibk_dev_data *dev_data;
261 int ret;
258 262
259 spin_lock_irqsave(&pcistub_devices_lock, flags); 263 spin_lock_irqsave(&pcistub_devices_lock, flags);
260 264
@@ -276,13 +280,20 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
276 /* Cleanup our device 280 /* Cleanup our device
277 * (so it's ready for the next domain) 281 * (so it's ready for the next domain)
278 */ 282 */
283 device_lock_assert(&dev->dev);
284 __pci_reset_function_locked(dev);
279 285
280 /* This is OK - we are running from workqueue context 286 dev_data = pci_get_drvdata(dev);
281 * and want to inhibit the user from fiddling with 'reset' 287 ret = pci_load_saved_state(dev, dev_data->pci_saved_state);
282 */ 288 if (!ret) {
283 pci_reset_function(dev); 289 /*
284 pci_restore_state(dev); 290 * The usual sequence is pci_save_state & pci_restore_state
285 291 * but the guest might have messed the configuration space up.
292 * Use the initial version (when device was bound to us).
293 */
294 pci_restore_state(dev);
295 } else
296 dev_info(&dev->dev, "Could not reload PCI state\n");
286 /* This disables the device. */ 297 /* This disables the device. */
287 xen_pcibk_reset_device(dev); 298 xen_pcibk_reset_device(dev);
288 299
@@ -554,12 +565,14 @@ static void pcistub_remove(struct pci_dev *dev)
554 spin_unlock_irqrestore(&pcistub_devices_lock, flags); 565 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
555 566
556 if (found_psdev) { 567 if (found_psdev) {
557 dev_dbg(&dev->dev, "found device to remove - in use? %p\n", 568 dev_dbg(&dev->dev, "found device to remove %s\n",
558 found_psdev->pdev); 569 found_psdev->pdev ? "- in-use" : "");
559 570
560 if (found_psdev->pdev) { 571 if (found_psdev->pdev) {
561 pr_warn("****** removing device %s while still in-use! ******\n", 572 int domid = xen_find_device_domain_owner(dev);
562 pci_name(found_psdev->dev)); 573
574 pr_warn("****** removing device %s while still in-use by domain %d! ******\n",
575 pci_name(found_psdev->dev), domid);
563 pr_warn("****** driver domain may still access this device's i/o resources!\n"); 576 pr_warn("****** driver domain may still access this device's i/o resources!\n");
564 pr_warn("****** shutdown driver domain before binding device\n"); 577 pr_warn("****** shutdown driver domain before binding device\n");
565 pr_warn("****** to other drivers or domains\n"); 578 pr_warn("****** to other drivers or domains\n");
@@ -567,7 +580,8 @@ static void pcistub_remove(struct pci_dev *dev)
567 /* N.B. This ends up calling pcistub_put_pci_dev which ends up 580 /* N.B. This ends up calling pcistub_put_pci_dev which ends up
568 * doing the FLR. */ 581 * doing the FLR. */
569 xen_pcibk_release_pci_dev(found_psdev->pdev, 582 xen_pcibk_release_pci_dev(found_psdev->pdev,
570 found_psdev->dev); 583 found_psdev->dev,
584 false /* caller holds the lock. */);
571 } 585 }
572 586
573 spin_lock_irqsave(&pcistub_devices_lock, flags); 587 spin_lock_irqsave(&pcistub_devices_lock, flags);
@@ -629,10 +643,12 @@ static pci_ers_result_t common_process(struct pcistub_device *psdev,
629{ 643{
630 pci_ers_result_t res = result; 644 pci_ers_result_t res = result;
631 struct xen_pcie_aer_op *aer_op; 645 struct xen_pcie_aer_op *aer_op;
646 struct xen_pcibk_device *pdev = psdev->pdev;
647 struct xen_pci_sharedinfo *sh_info = pdev->sh_info;
632 int ret; 648 int ret;
633 649
634 /*with PV AER drivers*/ 650 /*with PV AER drivers*/
635 aer_op = &(psdev->pdev->sh_info->aer_op); 651 aer_op = &(sh_info->aer_op);
636 aer_op->cmd = aer_cmd ; 652 aer_op->cmd = aer_cmd ;
637 /*useful for error_detected callback*/ 653 /*useful for error_detected callback*/
638 aer_op->err = state; 654 aer_op->err = state;
@@ -653,36 +669,36 @@ static pci_ers_result_t common_process(struct pcistub_device *psdev,
653 * this flag to judge whether we need to check pci-front give aer 669 * this flag to judge whether we need to check pci-front give aer
654 * service ack signal 670 * service ack signal
655 */ 671 */
656 set_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags); 672 set_bit(_PCIB_op_pending, (unsigned long *)&pdev->flags);
657 673
658 /*It is possible that a pcifront conf_read_write ops request invokes 674 /*It is possible that a pcifront conf_read_write ops request invokes
659 * the callback which cause the spurious execution of wake_up. 675 * the callback which cause the spurious execution of wake_up.
660 * Yet it is harmless and better than a spinlock here 676 * Yet it is harmless and better than a spinlock here
661 */ 677 */
662 set_bit(_XEN_PCIB_active, 678 set_bit(_XEN_PCIB_active,
663 (unsigned long *)&psdev->pdev->sh_info->flags); 679 (unsigned long *)&sh_info->flags);
664 wmb(); 680 wmb();
665 notify_remote_via_irq(psdev->pdev->evtchn_irq); 681 notify_remote_via_irq(pdev->evtchn_irq);
666 682
667 ret = wait_event_timeout(xen_pcibk_aer_wait_queue, 683 ret = wait_event_timeout(xen_pcibk_aer_wait_queue,
668 !(test_bit(_XEN_PCIB_active, (unsigned long *) 684 !(test_bit(_XEN_PCIB_active, (unsigned long *)
669 &psdev->pdev->sh_info->flags)), 300*HZ); 685 &sh_info->flags)), 300*HZ);
670 686
671 if (!ret) { 687 if (!ret) {
672 if (test_bit(_XEN_PCIB_active, 688 if (test_bit(_XEN_PCIB_active,
673 (unsigned long *)&psdev->pdev->sh_info->flags)) { 689 (unsigned long *)&sh_info->flags)) {
674 dev_err(&psdev->dev->dev, 690 dev_err(&psdev->dev->dev,
675 "pcifront aer process not responding!\n"); 691 "pcifront aer process not responding!\n");
676 clear_bit(_XEN_PCIB_active, 692 clear_bit(_XEN_PCIB_active,
677 (unsigned long *)&psdev->pdev->sh_info->flags); 693 (unsigned long *)&sh_info->flags);
678 aer_op->err = PCI_ERS_RESULT_NONE; 694 aer_op->err = PCI_ERS_RESULT_NONE;
679 return res; 695 return res;
680 } 696 }
681 } 697 }
682 clear_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags); 698 clear_bit(_PCIB_op_pending, (unsigned long *)&pdev->flags);
683 699
684 if (test_bit(_XEN_PCIF_active, 700 if (test_bit(_XEN_PCIF_active,
685 (unsigned long *)&psdev->pdev->sh_info->flags)) { 701 (unsigned long *)&sh_info->flags)) {
686 dev_dbg(&psdev->dev->dev, 702 dev_dbg(&psdev->dev->dev,
687 "schedule pci_conf service in " DRV_NAME "\n"); 703 "schedule pci_conf service in " DRV_NAME "\n");
688 xen_pcibk_test_and_schedule_op(psdev->pdev); 704 xen_pcibk_test_and_schedule_op(psdev->pdev);
@@ -1502,6 +1518,53 @@ parse_error:
1502fs_initcall(pcistub_init); 1518fs_initcall(pcistub_init);
1503#endif 1519#endif
1504 1520
1521#ifdef CONFIG_PCI_IOV
1522static struct pcistub_device *find_vfs(const struct pci_dev *pdev)
1523{
1524 struct pcistub_device *psdev = NULL;
1525 unsigned long flags;
1526 bool found = false;
1527
1528 spin_lock_irqsave(&pcistub_devices_lock, flags);
1529 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
1530 if (!psdev->pdev && psdev->dev != pdev
1531 && pci_physfn(psdev->dev) == pdev) {
1532 found = true;
1533 break;
1534 }
1535 }
1536 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
1537 if (found)
1538 return psdev;
1539 return NULL;
1540}
1541
1542static int pci_stub_notifier(struct notifier_block *nb,
1543 unsigned long action, void *data)
1544{
1545 struct device *dev = data;
1546 const struct pci_dev *pdev = to_pci_dev(dev);
1547
1548 if (action != BUS_NOTIFY_UNBIND_DRIVER)
1549 return NOTIFY_DONE;
1550
1551 if (!pdev->is_physfn)
1552 return NOTIFY_DONE;
1553
1554 for (;;) {
1555 struct pcistub_device *psdev = find_vfs(pdev);
1556 if (!psdev)
1557 break;
1558 device_release_driver(&psdev->dev->dev);
1559 }
1560 return NOTIFY_DONE;
1561}
1562
1563static struct notifier_block pci_stub_nb = {
1564 .notifier_call = pci_stub_notifier,
1565};
1566#endif
1567
1505static int __init xen_pcibk_init(void) 1568static int __init xen_pcibk_init(void)
1506{ 1569{
1507 int err; 1570 int err;
@@ -1523,12 +1586,19 @@ static int __init xen_pcibk_init(void)
1523 err = xen_pcibk_xenbus_register(); 1586 err = xen_pcibk_xenbus_register();
1524 if (err) 1587 if (err)
1525 pcistub_exit(); 1588 pcistub_exit();
1589#ifdef CONFIG_PCI_IOV
1590 else
1591 bus_register_notifier(&pci_bus_type, &pci_stub_nb);
1592#endif
1526 1593
1527 return err; 1594 return err;
1528} 1595}
1529 1596
1530static void __exit xen_pcibk_cleanup(void) 1597static void __exit xen_pcibk_cleanup(void)
1531{ 1598{
1599#ifdef CONFIG_PCI_IOV
1600 bus_unregister_notifier(&pci_bus_type, &pci_stub_nb);
1601#endif
1532 xen_pcibk_xenbus_unregister(); 1602 xen_pcibk_xenbus_unregister();
1533 pcistub_exit(); 1603 pcistub_exit();
1534} 1604}
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index f72af87640e0..58e38d586f52 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -99,7 +99,8 @@ struct xen_pcibk_backend {
99 unsigned int *domain, unsigned int *bus, 99 unsigned int *domain, unsigned int *bus,
100 unsigned int *devfn); 100 unsigned int *devfn);
101 int (*publish)(struct xen_pcibk_device *pdev, publish_pci_root_cb cb); 101 int (*publish)(struct xen_pcibk_device *pdev, publish_pci_root_cb cb);
102 void (*release)(struct xen_pcibk_device *pdev, struct pci_dev *dev); 102 void (*release)(struct xen_pcibk_device *pdev, struct pci_dev *dev,
103 bool lock);
103 int (*add)(struct xen_pcibk_device *pdev, struct pci_dev *dev, 104 int (*add)(struct xen_pcibk_device *pdev, struct pci_dev *dev,
104 int devid, publish_pci_dev_cb publish_cb); 105 int devid, publish_pci_dev_cb publish_cb);
105 struct pci_dev *(*get)(struct xen_pcibk_device *pdev, 106 struct pci_dev *(*get)(struct xen_pcibk_device *pdev,
@@ -122,10 +123,10 @@ static inline int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
122} 123}
123 124
124static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, 125static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
125 struct pci_dev *dev) 126 struct pci_dev *dev, bool lock)
126{ 127{
127 if (xen_pcibk_backend && xen_pcibk_backend->release) 128 if (xen_pcibk_backend && xen_pcibk_backend->release)
128 return xen_pcibk_backend->release(pdev, dev); 129 return xen_pcibk_backend->release(pdev, dev, lock);
129} 130}
130 131
131static inline struct pci_dev * 132static inline struct pci_dev *
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index 51afff96c515..c99f8bb1c56c 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -145,7 +145,7 @@ out:
145} 145}
146 146
147static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, 147static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
148 struct pci_dev *dev) 148 struct pci_dev *dev, bool lock)
149{ 149{
150 int slot; 150 int slot;
151 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 151 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
@@ -169,8 +169,13 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
169out: 169out:
170 mutex_unlock(&vpci_dev->lock); 170 mutex_unlock(&vpci_dev->lock);
171 171
172 if (found_dev) 172 if (found_dev) {
173 if (lock)
174 device_lock(&found_dev->dev);
173 pcistub_put_pci_dev(found_dev); 175 pcistub_put_pci_dev(found_dev);
176 if (lock)
177 device_unlock(&found_dev->dev);
178 }
174} 179}
175 180
176static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev) 181static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
@@ -208,8 +213,11 @@ static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
208 struct pci_dev_entry *e, *tmp; 213 struct pci_dev_entry *e, *tmp;
209 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot], 214 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
210 list) { 215 list) {
216 struct pci_dev *dev = e->dev;
211 list_del(&e->list); 217 list_del(&e->list);
212 pcistub_put_pci_dev(e->dev); 218 device_lock(&dev->dev);
219 pcistub_put_pci_dev(dev);
220 device_unlock(&dev->dev);
213 kfree(e); 221 kfree(e);
214 } 222 }
215 } 223 }
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
index ad8d30c088fe..fe17c80ff4b7 100644
--- a/drivers/xen/xen-pciback/xenbus.c
+++ b/drivers/xen/xen-pciback/xenbus.c
@@ -247,7 +247,7 @@ static int xen_pcibk_export_device(struct xen_pcibk_device *pdev,
247 if (err) 247 if (err)
248 goto out; 248 goto out;
249 249
250 dev_dbg(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id); 250 dev_info(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id);
251 if (xen_register_device_domain_owner(dev, 251 if (xen_register_device_domain_owner(dev,
252 pdev->xdev->otherend_id) != 0) { 252 pdev->xdev->otherend_id) != 0) {
253 dev_err(&dev->dev, "Stealing ownership from dom%d.\n", 253 dev_err(&dev->dev, "Stealing ownership from dom%d.\n",
@@ -291,7 +291,7 @@ static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev,
291 291
292 /* N.B. This ends up calling pcistub_put_pci_dev which ends up 292 /* N.B. This ends up calling pcistub_put_pci_dev which ends up
293 * doing the FLR. */ 293 * doing the FLR. */
294 xen_pcibk_release_pci_dev(pdev, dev); 294 xen_pcibk_release_pci_dev(pdev, dev, true /* use the lock. */);
295 295
296out: 296out:
297 return err; 297 return err;