summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2020-05-16 14:01:31 +0100
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2020-05-16 14:42:22 +0100
commit4704d9eba6d8017dc694c077ca4205ffd8becad8 (patch)
treea2f303d44f4e8ba4cabae1d7bba6e11b6b2f1519
parent9b8c30c6db07daa27e9422daf1bb542dbe46170a (diff)
downloadqemu-openbios-4704d9eba6d8017dc694c077ca4205ffd8becad8.tar.gz
virtio: limit ring size to a maximum of 128 descriptor entries
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>
-rw-r--r--drivers/virtio.c7
-rw-r--r--drivers/virtio.h5
2 files changed, 9 insertions, 3 deletions
diff --git a/drivers/virtio.c b/drivers/virtio.c
index ff7ed6f1..7808d943 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 64b49e73..36cb205c 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