diff options
| -rw-r--r-- | drivers/virtio/virtio_pci.c | 18 | ||||
| -rw-r--r-- | include/linux/virtio_config.h | 2 |
2 files changed, 20 insertions, 0 deletions
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 3d1bf41e8892..03d1984bd363 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
| @@ -169,11 +169,29 @@ static void vp_set_status(struct virtio_device *vdev, u8 status) | |||
| 169 | iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | 169 | iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | /* wait for pending irq handlers */ | ||
| 173 | static void vp_synchronize_vectors(struct virtio_device *vdev) | ||
| 174 | { | ||
| 175 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
| 176 | int i; | ||
| 177 | |||
| 178 | if (vp_dev->intx_enabled) | ||
| 179 | synchronize_irq(vp_dev->pci_dev->irq); | ||
| 180 | |||
| 181 | for (i = 0; i < vp_dev->msix_vectors; ++i) | ||
| 182 | synchronize_irq(vp_dev->msix_entries[i].vector); | ||
| 183 | } | ||
| 184 | |||
| 172 | static void vp_reset(struct virtio_device *vdev) | 185 | static void vp_reset(struct virtio_device *vdev) |
| 173 | { | 186 | { |
| 174 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 187 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
| 175 | /* 0 status means a reset. */ | 188 | /* 0 status means a reset. */ |
| 176 | iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | 189 | iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); |
| 190 | /* Flush out the status write, and flush in device writes, | ||
| 191 | * including MSi-X interrupts, if any. */ | ||
| 192 | ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); | ||
| 193 | /* Flush pending VQ/configuration callbacks. */ | ||
| 194 | vp_synchronize_vectors(vdev); | ||
| 177 | } | 195 | } |
| 178 | 196 | ||
| 179 | /* the notify function used when creating a virt queue */ | 197 | /* the notify function used when creating a virt queue */ |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index add4790b21fe..e9e72bda1b72 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
| @@ -85,6 +85,8 @@ | |||
| 85 | * @reset: reset the device | 85 | * @reset: reset the device |
| 86 | * vdev: the virtio device | 86 | * vdev: the virtio device |
| 87 | * After this, status and feature negotiation must be done again | 87 | * After this, status and feature negotiation must be done again |
| 88 | * Device must not be reset from its vq/config callbacks, or in | ||
| 89 | * parallel with being added/removed. | ||
| 88 | * @find_vqs: find virtqueues and instantiate them. | 90 | * @find_vqs: find virtqueues and instantiate them. |
| 89 | * vdev: the virtio_device | 91 | * vdev: the virtio_device |
| 90 | * nvqs: the number of virtqueues to find | 92 | * nvqs: the number of virtqueues to find |
