diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-25 16:48:24 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-25 17:26:28 -0400 |
commit | c341ca45ce56143804ef5a8f4db753e554e640b4 (patch) | |
tree | bc26c8eb1cf98658a7a8d23293f21d243c5a70c1 /drivers/xen | |
parent | e6aa70a0d5511296ea3d5fd1f5e2203ff6898107 (diff) |
xen/pciback: Restore the PCI config space after an FLR.
When we do an FLR, or D0->D3_hot we may lose the BARs as the
device has turned itself off (and on). This means the device cannot
function unless the pci_restore_state is called - which it is
when the PCI device is unbound from the Xen PCI backend driver.
For PV guests it ends up calling pci_enable_device / pci_enable_msi[x]
which does the proper steps
That however is not happening if a HVM guest is run as QEMU
deals with PCI configuration space. QEMU also requires that the
device be "parked" under the ownership of a pci-stub driver to
guarantee that the PCI device is not being used. Hence we
follow the same incantation as pci_reset_function does - by
doing an FLR, then restoring the PCI configuration space.
The result of this patch is that when you run lspci, you get
now this:
- Region 0: [virtual] Memory at fe8c0000 (32-bit, non-prefetchable) [size=128K]
- Region 1: [virtual] Memory at fe800000 (32-bit, non-prefetchable) [size=512K]
+ Region 0: Memory at fe8c0000 (32-bit, non-prefetchable) [size=128K]
+ Region 1: Memory at fe800000 (32-bit, non-prefetchable) [size=512K]
Region 2: I/O ports at c000 [size=32]
- Region 3: [virtual] Memory at fe8e0000 (32-bit, non-prefetchable) [size=16K]
+ Region 3: Memory at fe8e0000 (32-bit, non-prefetchable) [size=16K]
The [virtual] means that lspci read those entries from SysFS but when
it read them from the device it got a different value (0xfffffff).
CC: stable@vger.kernel.org #only for 3.5, 3.6
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/xen-pciback/pci_stub.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index acec6faff885..e5a0c13e2ad4 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
@@ -362,6 +362,7 @@ static int __devinit pcistub_init_device(struct pci_dev *dev) | |||
362 | else { | 362 | else { |
363 | dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); | 363 | dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); |
364 | __pci_reset_function_locked(dev); | 364 | __pci_reset_function_locked(dev); |
365 | pci_restore_state(dev); | ||
365 | } | 366 | } |
366 | /* Now disable the device (this also ensures some private device | 367 | /* Now disable the device (this also ensures some private device |
367 | * data is setup before we export) | 368 | * data is setup before we export) |