virtio: harden vring IRQ
[linux-block.git] / drivers / virtio / virtio_mmio.c
index 56128b9c46ebaabe1c1dcd872d11d664cd75d1dd..f9a36bc7ac27e1f32d6192b3cb68da31c36c315b 100644 (file)
@@ -144,8 +144,8 @@ static int vm_finalize_features(struct virtio_device *vdev)
        return 0;
 }
 
-static void vm_get(struct virtio_device *vdev, unsigned offset,
-                  void *buf, unsigned len)
+static void vm_get(struct virtio_device *vdev, unsigned int offset,
+                  void *buf, unsigned int len)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
        void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG;
@@ -186,8 +186,8 @@ static void vm_get(struct virtio_device *vdev, unsigned offset,
        }
 }
 
-static void vm_set(struct virtio_device *vdev, unsigned offset,
-                  const void *buf, unsigned len)
+static void vm_set(struct virtio_device *vdev, unsigned int offset,
+                  const void *buf, unsigned int len)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
        void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG;
@@ -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,7 +350,14 @@ static void vm_del_vqs(struct virtio_device *vdev)
        free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
 }
 
-static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
+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)
 {
@@ -455,7 +467,7 @@ error_available:
        return ERR_PTR(err);
 }
 
-static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                       struct virtqueue *vqs[],
                       vq_callback_t *callbacks[],
                       const char * const names[],
@@ -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;