Under the standard of Virtio 1.0, the initialization process of the device must first write sub-features back to device before using device, such as finding vqs.
There are four places using vp_find_vq().
1. virtio-blk.pci: put the code of finalizing features in front of using device 2. virtio-blk.mmio: put the code of finalizing features in front of using device 3. virtio-scsi.pci: is ok 4. virtio-scsi.mmio: add the code of finalizing features before vp_find_vq()
Link: https://www.mail-archive.com/qemu-devel@nongnu.org/msg920776.html Signed-off-by: Xuan Zhuo xuanzhuo@linux.alibaba.com --- src/hw/virtio-blk.c | 22 +++++++++++++--------- src/hw/virtio-scsi.c | 13 +++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c index 9b4a05a..ab6e79b 100644 --- a/src/hw/virtio-blk.c +++ b/src/hw/virtio-blk.c @@ -151,10 +151,6 @@ init_virtio_blk(void *data) vdrive->drive.cntl_id = pci->bdf;
vp_init_simple(&vdrive->vp, pci); - if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { - dprintf(1, "fail to find vq for virtio-blk %pP\n", pci); - goto fail; - }
if (vdrive->vp.use_modern) { struct vp_device *vp = &vdrive->vp; @@ -212,7 +208,14 @@ init_virtio_blk(void *data) vp_read(&vp->device, struct virtio_blk_config, heads); vdrive->drive.pchs.sector = vp_read(&vp->device, struct virtio_blk_config, sectors); - } else { + } + + if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { + dprintf(1, "fail to find vq for virtio-blk %pP\n", pci); + goto fail; + } + + if (!vdrive->vp.use_modern) { struct virtio_blk_config cfg; vp_get_legacy(&vdrive->vp, 0, &cfg, sizeof(cfg));
@@ -272,10 +275,6 @@ init_virtio_blk_mmio(void *mmio) vdrive->drive.cntl_id = (u32)mmio;
vp_init_mmio(&vdrive->vp, mmio); - if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { - dprintf(1, "fail to find vq for virtio-blk-mmio %p\n", mmio); - goto fail; - }
struct vp_device *vp = &vdrive->vp; u64 features = vp_get_features(vp); @@ -294,6 +293,11 @@ init_virtio_blk_mmio(void *mmio) goto fail; }
+ if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) { + dprintf(1, "fail to find vq for virtio-blk-mmio %p\n", mmio); + goto fail; + } + if (features & max_segment_size) vdrive->drive.max_segment_size = vp_read(&vp->device, struct virtio_blk_config, size_max); diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c index 369c981..79bda0b 100644 --- a/src/hw/virtio-scsi.c +++ b/src/hw/virtio-scsi.c @@ -239,6 +239,19 @@ init_virtio_scsi_mmio(void *mmio) vp_init_mmio(vp, mmio); u8 status = VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER;
+ u64 features = vp_get_features(vp); + u64 version1 = 1ull << VIRTIO_F_VERSION_1; + if (features & version1) { + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; + + vp_set_features(vp, features & (version1 | iommu_platform)); + vp_set_status(vp, VIRTIO_CONFIG_S_FEATURES_OK); + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { + dprintf(1, "device didn't accept features: %pP\n", mmio); + goto fail; + } + } + if (vp_find_vq(vp, 2, &vq) < 0 ) { dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); goto fail;