src/hw/virtio-blk.c | 23 ++++++++++++++--------- src/hw/virtio-scsi.c | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-)
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 finalizing features code in front of using device
2. virtio-blk.mmio: put the finalizing features code in front of using device
3. virtio-scsi.pci: is ok
4. virtio-scsi.mmio: add set features before vp_find_vq()
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
src/hw/virtio-blk.c | 23 ++++++++++++++---------
src/hw/virtio-scsi.c | 18 ++++++++++++++++++
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c
index 9b4a05a..52eb08f 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,15 @@ 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 +276,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 +294,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..cf131fb 100644
--- a/src/hw/virtio-scsi.c
+++ b/src/hw/virtio-scsi.c
@@ -239,6 +239,24 @@ 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;
+ u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM;
+ if (!(features & version1)) {
+ dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio);
+ goto fail;
+ }
+
+ vp_set_features(vp, features & (version1 | iommu_platform));
+ status |= VIRTIO_CONFIG_S_FEATURES_OK;
+ vp_set_status(vp, status);
+ 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;
--
2.32.0.3.g01195cf9f
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
On Wed, Nov 09, 2022 at 09:17:25PM +0800, Xuan Zhuo wrote: > 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 finalizing features code in front of using device > 2. virtio-blk.mmio: put the finalizing features code in front of using device > 3. virtio-scsi.pci: is ok > 4. virtio-scsi.mmio: add set features before vp_find_vq() > > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Please confirm you tested this with both modern and legacy and all these device types. Because e.g. scsi does not look like it would work. > --- > src/hw/virtio-blk.c | 23 ++++++++++++++--------- > src/hw/virtio-scsi.c | 18 ++++++++++++++++++ > 2 files changed, 32 insertions(+), 9 deletions(-) > > diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c > index 9b4a05a..52eb08f 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,15 @@ 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 { > + } > + > + Why two empty lines? > + 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 +276,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 +294,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..cf131fb 100644 > --- a/src/hw/virtio-scsi.c > +++ b/src/hw/virtio-scsi.c > @@ -239,6 +239,24 @@ 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; > + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; > + if (!(features & version1)) { > + dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio); > + goto fail; > + } > + > + vp_set_features(vp, features & (version1 | iommu_platform)); > + status |= VIRTIO_CONFIG_S_FEATURES_OK; > + vp_set_status(vp, status); > + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { > + dprintf(1, "device didn't accept features: %pP\n", mmio); > + goto fail; > + } > + } This extra scope is quite ugly. > + > if (vp_find_vq(vp, 2, &vq) < 0 ) { > dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); > goto fail; I don't get it. Don't you need to test use_modern? And where is the code coming from? > -- > 2.32.0.3.g01195cf9f _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Wed, 9 Nov 2022 08:28:00 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: > On Wed, Nov 09, 2022 at 09:17:25PM +0800, Xuan Zhuo wrote: > > 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 finalizing features code in front of using device > > 2. virtio-blk.mmio: put the finalizing features code in front of using device > > 3. virtio-scsi.pci: is ok > > 4. virtio-scsi.mmio: add set features before vp_find_vq() > > > > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> > > > Please confirm you tested this with both modern and legacy > and all these device types. Because e.g. scsi does not look > like it would work. I have tested this: virtio-blk.pci I tried to start virtio-blk and virtio-scsi with MMIO, but it was not successful. I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? > > > > --- > > src/hw/virtio-blk.c | 23 ++++++++++++++--------- > > src/hw/virtio-scsi.c | 18 ++++++++++++++++++ > > 2 files changed, 32 insertions(+), 9 deletions(-) > > > > diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c > > index 9b4a05a..52eb08f 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,15 @@ 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 { > > + } > > + > > + > > Why two empty lines? Will fix. > > > + 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 +276,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 +294,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..cf131fb 100644 > > --- a/src/hw/virtio-scsi.c > > +++ b/src/hw/virtio-scsi.c > > @@ -239,6 +239,24 @@ 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; > > + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; > > + if (!(features & version1)) { > > + dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio); > > + goto fail; > > + } > > + > > + vp_set_features(vp, features & (version1 | iommu_platform)); > > + status |= VIRTIO_CONFIG_S_FEATURES_OK; > > + vp_set_status(vp, status); > > + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { > > + dprintf(1, "device didn't accept features: %pP\n", mmio); > > + goto fail; > > + } > > + } > > > This extra scope is quite ugly. Will fix. > > > + > > if (vp_find_vq(vp, 2, &vq) < 0 ) { > > dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); > > goto fail; > > I don't get it. Don't you need to test use_modern? And where is > the code coming from? Do we need to distinguish between modern for mmio? Is there any error in my understanding? Thanks. > > > > -- > > 2.32.0.3.g01195cf9f > _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
Hi, > I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? qemu -machine microvm \ -global virtio-mmio.force-legacy={true,false} \ -device virtio-scsi-device \ take care, Gerd _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Thu, 10 Nov 2022 11:30:17 +0100, Gerd Hoffmann <kraxel@redhat.com> wrote: > Hi, > > > I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? > > qemu -machine microvm \ > -global virtio-mmio.force-legacy={true,false} \ Thanks. This help me. > -device virtio-scsi-device \ > > take care, > Gerd > _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On 11/09/22 14:59, Xuan Zhuo wrote: > On Wed, 9 Nov 2022 08:28:00 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: >> On Wed, Nov 09, 2022 at 09:17:25PM +0800, Xuan Zhuo wrote: >>> 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 finalizing features code in front of using device >>> 2. virtio-blk.mmio: put the finalizing features code in front of using device >>> 3. virtio-scsi.pci: is ok >>> 4. virtio-scsi.mmio: add set features before vp_find_vq() >>> >>> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> >> >> >> Please confirm you tested this with both modern and legacy >> and all these device types. Because e.g. scsi does not look >> like it would work. > > I have tested this: virtio-blk.pci > > I tried to start virtio-blk and virtio-scsi with MMIO, but it was not > successful. > > I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? > > >> >> >>> --- >>> src/hw/virtio-blk.c | 23 ++++++++++++++--------- >>> src/hw/virtio-scsi.c | 18 ++++++++++++++++++ >>> 2 files changed, 32 insertions(+), 9 deletions(-) >>> >>> diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c >>> index 9b4a05a..52eb08f 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,15 @@ 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 { >>> + } >>> + >>> + >> >> Why two empty lines? > > Will fix. > >> >>> + 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 +276,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 +294,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..cf131fb 100644 >>> --- a/src/hw/virtio-scsi.c >>> +++ b/src/hw/virtio-scsi.c >>> @@ -239,6 +239,24 @@ 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; >>> + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; >>> + if (!(features & version1)) { >>> + dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio); >>> + goto fail; >>> + } >>> + >>> + vp_set_features(vp, features & (version1 | iommu_platform)); >>> + status |= VIRTIO_CONFIG_S_FEATURES_OK; >>> + vp_set_status(vp, status); >>> + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { >>> + dprintf(1, "device didn't accept features: %pP\n", mmio); >>> + goto fail; >>> + } >>> + } >> >> >> This extra scope is quite ugly. > > Will fix. > >> >>> + >>> if (vp_find_vq(vp, 2, &vq) < 0 ) { >>> dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); >>> goto fail; >> >> I don't get it. Don't you need to test use_modern? And where is >> the code coming from? > > Do we need to distinguish between modern for mmio? Is there any error in my > understanding? I think Gerd can comment well on MMIO vs. virtio-1.0. In edk2, we had originally implemented the following combinations (over time): - virtio-0.9.5 over MMIO, usable with qemu-system-(arm|aarch64), "virt" machine - virtio-0.9.5 over PCI, usable with qemu-system-(arm|aarch64), "virt" machine, *if* you configure a PCIe host, and also usable (of course) with qemu-system-(i386|x86_64) with the "pc" and "q35" machine types. - virtio-1.0 over PCI (same scenarios as in the previous bullet). I never implemented virtio-1.0 over MMIO because it looked complicated with no actual use case -- after aarch64/virt started supporting PCIe, there was no real need to use MMIO, ever. So if you wanted virtio-1.0, you were forced to use PCI on aarch64 as well, but that was fine (IMO). However, Gerd then invented the MicroVM (x86) machine type, which wanted virtio-1.0 over MMIO. Gerd added the necessary *transport* code to edk2 (I was surprised -- I thought it would be much more complex, and IIRC, no *device driver* was necessary to modify). In fact I think the MicroVM machine type is the *only* option for exercising the virtio-mmio transport on x86. (And because this is about SeaBIOS, you certainly want x86, not aarch64/virt!) But I'm unsure if MicroVM uses SeaBIOS at all -- Gerd can tell best. At least in theory, the test matrix is large: - PCI vs. MMIO transport - virtio-0.9.5 (legacy) vs. virtio-1.0 (modern) spec - blk vs. scsi device model 8 cases. (With edk2, the test matrix was even larger, due to (a) supporting more architectures than SeaBIOS (+aarch64), (b) supporting many more device types (+rng +net +gpu +fs), (c) supporting guest memory encryption with SEV on x86. But that matrix was *also smaller* in a sense, because virtio-1.0 in combination with MMIO was not meant to be supported -- until Gerd just went ahead and implemented it, that is :)) Laszlo _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Wed, Nov 09, 2022 at 03:33:21PM +0100, Laszlo Ersek wrote: > On 11/09/22 14:59, Xuan Zhuo wrote: > > On Wed, 9 Nov 2022 08:28:00 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: > >> On Wed, Nov 09, 2022 at 09:17:25PM +0800, Xuan Zhuo wrote: > >>> 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 finalizing features code in front of using device > >>> 2. virtio-blk.mmio: put the finalizing features code in front of using device > >>> 3. virtio-scsi.pci: is ok > >>> 4. virtio-scsi.mmio: add set features before vp_find_vq() > >>> > >>> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> > >> > >> > >> Please confirm you tested this with both modern and legacy > >> and all these device types. Because e.g. scsi does not look > >> like it would work. > > > > I have tested this: virtio-blk.pci > > > > I tried to start virtio-blk and virtio-scsi with MMIO, but it was not > > successful. > > > > I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? > > > > > >> > >> > >>> --- > >>> src/hw/virtio-blk.c | 23 ++++++++++++++--------- > >>> src/hw/virtio-scsi.c | 18 ++++++++++++++++++ > >>> 2 files changed, 32 insertions(+), 9 deletions(-) > >>> > >>> diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c > >>> index 9b4a05a..52eb08f 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,15 @@ 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 { > >>> + } > >>> + > >>> + > >> > >> Why two empty lines? > > > > Will fix. > > > >> > >>> + 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 +276,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 +294,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..cf131fb 100644 > >>> --- a/src/hw/virtio-scsi.c > >>> +++ b/src/hw/virtio-scsi.c > >>> @@ -239,6 +239,24 @@ 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; > >>> + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; > >>> + if (!(features & version1)) { > >>> + dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio); > >>> + goto fail; > >>> + } > >>> + > >>> + vp_set_features(vp, features & (version1 | iommu_platform)); > >>> + status |= VIRTIO_CONFIG_S_FEATURES_OK; > >>> + vp_set_status(vp, status); > >>> + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { > >>> + dprintf(1, "device didn't accept features: %pP\n", mmio); > >>> + goto fail; > >>> + } > >>> + } > >> > >> > >> This extra scope is quite ugly. > > > > Will fix. > > > >> > >>> + > >>> if (vp_find_vq(vp, 2, &vq) < 0 ) { > >>> dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); > >>> goto fail; > >> > >> I don't get it. Don't you need to test use_modern? And where is > >> the code coming from? > > > > Do we need to distinguish between modern for mmio? Is there any error in my > > understanding? > > I think Gerd can comment well on MMIO vs. virtio-1.0. > > In edk2, we had originally implemented the following combinations (over > time): > > - virtio-0.9.5 over MMIO, usable with qemu-system-(arm|aarch64), "virt" > machine > > - virtio-0.9.5 over PCI, usable with qemu-system-(arm|aarch64), "virt" > machine, *if* you configure a PCIe host, and also usable (of course) > with qemu-system-(i386|x86_64) with the "pc" and "q35" machine types. > > - virtio-1.0 over PCI (same scenarios as in the previous bullet). > > I never implemented virtio-1.0 over MMIO because it looked complicated > with no actual use case -- after aarch64/virt started supporting PCIe, > there was no real need to use MMIO, ever. So if you wanted virtio-1.0, > you were forced to use PCI on aarch64 as well, but that was fine (IMO). > > However, Gerd then invented the MicroVM (x86) machine type, which wanted > virtio-1.0 over MMIO. Gerd added the necessary *transport* code to edk2 > (I was surprised -- I thought it would be much more complex, and IIRC, > no *device driver* was necessary to modify). > > In fact I think the MicroVM machine type is the *only* option for > exercising the virtio-mmio transport on x86. (And because this is about > SeaBIOS, you certainly want x86, not aarch64/virt!) But I'm unsure if > MicroVM uses SeaBIOS at all -- Gerd can tell best. > > At least in theory, the test matrix is large: > - PCI vs. MMIO transport > - virtio-0.9.5 (legacy) vs. virtio-1.0 (modern) spec > - blk vs. scsi device model > > 8 cases. > > (With edk2, the test matrix was even larger, due to (a) supporting more > architectures than SeaBIOS (+aarch64), (b) supporting many more device > types (+rng +net +gpu +fs), (c) supporting guest memory encryption with > SEV on x86. But that matrix was *also smaller* in a sense, because > virtio-1.0 in combination with MMIO was not meant to be supported -- > until Gerd just went ahead and implemented it, that is :)) > > Laszlo BTW, it is not strictly necessary to keep find vqs after set features in legacy mode. Linux switched to setting features first back in 2009 and that works fine - legacy spec was more a de-facto thing anyway. -- MST _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Wed, 9 Nov 2022 09:43:57 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: > On Wed, Nov 09, 2022 at 03:33:21PM +0100, Laszlo Ersek wrote: > > On 11/09/22 14:59, Xuan Zhuo wrote: > > > On Wed, 9 Nov 2022 08:28:00 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: > > >> On Wed, Nov 09, 2022 at 09:17:25PM +0800, Xuan Zhuo wrote: > > >>> 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 finalizing features code in front of using device > > >>> 2. virtio-blk.mmio: put the finalizing features code in front of using device > > >>> 3. virtio-scsi.pci: is ok > > >>> 4. virtio-scsi.mmio: add set features before vp_find_vq() > > >>> > > >>> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> > > >> > > >> > > >> Please confirm you tested this with both modern and legacy > > >> and all these device types. Because e.g. scsi does not look > > >> like it would work. > > > > > > I have tested this: virtio-blk.pci > > > > > > I tried to start virtio-blk and virtio-scsi with MMIO, but it was not > > > successful. > > > > > > I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? > > > > > > > > >> > > >> > > >>> --- > > >>> src/hw/virtio-blk.c | 23 ++++++++++++++--------- > > >>> src/hw/virtio-scsi.c | 18 ++++++++++++++++++ > > >>> 2 files changed, 32 insertions(+), 9 deletions(-) > > >>> > > >>> diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c > > >>> index 9b4a05a..52eb08f 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,15 @@ 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 { > > >>> + } > > >>> + > > >>> + > > >> > > >> Why two empty lines? > > > > > > Will fix. > > > > > >> > > >>> + 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 +276,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 +294,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..cf131fb 100644 > > >>> --- a/src/hw/virtio-scsi.c > > >>> +++ b/src/hw/virtio-scsi.c > > >>> @@ -239,6 +239,24 @@ 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; > > >>> + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; > > >>> + if (!(features & version1)) { > > >>> + dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio); > > >>> + goto fail; > > >>> + } > > >>> + > > >>> + vp_set_features(vp, features & (version1 | iommu_platform)); > > >>> + status |= VIRTIO_CONFIG_S_FEATURES_OK; > > >>> + vp_set_status(vp, status); > > >>> + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { > > >>> + dprintf(1, "device didn't accept features: %pP\n", mmio); > > >>> + goto fail; > > >>> + } > > >>> + } > > >> > > >> > > >> This extra scope is quite ugly. > > > > > > Will fix. > > > > > >> > > >>> + > > >>> if (vp_find_vq(vp, 2, &vq) < 0 ) { > > >>> dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); > > >>> goto fail; > > >> > > >> I don't get it. Don't you need to test use_modern? And where is > > >> the code coming from? > > > > > > Do we need to distinguish between modern for mmio? Is there any error in my > > > understanding? > > > > I think Gerd can comment well on MMIO vs. virtio-1.0. > > > > In edk2, we had originally implemented the following combinations (over > > time): > > > > - virtio-0.9.5 over MMIO, usable with qemu-system-(arm|aarch64), "virt" > > machine > > > > - virtio-0.9.5 over PCI, usable with qemu-system-(arm|aarch64), "virt" > > machine, *if* you configure a PCIe host, and also usable (of course) > > with qemu-system-(i386|x86_64) with the "pc" and "q35" machine types. > > > > - virtio-1.0 over PCI (same scenarios as in the previous bullet). > > > > I never implemented virtio-1.0 over MMIO because it looked complicated > > with no actual use case -- after aarch64/virt started supporting PCIe, > > there was no real need to use MMIO, ever. So if you wanted virtio-1.0, > > you were forced to use PCI on aarch64 as well, but that was fine (IMO). > > > > However, Gerd then invented the MicroVM (x86) machine type, which wanted > > virtio-1.0 over MMIO. Gerd added the necessary *transport* code to edk2 > > (I was surprised -- I thought it would be much more complex, and IIRC, > > no *device driver* was necessary to modify). > > > > In fact I think the MicroVM machine type is the *only* option for > > exercising the virtio-mmio transport on x86. (And because this is about > > SeaBIOS, you certainly want x86, not aarch64/virt!) But I'm unsure if > > MicroVM uses SeaBIOS at all -- Gerd can tell best. > > > > At least in theory, the test matrix is large: > > - PCI vs. MMIO transport > > - virtio-0.9.5 (legacy) vs. virtio-1.0 (modern) spec > > - blk vs. scsi device model > > > > 8 cases. > > > > (With edk2, the test matrix was even larger, due to (a) supporting more > > architectures than SeaBIOS (+aarch64), (b) supporting many more device > > types (+rng +net +gpu +fs), (c) supporting guest memory encryption with > > SEV on x86. But that matrix was *also smaller* in a sense, because > > virtio-1.0 in combination with MMIO was not meant to be supported -- > > until Gerd just went ahead and implemented it, that is :)) > > > > Laszlo > > > BTW, it is not strictly necessary to keep find vqs > after set features in legacy mode. Linux switched > to setting features first back in 2009 and that > works fine - legacy spec was more a de-facto thing anyway. So we can actually put the setting features directly in the front without checking modern(VERSION_1). Is that so? Thanks. > > -- > MST > _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Thu, Nov 10, 2022 at 10:31:37AM +0800, Xuan Zhuo wrote: > On Wed, 9 Nov 2022 09:43:57 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: > > On Wed, Nov 09, 2022 at 03:33:21PM +0100, Laszlo Ersek wrote: > > > On 11/09/22 14:59, Xuan Zhuo wrote: > > > > On Wed, 9 Nov 2022 08:28:00 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: > > > >> On Wed, Nov 09, 2022 at 09:17:25PM +0800, Xuan Zhuo wrote: > > > >>> 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 finalizing features code in front of using device > > > >>> 2. virtio-blk.mmio: put the finalizing features code in front of using device > > > >>> 3. virtio-scsi.pci: is ok > > > >>> 4. virtio-scsi.mmio: add set features before vp_find_vq() > > > >>> > > > >>> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> > > > >> > > > >> > > > >> Please confirm you tested this with both modern and legacy > > > >> and all these device types. Because e.g. scsi does not look > > > >> like it would work. > > > > > > > > I have tested this: virtio-blk.pci > > > > > > > > I tried to start virtio-blk and virtio-scsi with MMIO, but it was not > > > > successful. > > > > > > > > I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? > > > > > > > > > > > >> > > > >> > > > >>> --- > > > >>> src/hw/virtio-blk.c | 23 ++++++++++++++--------- > > > >>> src/hw/virtio-scsi.c | 18 ++++++++++++++++++ > > > >>> 2 files changed, 32 insertions(+), 9 deletions(-) > > > >>> > > > >>> diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c > > > >>> index 9b4a05a..52eb08f 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,15 @@ 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 { > > > >>> + } > > > >>> + > > > >>> + > > > >> > > > >> Why two empty lines? > > > > > > > > Will fix. > > > > > > > >> > > > >>> + 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 +276,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 +294,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..cf131fb 100644 > > > >>> --- a/src/hw/virtio-scsi.c > > > >>> +++ b/src/hw/virtio-scsi.c > > > >>> @@ -239,6 +239,24 @@ 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; > > > >>> + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; > > > >>> + if (!(features & version1)) { > > > >>> + dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio); > > > >>> + goto fail; > > > >>> + } > > > >>> + > > > >>> + vp_set_features(vp, features & (version1 | iommu_platform)); > > > >>> + status |= VIRTIO_CONFIG_S_FEATURES_OK; > > > >>> + vp_set_status(vp, status); > > > >>> + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { > > > >>> + dprintf(1, "device didn't accept features: %pP\n", mmio); > > > >>> + goto fail; > > > >>> + } > > > >>> + } > > > >> > > > >> > > > >> This extra scope is quite ugly. > > > > > > > > Will fix. > > > > > > > >> > > > >>> + > > > >>> if (vp_find_vq(vp, 2, &vq) < 0 ) { > > > >>> dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); > > > >>> goto fail; > > > >> > > > >> I don't get it. Don't you need to test use_modern? And where is > > > >> the code coming from? > > > > > > > > Do we need to distinguish between modern for mmio? Is there any error in my > > > > understanding? > > > > > > I think Gerd can comment well on MMIO vs. virtio-1.0. > > > > > > In edk2, we had originally implemented the following combinations (over > > > time): > > > > > > - virtio-0.9.5 over MMIO, usable with qemu-system-(arm|aarch64), "virt" > > > machine > > > > > > - virtio-0.9.5 over PCI, usable with qemu-system-(arm|aarch64), "virt" > > > machine, *if* you configure a PCIe host, and also usable (of course) > > > with qemu-system-(i386|x86_64) with the "pc" and "q35" machine types. > > > > > > - virtio-1.0 over PCI (same scenarios as in the previous bullet). > > > > > > I never implemented virtio-1.0 over MMIO because it looked complicated > > > with no actual use case -- after aarch64/virt started supporting PCIe, > > > there was no real need to use MMIO, ever. So if you wanted virtio-1.0, > > > you were forced to use PCI on aarch64 as well, but that was fine (IMO). > > > > > > However, Gerd then invented the MicroVM (x86) machine type, which wanted > > > virtio-1.0 over MMIO. Gerd added the necessary *transport* code to edk2 > > > (I was surprised -- I thought it would be much more complex, and IIRC, > > > no *device driver* was necessary to modify). > > > > > > In fact I think the MicroVM machine type is the *only* option for > > > exercising the virtio-mmio transport on x86. (And because this is about > > > SeaBIOS, you certainly want x86, not aarch64/virt!) But I'm unsure if > > > MicroVM uses SeaBIOS at all -- Gerd can tell best. > > > > > > At least in theory, the test matrix is large: > > > - PCI vs. MMIO transport > > > - virtio-0.9.5 (legacy) vs. virtio-1.0 (modern) spec > > > - blk vs. scsi device model > > > > > > 8 cases. > > > > > > (With edk2, the test matrix was even larger, due to (a) supporting more > > > architectures than SeaBIOS (+aarch64), (b) supporting many more device > > > types (+rng +net +gpu +fs), (c) supporting guest memory encryption with > > > SEV on x86. But that matrix was *also smaller* in a sense, because > > > virtio-1.0 in combination with MMIO was not meant to be supported -- > > > until Gerd just went ahead and implemented it, that is :)) > > > > > > Laszlo > > > > > > BTW, it is not strictly necessary to keep find vqs > > after set features in legacy mode. Linux switched > > to setting features first back in 2009 and that > > works fine - legacy spec was more a de-facto thing anyway. > > So we can actually put the setting features directly in the front without > checking modern(VERSION_1). > > Is that so? > > Thanks. Yes, if that helps. > > > > -- > > MST > > _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Wed, Nov 09, 2022 at 09:59:17PM +0800, Xuan Zhuo wrote: > On Wed, 9 Nov 2022 08:28:00 -0500, "Michael S. Tsirkin" <mst@redhat.com> wrote: > > On Wed, Nov 09, 2022 at 09:17:25PM +0800, Xuan Zhuo wrote: > > > 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 finalizing features code in front of using device > > > 2. virtio-blk.mmio: put the finalizing features code in front of using device > > > 3. virtio-scsi.pci: is ok > > > 4. virtio-scsi.mmio: add set features before vp_find_vq() > > > > > > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> > > > > > > Please confirm you tested this with both modern and legacy > > and all these device types. Because e.g. scsi does not look > > like it would work. > > I have tested this: virtio-blk.pci both modern and legacy? and scsi? > I tried to start virtio-blk and virtio-scsi with MMIO, but it was not > successful. > > I want to know how to start Virtio-BLK and Virtio-SCSI based on MMIO? with microvm > > > > > > > > --- > > > src/hw/virtio-blk.c | 23 ++++++++++++++--------- > > > src/hw/virtio-scsi.c | 18 ++++++++++++++++++ > > > 2 files changed, 32 insertions(+), 9 deletions(-) > > > > > > diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c > > > index 9b4a05a..52eb08f 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,15 @@ 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 { > > > + } > > > + > > > + > > > > Why two empty lines? > > Will fix. > > > > > > + 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 +276,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 +294,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..cf131fb 100644 > > > --- a/src/hw/virtio-scsi.c > > > +++ b/src/hw/virtio-scsi.c > > > @@ -239,6 +239,24 @@ 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; > > > + u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; > > > + if (!(features & version1)) { > > > + dprintf(1, "modern device without virtio_1 feature bit: %pP\n", mmio); > > > + goto fail; > > > + } > > > + > > > + vp_set_features(vp, features & (version1 | iommu_platform)); > > > + status |= VIRTIO_CONFIG_S_FEATURES_OK; > > > + vp_set_status(vp, status); > > > + if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) { > > > + dprintf(1, "device didn't accept features: %pP\n", mmio); > > > + goto fail; > > > + } > > > + } > > > > > > This extra scope is quite ugly. > > Will fix. > > > > > > + > > > if (vp_find_vq(vp, 2, &vq) < 0 ) { > > > dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); > > > goto fail; > > > > I don't get it. Don't you need to test use_modern? And where is > > the code coming from? > > Do we need to distinguish between modern for mmio? Is there any error in my > understanding? > > Thanks. > > > > > > > > > -- > > > 2.32.0.3.g01195cf9f > > _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
Dear Xuan, Thank you for your patch. Am 09.11.22 um 14:17 schrieb Xuan Zhuo: A small nit for the summary/title (subject), maybe use imperative mood *finalize*. > 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 finalizing features code in front of using device > 2. virtio-blk.mmio: put the finalizing features code in front of using device > 3. virtio-scsi.pci: is ok > 4. virtio-scsi.mmio: add set features before vp_find_vq() Did you hit an error without the patch? If so, could you please document how to reproduce the issue? […] Kind regards, Paul _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
On Wed, 9 Nov 2022 14:24:06 +0100, Paul Menzel <pmenzel@molgen.mpg.de> wrote: > Dear Xuan, > > > Thank you for your patch. > > > Am 09.11.22 um 14:17 schrieb Xuan Zhuo: > > A small nit for the summary/title (subject), maybe use imperative mood > *finalize*. OK. > > > 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 finalizing features code in front of using device > > 2. virtio-blk.mmio: put the finalizing features code in front of using device > > 3. virtio-scsi.pci: is ok > > 4. virtio-scsi.mmio: add set features before vp_find_vq() > > Did you hit an error without the patch? If so, could you please document > how to reproduce the issue? > > […] https://www.mail-archive.com/qemu-devel@nongnu.org/msg920776.html qemu with patch https://www.mail-archive.com/qemu-devel@nongnu.org/msg920538.html Then: $ build/qemu-system-x86_64 -M accel=kvm -m 1G -cpu host -blockdev file,node-name=drive0,filename=test.img -device virtio-blk-pci,drive=drive0 qemu: queue_enable is only suppported in devices of virtio 1.0 or later. Thanks > > > Kind regards, > > Paul _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
© 2016 - 2023 Red Hat, Inc.