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.
diff --git a/src/virtio-blk.c b/src/virtio-blk.c index 7cc2edb..e6167e9 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -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; diff --git a/src/virtio-blk.h b/src/virtio-blk.h index 8095d5b..7243704 100644 --- a/src/virtio-blk.h +++ b/src/virtio-blk.h @@ -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 diff --git a/src/virtio-ring.h b/src/virtio-ring.h index 3fb86fe..014defc 100644 --- a/src/virtio-ring.h +++ b/src/virtio-ring.h @@ -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 */
-- Gleb.