virtio: finalize features before using device
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> Acked-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20221114035818.109511-3-xuanzhuo@linux.alibaba.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
5ea5c64c20
commit
3208b098f5
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue