Skip to content

Commit

Permalink
vfio-pci: Re-order device reset
Browse files Browse the repository at this point in the history
Move the device reset to the end of our disable path, the device
should already be stopped from pci_disable_device().  This also allows
us to manipulate the save/restore to avoid the save/reset/restore +
save/restore that we had before.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
  • Loading branch information
Alex Williamson committed Dec 7, 2012
1 parent 3a1f704 commit 2007722
Showing 1 changed file with 31 additions and 12 deletions.
43 changes: 31 additions & 12 deletions drivers/vfio/pci/vfio_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)

static void vfio_pci_disable(struct vfio_pci_device *vdev)
{
struct pci_dev *pdev = vdev->pdev;
int bar;

pci_disable_device(vdev->pdev);
pci_disable_device(pdev);

vfio_pci_set_irqs_ioctl(vdev, VFIO_IRQ_SET_DATA_NONE |
VFIO_IRQ_SET_ACTION_TRIGGER,
Expand All @@ -104,22 +105,40 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)

vfio_config_free(vdev);

pci_reset_function(vdev->pdev);

if (pci_load_and_free_saved_state(vdev->pdev,
&vdev->pci_saved_state) == 0)
pci_restore_state(vdev->pdev);
else
pr_info("%s: Couldn't reload %s saved state\n",
__func__, dev_name(&vdev->pdev->dev));

for (bar = PCI_STD_RESOURCES; bar <= PCI_STD_RESOURCE_END; bar++) {
if (!vdev->barmap[bar])
continue;
pci_iounmap(vdev->pdev, vdev->barmap[bar]);
pci_release_selected_regions(vdev->pdev, 1 << bar);
pci_iounmap(pdev, vdev->barmap[bar]);
pci_release_selected_regions(pdev, 1 << bar);
vdev->barmap[bar] = NULL;
}

/*
* If we have saved state, restore it. If we can reset the device,
* even better. Resetting with current state seems better than
* nothing, but saving and restoring current state without reset
* is just busy work.
*/
if (pci_load_and_free_saved_state(pdev, &vdev->pci_saved_state)) {
pr_info("%s: Couldn't reload %s saved state\n",
__func__, dev_name(&pdev->dev));

if (!vdev->reset_works)
return;

pci_save_state(pdev);
}

/*
* Disable INTx and MSI, presumably to avoid spurious interrupts
* during reset. Stolen from pci_reset_function()
*/
pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);

if (vdev->reset_works)
__pci_reset_function(pdev);

pci_restore_state(pdev);
}

static void vfio_pci_release(void *device_data)
Expand Down

0 comments on commit 2007722

Please sign in to comment.