QEMU commit c9b7d9ec21 "virtio: increase virtqueue size for virtio-scsi and virtio-blk" increased the number of queue descriptors from 128 to 256 which caused OpenBIOS to fail when booting from a virtio-blk device under qemu-system-ppc due to a memory overflow.
Update the virtio-blk driver so that it uses a maximum of 128 descriptor entries (the previous value) to fix the issue, and also ensure that any further increases in virtqueue size will not cause the same failure.
Note that this commit also fixes the vring_area size calculation which was incorrectly based upon the number of virtqueues, and not the number of descriptor entries.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/virtio.c | 7 ++++++- drivers/virtio.h | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/virtio.c b/drivers/virtio.c index ff7ed6f..7808d94 100644 --- a/drivers/virtio.c +++ b/drivers/virtio.c @@ -303,7 +303,12 @@ ob_virtio_configure_device(VDev *vdev) };
virtio_cfg_write16(vdev->common_cfg, VIRTIO_PCI_COMMON_Q_SELECT, i); + info.num = virtio_cfg_read16(vdev->common_cfg, VIRTIO_PCI_COMMON_Q_SIZE); + if (info.num > VIRTIO_MAX_RING_ENTRIES) { + info.num = VIRTIO_MAX_RING_ENTRIES; + virtio_cfg_write16(vdev->common_cfg, VIRTIO_PCI_COMMON_Q_SIZE, info.num); + }
vring_init(&vdev->vrings[i], &info);
@@ -503,7 +508,7 @@ void ob_virtio_init(const char *path, const char *dev_name, uint64_t common_cfg, addr = POP(); vdev->vrings = cell2pointer(addr);
- PUSH(VIRTIO_RING_SIZE * VIRTIO_MAX_VQS); + PUSH((VIRTIO_RING_SIZE * 2 + VIRTIO_PCI_VRING_ALIGN) * VIRTIO_MAX_VQS); feval("dma-alloc"); addr = POP(); vdev->ring_area = cell2pointer(addr); diff --git a/drivers/virtio.h b/drivers/virtio.h index 64b49e7..36cb205 100644 --- a/drivers/virtio.h +++ b/drivers/virtio.h @@ -147,8 +147,9 @@ struct VirtioDev { }; typedef struct VirtioDev VirtioDev;
-#define VIRTIO_RING_SIZE (PAGE_SIZE * 8) -#define VIRTIO_MAX_VQS 3 +#define VIRTIO_MAX_RING_ENTRIES 128 +#define VIRTIO_RING_SIZE (sizeof(VRingDesc) * VIRTIO_MAX_RING_ENTRIES) +#define VIRTIO_MAX_VQS 1 #define KVM_S390_VIRTIO_RING_ALIGN 4096
#define VRING_USED_F_NO_NOTIFY 1