Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

virtio: virtio 1.0 cs04 spec compliance for reset

The spec says: after writing 0 to device_status, the driver MUST wait
for a read of device_status to return 0 before reinitializing the
device.

Cc: stable@vger.kernel.org
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>

+8 -3
+8 -3
drivers/virtio/virtio_pci_modern.c
··· 17 17 * 18 18 */ 19 19 20 + #include <linux/delay.h> 20 21 #define VIRTIO_PCI_NO_LEGACY 21 22 #include "virtio_pci_common.h" 22 23 ··· 272 271 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 273 272 /* 0 status means a reset. */ 274 273 vp_iowrite8(0, &vp_dev->common->device_status); 275 - /* Flush out the status write, and flush in device writes, 276 - * including MSI-X interrupts, if any. */ 277 - vp_ioread8(&vp_dev->common->device_status); 274 + /* After writing 0 to device_status, the driver MUST wait for a read of 275 + * device_status to return 0 before reinitializing the device. 276 + * This will flush out the status write, and flush in device writes, 277 + * including MSI-X interrupts, if any. 278 + */ 279 + while (vp_ioread8(&vp_dev->common->device_status)) 280 + msleep(1); 278 281 /* Flush pending VQ/configuration callbacks. */ 279 282 vp_synchronize_vectors(vdev); 280 283 }