mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
xen: features and fixes for 3.19-rc0
- 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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAABAgAGBQJUiYb+AAoJEFxbo/MsZsTRwmEH+gNaJz5r8gIJlq8Q51+nOIs4 Gw6HdjUB5MOT47vDV4treEOx0Bk8hYTfgWUWvAC81JMJ1sMWOVrUGuG/0lmzaomW zXvSk+o0n4LafwEhHb8LIccZMbaH7f9o3PNdNchrTkPrIl8Gf2nmBXCkDsT4mRye 5ZFpc4ntgBrznh3baPYDS8PCAmlyZ0uVEnz1ofYI6S80dC13siEiPG0c9TrNEKzO glhvgCRmR0C4ZNLblM36HWBEqrdLuGCoNJSH+7okygyP2TLD3aO4R+9aD5JWYNdf fO2WmivX/zK+UGVAElrLx+rb8R2dv3ddeaE5piZhIBUieopIWJd32L3LhQORdtc= =N6DP -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
9d050966e2
26 changed files with 488 additions and 309 deletions
|
|
@ -96,8 +96,6 @@ static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
|
|||
dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT;
|
||||
phys_addr_t paddr = dma;
|
||||
|
||||
BUG_ON(paddr != dma); /* truncation has occurred, should never happen */
|
||||
|
||||
paddr |= baddr & ~PAGE_MASK;
|
||||
|
||||
return paddr;
|
||||
|
|
@ -399,11 +397,13 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
|
|||
* buffering it.
|
||||
*/
|
||||
if (dma_capable(dev, dev_addr, size) &&
|
||||
!range_straddles_page_boundary(phys, size) && !swiotlb_force) {
|
||||
!range_straddles_page_boundary(phys, size) &&
|
||||
!xen_arch_need_swiotlb(dev, PFN_DOWN(phys), PFN_DOWN(dev_addr)) &&
|
||||
!swiotlb_force) {
|
||||
/* we are not interested in the dma_addr returned by
|
||||
* xen_dma_map_page, only in the potential cache flushes executed
|
||||
* by the function. */
|
||||
xen_dma_map_page(dev, page, offset, size, dir, attrs);
|
||||
xen_dma_map_page(dev, page, dev_addr, offset, size, dir, attrs);
|
||||
return dev_addr;
|
||||
}
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
|
|||
return DMA_ERROR_CODE;
|
||||
|
||||
xen_dma_map_page(dev, pfn_to_page(map >> PAGE_SHIFT),
|
||||
map & ~PAGE_MASK, size, dir, attrs);
|
||||
dev_addr, map & ~PAGE_MASK, size, dir, attrs);
|
||||
dev_addr = xen_phys_to_bus(map);
|
||||
|
||||
/*
|
||||
|
|
@ -447,7 +447,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
|
|||
|
||||
BUG_ON(dir == DMA_NONE);
|
||||
|
||||
xen_dma_unmap_page(hwdev, paddr, size, dir, attrs);
|
||||
xen_dma_unmap_page(hwdev, dev_addr, size, dir, attrs);
|
||||
|
||||
/* NOTE: We use dev_addr here, not paddr! */
|
||||
if (is_xen_swiotlb_buffer(dev_addr)) {
|
||||
|
|
@ -495,14 +495,14 @@ xen_swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
|
|||
BUG_ON(dir == DMA_NONE);
|
||||
|
||||
if (target == SYNC_FOR_CPU)
|
||||
xen_dma_sync_single_for_cpu(hwdev, paddr, size, dir);
|
||||
xen_dma_sync_single_for_cpu(hwdev, dev_addr, size, dir);
|
||||
|
||||
/* NOTE: We use dev_addr here, not paddr! */
|
||||
if (is_xen_swiotlb_buffer(dev_addr))
|
||||
swiotlb_tbl_sync_single(hwdev, paddr, size, dir, target);
|
||||
|
||||
if (target == SYNC_FOR_DEVICE)
|
||||
xen_dma_sync_single_for_cpu(hwdev, paddr, size, dir);
|
||||
xen_dma_sync_single_for_device(hwdev, dev_addr, size, dir);
|
||||
|
||||
if (dir != DMA_FROM_DEVICE)
|
||||
return;
|
||||
|
|
@ -557,6 +557,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
|
|||
dma_addr_t dev_addr = xen_phys_to_bus(paddr);
|
||||
|
||||
if (swiotlb_force ||
|
||||
xen_arch_need_swiotlb(hwdev, PFN_DOWN(paddr), PFN_DOWN(dev_addr)) ||
|
||||
!dma_capable(hwdev, dev_addr, sg->length) ||
|
||||
range_straddles_page_boundary(paddr, sg->length)) {
|
||||
phys_addr_t map = swiotlb_tbl_map_single(hwdev,
|
||||
|
|
@ -574,6 +575,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
|
|||
return 0;
|
||||
}
|
||||
xen_dma_map_page(hwdev, pfn_to_page(map >> PAGE_SHIFT),
|
||||
dev_addr,
|
||||
map & ~PAGE_MASK,
|
||||
sg->length,
|
||||
dir,
|
||||
|
|
@ -584,6 +586,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
|
|||
* xen_dma_map_page, only in the potential cache flushes executed
|
||||
* by the function. */
|
||||
xen_dma_map_page(hwdev, pfn_to_page(paddr >> PAGE_SHIFT),
|
||||
dev_addr,
|
||||
paddr & ~PAGE_MASK,
|
||||
sg->length,
|
||||
dir,
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
|
|||
}
|
||||
|
||||
static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
|
||||
struct pci_dev *dev)
|
||||
struct pci_dev *dev, bool lock)
|
||||
{
|
||||
struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
|
||||
struct pci_dev_entry *dev_entry, *t;
|
||||
|
|
@ -87,8 +87,13 @@ static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
|
|||
|
||||
mutex_unlock(&dev_data->lock);
|
||||
|
||||
if (found_dev)
|
||||
if (found_dev) {
|
||||
if (lock)
|
||||
device_lock(&found_dev->dev);
|
||||
pcistub_put_pci_dev(found_dev);
|
||||
if (lock)
|
||||
device_unlock(&found_dev->dev);
|
||||
}
|
||||
}
|
||||
|
||||
static 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)
|
|||
struct pci_dev_entry *dev_entry, *t;
|
||||
|
||||
list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
|
||||
struct pci_dev *dev = dev_entry->dev;
|
||||
list_del(&dev_entry->list);
|
||||
pcistub_put_pci_dev(dev_entry->dev);
|
||||
device_lock(&dev->dev);
|
||||
pcistub_put_pci_dev(dev);
|
||||
device_unlock(&dev->dev);
|
||||
kfree(dev_entry);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ static void pcistub_device_release(struct kref *kref)
|
|||
*/
|
||||
__pci_reset_function_locked(dev);
|
||||
if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state))
|
||||
dev_dbg(&dev->dev, "Could not reload PCI state\n");
|
||||
dev_info(&dev->dev, "Could not reload PCI state\n");
|
||||
else
|
||||
pci_restore_state(dev);
|
||||
|
||||
|
|
@ -250,11 +250,15 @@ struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev,
|
|||
* - 'echo BDF > unbind' with a guest still using it. See pcistub_remove
|
||||
*
|
||||
* As such we have to be careful.
|
||||
*
|
||||
* To make this easier, the caller has to hold the device lock.
|
||||
*/
|
||||
void pcistub_put_pci_dev(struct pci_dev *dev)
|
||||
{
|
||||
struct pcistub_device *psdev, *found_psdev = NULL;
|
||||
unsigned long flags;
|
||||
struct xen_pcibk_dev_data *dev_data;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&pcistub_devices_lock, flags);
|
||||
|
||||
|
|
@ -276,13 +280,20 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
|
|||
/* Cleanup our device
|
||||
* (so it's ready for the next domain)
|
||||
*/
|
||||
device_lock_assert(&dev->dev);
|
||||
__pci_reset_function_locked(dev);
|
||||
|
||||
/* This is OK - we are running from workqueue context
|
||||
* and want to inhibit the user from fiddling with 'reset'
|
||||
*/
|
||||
pci_reset_function(dev);
|
||||
pci_restore_state(dev);
|
||||
|
||||
dev_data = pci_get_drvdata(dev);
|
||||
ret = pci_load_saved_state(dev, dev_data->pci_saved_state);
|
||||
if (!ret) {
|
||||
/*
|
||||
* The usual sequence is pci_save_state & pci_restore_state
|
||||
* but the guest might have messed the configuration space up.
|
||||
* Use the initial version (when device was bound to us).
|
||||
*/
|
||||
pci_restore_state(dev);
|
||||
} else
|
||||
dev_info(&dev->dev, "Could not reload PCI state\n");
|
||||
/* This disables the device. */
|
||||
xen_pcibk_reset_device(dev);
|
||||
|
||||
|
|
@ -554,12 +565,14 @@ static void pcistub_remove(struct pci_dev *dev)
|
|||
spin_unlock_irqrestore(&pcistub_devices_lock, flags);
|
||||
|
||||
if (found_psdev) {
|
||||
dev_dbg(&dev->dev, "found device to remove - in use? %p\n",
|
||||
found_psdev->pdev);
|
||||
dev_dbg(&dev->dev, "found device to remove %s\n",
|
||||
found_psdev->pdev ? "- in-use" : "");
|
||||
|
||||
if (found_psdev->pdev) {
|
||||
pr_warn("****** removing device %s while still in-use! ******\n",
|
||||
pci_name(found_psdev->dev));
|
||||
int domid = xen_find_device_domain_owner(dev);
|
||||
|
||||
pr_warn("****** removing device %s while still in-use by domain %d! ******\n",
|
||||
pci_name(found_psdev->dev), domid);
|
||||
pr_warn("****** driver domain may still access this device's i/o resources!\n");
|
||||
pr_warn("****** shutdown driver domain before binding device\n");
|
||||
pr_warn("****** to other drivers or domains\n");
|
||||
|
|
@ -567,7 +580,8 @@ static void pcistub_remove(struct pci_dev *dev)
|
|||
/* N.B. This ends up calling pcistub_put_pci_dev which ends up
|
||||
* doing the FLR. */
|
||||
xen_pcibk_release_pci_dev(found_psdev->pdev,
|
||||
found_psdev->dev);
|
||||
found_psdev->dev,
|
||||
false /* caller holds the lock. */);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&pcistub_devices_lock, flags);
|
||||
|
|
@ -629,10 +643,12 @@ static pci_ers_result_t common_process(struct pcistub_device *psdev,
|
|||
{
|
||||
pci_ers_result_t res = result;
|
||||
struct xen_pcie_aer_op *aer_op;
|
||||
struct xen_pcibk_device *pdev = psdev->pdev;
|
||||
struct xen_pci_sharedinfo *sh_info = pdev->sh_info;
|
||||
int ret;
|
||||
|
||||
/*with PV AER drivers*/
|
||||
aer_op = &(psdev->pdev->sh_info->aer_op);
|
||||
aer_op = &(sh_info->aer_op);
|
||||
aer_op->cmd = aer_cmd ;
|
||||
/*useful for error_detected callback*/
|
||||
aer_op->err = state;
|
||||
|
|
@ -653,36 +669,36 @@ static pci_ers_result_t common_process(struct pcistub_device *psdev,
|
|||
* this flag to judge whether we need to check pci-front give aer
|
||||
* service ack signal
|
||||
*/
|
||||
set_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags);
|
||||
set_bit(_PCIB_op_pending, (unsigned long *)&pdev->flags);
|
||||
|
||||
/*It is possible that a pcifront conf_read_write ops request invokes
|
||||
* the callback which cause the spurious execution of wake_up.
|
||||
* Yet it is harmless and better than a spinlock here
|
||||
*/
|
||||
set_bit(_XEN_PCIB_active,
|
||||
(unsigned long *)&psdev->pdev->sh_info->flags);
|
||||
(unsigned long *)&sh_info->flags);
|
||||
wmb();
|
||||
notify_remote_via_irq(psdev->pdev->evtchn_irq);
|
||||
notify_remote_via_irq(pdev->evtchn_irq);
|
||||
|
||||
ret = wait_event_timeout(xen_pcibk_aer_wait_queue,
|
||||
!(test_bit(_XEN_PCIB_active, (unsigned long *)
|
||||
&psdev->pdev->sh_info->flags)), 300*HZ);
|
||||
&sh_info->flags)), 300*HZ);
|
||||
|
||||
if (!ret) {
|
||||
if (test_bit(_XEN_PCIB_active,
|
||||
(unsigned long *)&psdev->pdev->sh_info->flags)) {
|
||||
(unsigned long *)&sh_info->flags)) {
|
||||
dev_err(&psdev->dev->dev,
|
||||
"pcifront aer process not responding!\n");
|
||||
clear_bit(_XEN_PCIB_active,
|
||||
(unsigned long *)&psdev->pdev->sh_info->flags);
|
||||
(unsigned long *)&sh_info->flags);
|
||||
aer_op->err = PCI_ERS_RESULT_NONE;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
clear_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags);
|
||||
clear_bit(_PCIB_op_pending, (unsigned long *)&pdev->flags);
|
||||
|
||||
if (test_bit(_XEN_PCIF_active,
|
||||
(unsigned long *)&psdev->pdev->sh_info->flags)) {
|
||||
(unsigned long *)&sh_info->flags)) {
|
||||
dev_dbg(&psdev->dev->dev,
|
||||
"schedule pci_conf service in " DRV_NAME "\n");
|
||||
xen_pcibk_test_and_schedule_op(psdev->pdev);
|
||||
|
|
@ -1502,6 +1518,53 @@ parse_error:
|
|||
fs_initcall(pcistub_init);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
static struct pcistub_device *find_vfs(const struct pci_dev *pdev)
|
||||
{
|
||||
struct pcistub_device *psdev = NULL;
|
||||
unsigned long flags;
|
||||
bool found = false;
|
||||
|
||||
spin_lock_irqsave(&pcistub_devices_lock, flags);
|
||||
list_for_each_entry(psdev, &pcistub_devices, dev_list) {
|
||||
if (!psdev->pdev && psdev->dev != pdev
|
||||
&& pci_physfn(psdev->dev) == pdev) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&pcistub_devices_lock, flags);
|
||||
if (found)
|
||||
return psdev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int pci_stub_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
const struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
if (action != BUS_NOTIFY_UNBIND_DRIVER)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (!pdev->is_physfn)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
for (;;) {
|
||||
struct pcistub_device *psdev = find_vfs(pdev);
|
||||
if (!psdev)
|
||||
break;
|
||||
device_release_driver(&psdev->dev->dev);
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block pci_stub_nb = {
|
||||
.notifier_call = pci_stub_notifier,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init xen_pcibk_init(void)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -1523,12 +1586,19 @@ static int __init xen_pcibk_init(void)
|
|||
err = xen_pcibk_xenbus_register();
|
||||
if (err)
|
||||
pcistub_exit();
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
else
|
||||
bus_register_notifier(&pci_bus_type, &pci_stub_nb);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit xen_pcibk_cleanup(void)
|
||||
{
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
bus_unregister_notifier(&pci_bus_type, &pci_stub_nb);
|
||||
#endif
|
||||
xen_pcibk_xenbus_unregister();
|
||||
pcistub_exit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,8 @@ struct xen_pcibk_backend {
|
|||
unsigned int *domain, unsigned int *bus,
|
||||
unsigned int *devfn);
|
||||
int (*publish)(struct xen_pcibk_device *pdev, publish_pci_root_cb cb);
|
||||
void (*release)(struct xen_pcibk_device *pdev, struct pci_dev *dev);
|
||||
void (*release)(struct xen_pcibk_device *pdev, struct pci_dev *dev,
|
||||
bool lock);
|
||||
int (*add)(struct xen_pcibk_device *pdev, struct pci_dev *dev,
|
||||
int devid, publish_pci_dev_cb publish_cb);
|
||||
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,
|
|||
}
|
||||
|
||||
static inline void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
|
||||
struct pci_dev *dev)
|
||||
struct pci_dev *dev, bool lock)
|
||||
{
|
||||
if (xen_pcibk_backend && xen_pcibk_backend->release)
|
||||
return xen_pcibk_backend->release(pdev, dev);
|
||||
return xen_pcibk_backend->release(pdev, dev, lock);
|
||||
}
|
||||
|
||||
static inline struct pci_dev *
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ out:
|
|||
}
|
||||
|
||||
static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
|
||||
struct pci_dev *dev)
|
||||
struct pci_dev *dev, bool lock)
|
||||
{
|
||||
int slot;
|
||||
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,
|
|||
out:
|
||||
mutex_unlock(&vpci_dev->lock);
|
||||
|
||||
if (found_dev)
|
||||
if (found_dev) {
|
||||
if (lock)
|
||||
device_lock(&found_dev->dev);
|
||||
pcistub_put_pci_dev(found_dev);
|
||||
if (lock)
|
||||
device_unlock(&found_dev->dev);
|
||||
}
|
||||
}
|
||||
|
||||
static 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)
|
|||
struct pci_dev_entry *e, *tmp;
|
||||
list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
|
||||
list) {
|
||||
struct pci_dev *dev = e->dev;
|
||||
list_del(&e->list);
|
||||
pcistub_put_pci_dev(e->dev);
|
||||
device_lock(&dev->dev);
|
||||
pcistub_put_pci_dev(dev);
|
||||
device_unlock(&dev->dev);
|
||||
kfree(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ static int xen_pcibk_export_device(struct xen_pcibk_device *pdev,
|
|||
if (err)
|
||||
goto out;
|
||||
|
||||
dev_dbg(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id);
|
||||
dev_info(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id);
|
||||
if (xen_register_device_domain_owner(dev,
|
||||
pdev->xdev->otherend_id) != 0) {
|
||||
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,
|
|||
|
||||
/* N.B. This ends up calling pcistub_put_pci_dev which ends up
|
||||
* doing the FLR. */
|
||||
xen_pcibk_release_pci_dev(pdev, dev);
|
||||
xen_pcibk_release_pci_dev(pdev, dev, true /* use the lock. */);
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
|
|
|||
Loading…
Reference in a new issue