aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-05-17 16:27:27 +0300
committerKevin O'Connor <kevin@koconnor.net>2010-05-17 19:14:48 -0400
commit4030db0d2c5a79de2a1b5c31514503e4ff2a3cd1 (patch)
tree19585cedc982324f30501e1503d07f2d3743351e
parentea8ac63a06bf621408d65fbfc17d77fa4a19be6f (diff)
downloadseabios-4030db0d2c5a79de2a1b5c31514503e4ff2a3cd1.tar.gz
fix two issues with virtio-blk
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.
-rw-r--r--src/virtio-blk.c17
-rw-r--r--src/virtio-blk.h2
-rw-r--r--src/virtio-ring.h2
3 files changed, 18 insertions, 3 deletions
diff --git a/src/virtio-blk.c b/src/virtio-blk.c
index 7cc2edbf..e6167e90 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 8095d5b0..7243704b 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 3fb86fe4..014defc3 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 */