fix two issues with virtio-blk
authorGleb Natapov <gleb@redhat.com>
Mon, 17 May 2010 13:27:27 +0000 (16:27 +0300)
committerKevin O'Connor <kevin@koconnor.net>
Mon, 17 May 2010 23:14:48 +0000 (19:14 -0400)
1. Check if blk_size is valid in virtio_blk config.
2. Disable interrupt otherwise interrupt may stuck
   with some guests.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
ChangeLog:
 v1->v2:
  - Treat sector size not equal to 512 bytes as error.

src/virtio-blk.c
src/virtio-blk.h
src/virtio-ring.h

index 7cc2edbf75dd0b5bc647210b72d8a307e924c8b7..e6167e900479bafb46bc670e540f41b039aeed06 100644 (file)
@@ -127,23 +127,34 @@ virtio_blk_setup(void)
                       VIRTIO_CONFIG_S_DRIVER );
 
         if (vp_find_vq(ioaddr, 0, vdrive_g->vq) < 0 ) {
+            dprintf(1, "fail to find vq for virtio-blk %x:%x\n",
+                    pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf));
+        next:
             free(vdrive_g);
             free(desc);
             free(vq);
-            dprintf(1, "fail to find vq for virtio-blk %x:%x\n",
-                    pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf));
             continue;
         }
 
         struct virtio_blk_config cfg;
         vp_get(ioaddr, 0, &cfg, sizeof(cfg));
 
-        vdrive_g->drive.blksize = cfg.blk_size;
+        u32 f = vp_get_features(ioaddr);
+        vdrive_g->drive.blksize = (f & (1 << VIRTIO_BLK_F_BLK_SIZE)) ?
+            cfg.blk_size : DISK_SECTOR_SIZE;
+
         vdrive_g->drive.sectors = cfg.capacity;
         dprintf(3, "virtio-blk %x:%x blksize=%d sectors=%u\n",
                 pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf),
                 vdrive_g->drive.blksize, (u32)vdrive_g->drive.sectors);
 
+        if (vdrive_g->drive.blksize != DISK_SECTOR_SIZE) {
+            dprintf(1, "virtio-blk %x:%x block size %d is unsupported\n",
+                    pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf),
+                    vdrive_g->drive.blksize);
+            goto next;
+        }
+
         vdrive_g->drive.pchs.cylinders = cfg.cylinders;
         vdrive_g->drive.pchs.heads = cfg.heads;
         vdrive_g->drive.pchs.spt = cfg.sectors;
index 8095d5b080498ca663625a855d7acd8b99f41b98..7243704be7953711499864ff9d991e4805584491 100644 (file)
@@ -16,6 +16,8 @@ struct virtio_blk_config
     u32 opt_io_size;
 } __attribute__((packed));
 
+#define VIRTIO_BLK_F_BLK_SIZE 6
+
 /* These two define direction. */
 #define VIRTIO_BLK_T_IN                0
 #define VIRTIO_BLK_T_OUT       1
index 3fb86fe4f6d07ba3b77fb5bf57ae5ba1f6b465f1..014defc34917c3b3888e38e22a05d872343f8d04 100644 (file)
@@ -105,6 +105,8 @@ static inline void vring_init(struct vring *vr,
    vr->desc = phys_to_virt(pa);
 
    vr->avail = (struct vring_avail *)&vr->desc[num];
+   /* disable interrupts */
+   vr->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
 
    /* physical address of used must be page aligned */