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(a)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
--
2.20.1
From: Brandon Bergren <git(a)bdragon.rtk0.net>
In qemu 9d7bd0826f2d19f88631ad7078662668148f7b5f, the behavior of vring
processing was changed to not run whenever bus-mastering is disabled.
Since we were never enabling it in the first place, OpenBIOS was no longer
able to access virtio disks on qemu.
Fix this by enabling bus-mastering before initializing.
Signed-off-by: Brandon Bergren <git(a)bdragon.rtk0.net>
---
drivers/pci.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci.c b/drivers/pci.c
index 9d501d3..34ae69a 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -816,6 +816,9 @@ int virtio_blk_config_cb(const pci_config_t *config)
return 0;
}
+ /* Enable bus mastering to ensure vring processing will run. */
+ ob_pci_enable_bus_master(config);
+
ob_virtio_init(config->path, "virtio-blk", common_cfg, device_cfg,
notify_base, notify_mult, idx);
#endif
--
2.25.1
Unfortunately it looks as if my original fix for this was wrong, and
in particular causes one of the SPARC64 QEMU advent calendar images which
uses a preloaded kernel to panic on boot.
The SILO memory allocators search through the physical memory "available"
property but then don't actually allocate the result: instead
hardcoded virtual addresses are only mapped to the physical addresses that
are determined to be free.
These patches remove the physical and virtual allocations introduced as part
of the original fix and map these memory areas in exactly the same way that
SILO does.
This also solves the issue the original patches were trying to fix, which was
that clients could still claim the memory in-use by the kernel via the CIF - the
virtual addresses used by SILO are higher up in memory, making a clash extremely
unlikely (and indeed, if it did happen, would mean the kernel/initrd combination
would also fail to boot under SILO).
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland(a)ilande.co.uk>
v2:
- Fix typo and cut/paste error patch 2
Mark Cave-Ayland (2):
SPARC64: fix kernel and initrd mapping to match SILO
SPARC32: fix kernel and initrd mapping to match SILO
arch/sparc32/boot.h | 3 +++
arch/sparc32/openbios.c | 31 ++++++++++++++++---------------
arch/sparc64/boot.c | 2 +-
arch/sparc64/boot.h | 3 +++
arch/sparc64/openbios.c | 16 +++++++---------
5 files changed, 30 insertions(+), 25 deletions(-)
--
2.20.1