[SeaBIOS] [PATCHv2] fix two issues with virtio-blk

Kevin O'Connor kevin at koconnor.net
Tue May 18 01:27:30 CEST 2010


On Mon, May 17, 2010 at 04:27:27PM +0300, Gleb Natapov wrote:
> 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 at redhat.com>

Thanks.  I committed your change to my local repo.  I don't much like
that goto though - is it okay if we break up virtio_blk_setup with the
patch below (on top of your patch)?

-Kevin


diff --git a/src/virtio-blk.c b/src/virtio-blk.c
index e6167e9..7f9b3d2 100644
--- a/src/virtio-blk.c
+++ b/src/virtio-blk.c
@@ -85,6 +85,79 @@ process_virtio_op(struct disk_op_s *op)
     }
 }
 
+static void
+init_virtio_blk(u16 bdf)
+{
+    dprintf(1, "found virtio-blk at %x:%x\n", pci_bdf_to_bus(bdf),
+            pci_bdf_to_dev(bdf));
+    char *desc = malloc_tmphigh(MAXDESCSIZE);
+    struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g));
+    struct vring_virtqueue *vq = memalign_low(PAGE_SIZE, sizeof(*vq));
+    if (!vdrive_g || !desc || !vq) {
+        warn_noalloc();
+        goto fail;
+    }
+    memset(vdrive_g, 0, sizeof(*vdrive_g));
+    vdrive_g->drive.type = DTYPE_VIRTIO;
+    vdrive_g->drive.cntl_id = bdf;
+    vdrive_g->vq = vq;
+
+    u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) &
+        PCI_BASE_ADDRESS_IO_MASK;
+
+    vdrive_g->ioaddr = ioaddr;
+
+    vp_reset(ioaddr);
+    vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+                  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));
+        goto fail;
+    }
+
+    struct virtio_blk_config cfg;
+    vp_get(ioaddr, 0, &cfg, sizeof(cfg));
+
+    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 fail;
+    }
+
+    vdrive_g->drive.pchs.cylinders = cfg.cylinders;
+    vdrive_g->drive.pchs.heads = cfg.heads;
+    vdrive_g->drive.pchs.spt = cfg.sectors;
+
+    setup_translation(&vdrive_g->drive);
+    add_bcv_internal(&vdrive_g->drive);
+
+    snprintf(desc, MAXDESCSIZE, "Virtio disk PCI:%x:%x",
+             pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf));
+
+    vdrive_g->drive.desc = desc;
+
+    vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+                  VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
+    return;
+
+fail:
+    free(vdrive_g);
+    free(desc);
+    free(vq);
+}
+
 void
 virtio_blk_setup(void)
 {
@@ -100,74 +173,6 @@ virtio_blk_setup(void)
         u32 v = pci_config_readl(bdf, PCI_VENDOR_ID);
         if (v != id)
             continue;
-        dprintf(3, "found virtio-blk at %x:%x\n", pci_bdf_to_bus(bdf),
-                pci_bdf_to_dev(bdf));
-        char *desc = malloc_tmphigh(MAXDESCSIZE);
-        struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g));
-        struct vring_virtqueue *vq = memalign_low(PAGE_SIZE, sizeof(*vq));
-        if (!vdrive_g || !desc || !vq) {
-            free(vdrive_g);
-            free(desc);
-            free(vq);
-            warn_noalloc();
-            return;
-        }
-        memset(vdrive_g, 0, sizeof(*vdrive_g));
-        vdrive_g->drive.type = DTYPE_VIRTIO;
-        vdrive_g->drive.cntl_id = bdf;
-        vdrive_g->vq = vq;
-
-        u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) &
-            PCI_BASE_ADDRESS_IO_MASK;
-
-        vdrive_g->ioaddr = ioaddr;
-
-        vp_reset(ioaddr);
-        vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
-                      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);
-            continue;
-        }
-
-        struct virtio_blk_config cfg;
-        vp_get(ioaddr, 0, &cfg, sizeof(cfg));
-
-        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;
-
-        setup_translation(&vdrive_g->drive);
-        add_bcv_internal(&vdrive_g->drive);
-
-        snprintf(desc, MAXDESCSIZE, "Virtio disk PCI:%x:%x",
-                 pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf));
-
-        vdrive_g->drive.desc = desc;
-
-        vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
-                      VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
+        init_virtio_blk(bdf);
     }
 }



More information about the SeaBIOS mailing list