On Mon, May 17, 2010 at 04:27:27PM +0300, Gleb Natapov wrote:
- Check if blk_size is valid in virtio_blk config.
- Disable interrupt otherwise interrupt may stuck with some guests.
Signed-off-by: Gleb Natapov gleb@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); } }