virtio: harden vring IRQ
[linux-block.git] / drivers / virtio / virtio_mmio.c
index b717302dc4acdf40b981e46b593e4aeb1383b90f..f9a36bc7ac27e1f32d6192b3cb68da31c36c315b 100644 (file)
@@ -253,6 +253,11 @@ static void vm_set_status(struct virtio_device *vdev, u8 status)
        /* We should never be setting status to 0. */
        BUG_ON(status == 0);
 
+       /*
+        * Per memory-barriers.txt, wmb() is not needed to guarantee
+        * that the the cache coherent memory writes have completed
+        * before writing to the MMIO region.
+        */
        writel(status, vm_dev->base + VIRTIO_MMIO_STATUS);
 }
 
@@ -345,6 +350,13 @@ static void vm_del_vqs(struct virtio_device *vdev)
        free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
 }
 
+static void vm_synchronize_cbs(struct virtio_device *vdev)
+{
+       struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+
+       synchronize_irq(platform_get_irq(vm_dev->pdev, 0));
+}
+
 static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int index,
                                  void (*callback)(struct virtqueue *vq),
                                  const char *name, bool ctx)
@@ -541,6 +553,7 @@ static const struct virtio_config_ops virtio_mmio_config_ops = {
        .finalize_features = vm_finalize_features,
        .bus_name       = vm_bus_name,
        .get_shm_region = vm_get_shm_region,
+       .synchronize_cbs = vm_synchronize_cbs,
 };
 
 
@@ -657,7 +670,7 @@ static int vm_cmdline_set(const char *device,
        int err;
        struct resource resources[2] = {};
        char *str;
-       long long int base, size;
+       long long base, size;
        unsigned int irq;
        int processed, consumed = 0;
        struct platform_device *pdev;