All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH RFC v6 00/20] qemu: towards virtio-1 host support
@ 2014-12-11 13:25 ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

And yet another iteration of virtio-1 support in qemu, tested with the
latest virtio kernel patches. Find it at

    git://github.com/cohuck/qemu virtio-1

Changes from v5:
- fixed stupid bug in "virtio: support more feature bits": we need to
  define a proper prop backend for 64 bit wide handling...
- don't negotiate revision 1 unless VERSION_1 is offered
- use 64 bit wide features in the whole of vhost (patch can probably be
  merged into the 64 bit extension for the rest of the code)

The bug I suspected in the revision-specific feature handling turned out
to be a messup on my side. There still seems to be something missing for
vhost-net to support virtio-1.

Cornelia Huck (17):
  virtio: cull virtio_bus_set_vdev_features
  virtio: feature bit manipulation helpers
  virtio: add feature checking helpers
  virtio: support more feature bits
  virtio: endianness checks for virtio 1.0 devices
  virtio: allow virtio-1 queue layout
  dataplane: allow virtio-1 devices
  s390x/virtio-ccw: support virtio-1 set_vq format
  virtio: disallow late feature changes for virtio-1
  virtio: allow to fail setting status
  s390x/virtio-ccw: enable virtio 1.0
  virtio-net: no writeable mac for virtio-1
  virtio-net: support longer header
  virtio-net: enable virtio 1.0
  virtio: support revision-specific features
  virtio-blk: revision specific feature bits
  vhost: 64 bit features

Thomas Huth (3):
  linux-headers/virtio_config: Update with VIRTIO_F_VERSION_1
  s390x/css: Add a callback for when subchannel gets disabled
  s390x/virtio-ccw: add virtio set-revision call

 hw/9pfs/virtio-9p-device.c                    |    4 +-
 hw/block/dataplane/virtio-blk.c               |    4 +-
 hw/block/virtio-blk.c                         |   44 +++--
 hw/char/virtio-serial-bus.c                   |    6 +-
 hw/core/qdev-properties.c                     |   58 ++++++
 hw/net/vhost_net.c                            |   12 +-
 hw/net/virtio-net.c                           |  100 ++++++-----
 hw/s390x/css.c                                |   12 ++
 hw/s390x/css.h                                |    1 +
 hw/s390x/s390-virtio-bus.c                    |    3 +-
 hw/s390x/s390-virtio-bus.h                    |    2 +-
 hw/s390x/virtio-ccw.c                         |  234 ++++++++++++++++++-------
 hw/s390x/virtio-ccw.h                         |   13 +-
 hw/scsi/vhost-scsi.c                          |    3 +-
 hw/scsi/virtio-scsi-dataplane.c               |    2 +-
 hw/scsi/virtio-scsi.c                         |   12 +-
 hw/virtio/Makefile.objs                       |    2 +-
 hw/virtio/dataplane/Makefile.objs             |    2 +-
 hw/virtio/dataplane/vring.c                   |   96 +++++-----
 hw/virtio/vhost.c                             |   14 +-
 hw/virtio/virtio-balloon.c                    |    4 +-
 hw/virtio/virtio-bus.c                        |   24 ++-
 hw/virtio/virtio-mmio.c                       |    9 +-
 hw/virtio/virtio-pci.c                        |    7 +-
 hw/virtio/virtio-pci.h                        |    2 +-
 hw/virtio/virtio-rng.c                        |    2 +-
 hw/virtio/virtio.c                            |  120 +++++++++----
 include/hw/qdev-properties.h                  |   12 ++
 include/hw/virtio/dataplane/vring-accessors.h |   75 ++++++++
 include/hw/virtio/dataplane/vring.h           |   14 +-
 include/hw/virtio/vhost.h                     |    6 +-
 include/hw/virtio/virtio-access.h             |    4 +
 include/hw/virtio/virtio-bus.h                |   14 +-
 include/hw/virtio/virtio-net.h                |   46 ++---
 include/hw/virtio/virtio-scsi.h               |    6 +-
 include/hw/virtio/virtio.h                    |   62 +++++--
 include/net/vhost_net.h                       |    4 +-
 linux-headers/linux/virtio_config.h           |    3 +
 38 files changed, 727 insertions(+), 311 deletions(-)
 create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 00/20] qemu: towards virtio-1 host support
@ 2014-12-11 13:25 ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

And yet another iteration of virtio-1 support in qemu, tested with the
latest virtio kernel patches. Find it at

    git://github.com/cohuck/qemu virtio-1

Changes from v5:
- fixed stupid bug in "virtio: support more feature bits": we need to
  define a proper prop backend for 64 bit wide handling...
- don't negotiate revision 1 unless VERSION_1 is offered
- use 64 bit wide features in the whole of vhost (patch can probably be
  merged into the 64 bit extension for the rest of the code)

The bug I suspected in the revision-specific feature handling turned out
to be a messup on my side. There still seems to be something missing for
vhost-net to support virtio-1.

Cornelia Huck (17):
  virtio: cull virtio_bus_set_vdev_features
  virtio: feature bit manipulation helpers
  virtio: add feature checking helpers
  virtio: support more feature bits
  virtio: endianness checks for virtio 1.0 devices
  virtio: allow virtio-1 queue layout
  dataplane: allow virtio-1 devices
  s390x/virtio-ccw: support virtio-1 set_vq format
  virtio: disallow late feature changes for virtio-1
  virtio: allow to fail setting status
  s390x/virtio-ccw: enable virtio 1.0
  virtio-net: no writeable mac for virtio-1
  virtio-net: support longer header
  virtio-net: enable virtio 1.0
  virtio: support revision-specific features
  virtio-blk: revision specific feature bits
  vhost: 64 bit features

Thomas Huth (3):
  linux-headers/virtio_config: Update with VIRTIO_F_VERSION_1
  s390x/css: Add a callback for when subchannel gets disabled
  s390x/virtio-ccw: add virtio set-revision call

 hw/9pfs/virtio-9p-device.c                    |    4 +-
 hw/block/dataplane/virtio-blk.c               |    4 +-
 hw/block/virtio-blk.c                         |   44 +++--
 hw/char/virtio-serial-bus.c                   |    6 +-
 hw/core/qdev-properties.c                     |   58 ++++++
 hw/net/vhost_net.c                            |   12 +-
 hw/net/virtio-net.c                           |  100 ++++++-----
 hw/s390x/css.c                                |   12 ++
 hw/s390x/css.h                                |    1 +
 hw/s390x/s390-virtio-bus.c                    |    3 +-
 hw/s390x/s390-virtio-bus.h                    |    2 +-
 hw/s390x/virtio-ccw.c                         |  234 ++++++++++++++++++-------
 hw/s390x/virtio-ccw.h                         |   13 +-
 hw/scsi/vhost-scsi.c                          |    3 +-
 hw/scsi/virtio-scsi-dataplane.c               |    2 +-
 hw/scsi/virtio-scsi.c                         |   12 +-
 hw/virtio/Makefile.objs                       |    2 +-
 hw/virtio/dataplane/Makefile.objs             |    2 +-
 hw/virtio/dataplane/vring.c                   |   96 +++++-----
 hw/virtio/vhost.c                             |   14 +-
 hw/virtio/virtio-balloon.c                    |    4 +-
 hw/virtio/virtio-bus.c                        |   24 ++-
 hw/virtio/virtio-mmio.c                       |    9 +-
 hw/virtio/virtio-pci.c                        |    7 +-
 hw/virtio/virtio-pci.h                        |    2 +-
 hw/virtio/virtio-rng.c                        |    2 +-
 hw/virtio/virtio.c                            |  120 +++++++++----
 include/hw/qdev-properties.h                  |   12 ++
 include/hw/virtio/dataplane/vring-accessors.h |   75 ++++++++
 include/hw/virtio/dataplane/vring.h           |   14 +-
 include/hw/virtio/vhost.h                     |    6 +-
 include/hw/virtio/virtio-access.h             |    4 +
 include/hw/virtio/virtio-bus.h                |   14 +-
 include/hw/virtio/virtio-net.h                |   46 ++---
 include/hw/virtio/virtio-scsi.h               |    6 +-
 include/hw/virtio/virtio.h                    |   62 +++++--
 include/net/vhost_net.h                       |    4 +-
 linux-headers/linux/virtio_config.h           |    3 +
 38 files changed, 727 insertions(+), 311 deletions(-)
 create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 01/20] linux-headers/virtio_config: Update with VIRTIO_F_VERSION_1
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

From: Thomas Huth <thuth@linux.vnet.ibm.com>

Add the new VIRTIO_F_VERSION_1 definition to the virtio_config.h
linux header.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 linux-headers/linux/virtio_config.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/linux-headers/linux/virtio_config.h b/linux-headers/linux/virtio_config.h
index 75dc20b..16aa289 100644
--- a/linux-headers/linux/virtio_config.h
+++ b/linux-headers/linux/virtio_config.h
@@ -54,4 +54,7 @@
 /* Can the device handle any descriptor layout? */
 #define VIRTIO_F_ANY_LAYOUT		27
 
+/* v1.0 compliant. */
+#define VIRTIO_F_VERSION_1		32
+
 #endif /* _LINUX_VIRTIO_CONFIG_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 01/20] linux-headers/virtio_config: Update with VIRTIO_F_VERSION_1
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

From: Thomas Huth <thuth@linux.vnet.ibm.com>

Add the new VIRTIO_F_VERSION_1 definition to the virtio_config.h
linux header.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 linux-headers/linux/virtio_config.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/linux-headers/linux/virtio_config.h b/linux-headers/linux/virtio_config.h
index 75dc20b..16aa289 100644
--- a/linux-headers/linux/virtio_config.h
+++ b/linux-headers/linux/virtio_config.h
@@ -54,4 +54,7 @@
 /* Can the device handle any descriptor layout? */
 #define VIRTIO_F_ANY_LAYOUT		27
 
+/* v1.0 compliant. */
+#define VIRTIO_F_VERSION_1		32
+
 #endif /* _LINUX_VIRTIO_CONFIG_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 02/20] virtio: cull virtio_bus_set_vdev_features
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

The only user of this function was virtio-ccw, and it should use
virtio_set_features() like everybody else: We need to make sure
that bad features are masked out properly, which this function did
not do.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c          |    3 +--
 hw/virtio/virtio-bus.c         |   14 --------------
 include/hw/virtio/virtio-bus.h |    3 ---
 3 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index ea236c9..84f17bc 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -400,8 +400,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
                                        ccw.cda + sizeof(features.features));
             features.features = ldl_le_phys(&address_space_memory, ccw.cda);
             if (features.index < ARRAY_SIZE(dev->host_features)) {
-                virtio_bus_set_vdev_features(&dev->bus, features.features);
-                vdev->guest_features = features.features;
+                virtio_set_features(vdev, features.features);
             } else {
                 /*
                  * If the guest supports more feature bits, assert that it
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index eb77019..a8ffa07 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -109,20 +109,6 @@ uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
     return k->get_features(vdev, requested_features);
 }
 
-/* Set the features of the plugged device. */
-void virtio_bus_set_vdev_features(VirtioBusState *bus,
-                                      uint32_t requested_features)
-{
-    VirtIODevice *vdev = virtio_bus_get_device(bus);
-    VirtioDeviceClass *k;
-
-    assert(vdev != NULL);
-    k = VIRTIO_DEVICE_GET_CLASS(vdev);
-    if (k->set_features != NULL) {
-        k->set_features(vdev, requested_features);
-    }
-}
-
 /* Get bad features of the plugged device. */
 uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
 {
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 0756545..0d2e7b4 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -84,9 +84,6 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
 /* Get the features of the plugged device. */
 uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
                                     uint32_t requested_features);
-/* Set the features of the plugged device. */
-void virtio_bus_set_vdev_features(VirtioBusState *bus,
-                                  uint32_t requested_features);
 /* Get bad features of the plugged device. */
 uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
 /* Get config of the plugged device. */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 02/20] virtio: cull virtio_bus_set_vdev_features
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

The only user of this function was virtio-ccw, and it should use
virtio_set_features() like everybody else: We need to make sure
that bad features are masked out properly, which this function did
not do.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c          |    3 +--
 hw/virtio/virtio-bus.c         |   14 --------------
 include/hw/virtio/virtio-bus.h |    3 ---
 3 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index ea236c9..84f17bc 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -400,8 +400,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
                                        ccw.cda + sizeof(features.features));
             features.features = ldl_le_phys(&address_space_memory, ccw.cda);
             if (features.index < ARRAY_SIZE(dev->host_features)) {
-                virtio_bus_set_vdev_features(&dev->bus, features.features);
-                vdev->guest_features = features.features;
+                virtio_set_features(vdev, features.features);
             } else {
                 /*
                  * If the guest supports more feature bits, assert that it
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index eb77019..a8ffa07 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -109,20 +109,6 @@ uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
     return k->get_features(vdev, requested_features);
 }
 
-/* Set the features of the plugged device. */
-void virtio_bus_set_vdev_features(VirtioBusState *bus,
-                                      uint32_t requested_features)
-{
-    VirtIODevice *vdev = virtio_bus_get_device(bus);
-    VirtioDeviceClass *k;
-
-    assert(vdev != NULL);
-    k = VIRTIO_DEVICE_GET_CLASS(vdev);
-    if (k->set_features != NULL) {
-        k->set_features(vdev, requested_features);
-    }
-}
-
 /* Get bad features of the plugged device. */
 uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
 {
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 0756545..0d2e7b4 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -84,9 +84,6 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
 /* Get the features of the plugged device. */
 uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
                                     uint32_t requested_features);
-/* Set the features of the plugged device. */
-void virtio_bus_set_vdev_features(VirtioBusState *bus,
-                                  uint32_t requested_features);
 /* Get bad features of the plugged device. */
 uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
 /* Get config of the plugged device. */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 03/20] virtio: feature bit manipulation helpers
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Add virtio_{add,clear}_feature helper functions for manipulating a
feature bits variable. This has some benefits over open coding:
- add check that the bit is in a sane range
- make it obvious at a glance what is going on
- have a central point to change when we want to extend feature bits

Convert existing code manipulating features to use the new helpers.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/9pfs/virtio-9p-device.c  |    2 +-
 hw/block/virtio-blk.c       |   16 ++++++++--------
 hw/char/virtio-serial-bus.c |    2 +-
 hw/net/virtio-net.c         |   34 +++++++++++++++++-----------------
 hw/s390x/virtio-ccw.c       |    4 ++--
 hw/virtio/virtio-mmio.c     |    2 +-
 hw/virtio/virtio-pci.c      |    4 ++--
 include/hw/virtio/virtio.h  |   12 ++++++++++++
 8 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 2572747..30492ec 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -23,7 +23,7 @@
 
 static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
 {
-    features |= 1 << VIRTIO_9P_MOUNT_TAG;
+    virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
     return features;
 }
 
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index b19b102..3f76e2a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -568,20 +568,20 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
-    features |= (1 << VIRTIO_BLK_F_SEG_MAX);
-    features |= (1 << VIRTIO_BLK_F_GEOMETRY);
-    features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
-    features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
-    features |= (1 << VIRTIO_BLK_F_SCSI);
+    virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
+    virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
+    virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
+    virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
+    virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
 
     if (s->conf.config_wce) {
-        features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
+        virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
     }
     if (blk_enable_write_cache(s->blk)) {
-        features |= (1 << VIRTIO_BLK_F_WCE);
+        virtio_add_feature(&features, VIRTIO_BLK_F_WCE);
     }
     if (blk_is_read_only(s->blk)) {
-        features |= 1 << VIRTIO_BLK_F_RO;
+        virtio_add_feature(&features, VIRTIO_BLK_F_RO);
     }
 
     return features;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index a7b1b68..0f637db 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -474,7 +474,7 @@ static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
     vser = VIRTIO_SERIAL(vdev);
 
     if (vser->bus.max_nr_ports > 1) {
-        features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
+        virtio_add_feature(&features, VIRTIO_CONSOLE_F_MULTIPORT);
     }
     return features;
 }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index e574bd4..f1aa100 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -446,23 +446,23 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
     VirtIONet *n = VIRTIO_NET(vdev);
     NetClientState *nc = qemu_get_queue(n->nic);
 
-    features |= (1 << VIRTIO_NET_F_MAC);
+    virtio_add_feature(&features, VIRTIO_NET_F_MAC);
 
     if (!peer_has_vnet_hdr(n)) {
-        features &= ~(0x1 << VIRTIO_NET_F_CSUM);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);
+        virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
 
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
     }
 
     if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
     }
 
     if (!get_vhost_net(nc->peer)) {
@@ -477,11 +477,11 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
 
     /* Linux kernel 2.6.25.  It understood MAC (as everyone must),
      * but also these: */
-    features |= (1 << VIRTIO_NET_F_MAC);
-    features |= (1 << VIRTIO_NET_F_CSUM);
-    features |= (1 << VIRTIO_NET_F_HOST_TSO4);
-    features |= (1 << VIRTIO_NET_F_HOST_TSO6);
-    features |= (1 << VIRTIO_NET_F_HOST_ECN);
+    virtio_add_feature(&features, VIRTIO_NET_F_MAC);
+    virtio_add_feature(&features, VIRTIO_NET_F_CSUM);
+    virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO4);
+    virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO6);
+    virtio_add_feature(&features, VIRTIO_NET_F_HOST_ECN);
 
     return features;
 }
@@ -1560,7 +1560,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
 void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
 {
     int i, config_size = 0;
-    host_features |= (1 << VIRTIO_NET_F_MAC);
+    virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
     for (i = 0; feature_sizes[i].flags != 0; i++) {
         if (host_features & feature_sizes[i].flags) {
             config_size = MAX(feature_sizes[i].end, config_size);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 84f17bc..3fee4aa 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -743,8 +743,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
                                                          dev->host_features[0]);
 
-    dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
-    dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
+    virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE);
 
     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                           parent->hotplugged, 1);
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 2450c13..10123f3 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -349,7 +349,7 @@ static void virtio_mmio_device_plugged(DeviceState *opaque)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
 
-    proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
     proxy->host_features = virtio_bus_get_vdev_features(&proxy->bus,
                                                         proxy->host_features);
 }
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index dde1d73..e7969bf 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -996,8 +996,8 @@ static void virtio_pci_device_plugged(DeviceState *d)
         proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
     }
 
-    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
-    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
+    virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&proxy->host_features, VIRTIO_F_BAD_FEATURE);
     proxy->host_features = virtio_bus_get_vdev_features(bus,
                                                       proxy->host_features);
 }
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 0726d76..2fede2e 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -266,6 +266,18 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
 void virtio_queue_notify_vq(VirtQueue *vq);
 void virtio_irq(VirtQueue *vq);
 
+static inline void virtio_add_feature(uint32_t *features, unsigned int fbit)
+{
+    assert(fbit < 32);
+    *features |= (1 << fbit);
+}
+
+static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
+{
+    assert(fbit < 32);
+    *features &= ~(1 << fbit);
+}
+
 static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 {
     assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 03/20] virtio: feature bit manipulation helpers
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Add virtio_{add,clear}_feature helper functions for manipulating a
feature bits variable. This has some benefits over open coding:
- add check that the bit is in a sane range
- make it obvious at a glance what is going on
- have a central point to change when we want to extend feature bits

Convert existing code manipulating features to use the new helpers.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/9pfs/virtio-9p-device.c  |    2 +-
 hw/block/virtio-blk.c       |   16 ++++++++--------
 hw/char/virtio-serial-bus.c |    2 +-
 hw/net/virtio-net.c         |   34 +++++++++++++++++-----------------
 hw/s390x/virtio-ccw.c       |    4 ++--
 hw/virtio/virtio-mmio.c     |    2 +-
 hw/virtio/virtio-pci.c      |    4 ++--
 include/hw/virtio/virtio.h  |   12 ++++++++++++
 8 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 2572747..30492ec 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -23,7 +23,7 @@
 
 static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
 {
-    features |= 1 << VIRTIO_9P_MOUNT_TAG;
+    virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
     return features;
 }
 
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index b19b102..3f76e2a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -568,20 +568,20 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
-    features |= (1 << VIRTIO_BLK_F_SEG_MAX);
-    features |= (1 << VIRTIO_BLK_F_GEOMETRY);
-    features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
-    features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
-    features |= (1 << VIRTIO_BLK_F_SCSI);
+    virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
+    virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
+    virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
+    virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
+    virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
 
     if (s->conf.config_wce) {
-        features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
+        virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
     }
     if (blk_enable_write_cache(s->blk)) {
-        features |= (1 << VIRTIO_BLK_F_WCE);
+        virtio_add_feature(&features, VIRTIO_BLK_F_WCE);
     }
     if (blk_is_read_only(s->blk)) {
-        features |= 1 << VIRTIO_BLK_F_RO;
+        virtio_add_feature(&features, VIRTIO_BLK_F_RO);
     }
 
     return features;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index a7b1b68..0f637db 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -474,7 +474,7 @@ static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
     vser = VIRTIO_SERIAL(vdev);
 
     if (vser->bus.max_nr_ports > 1) {
-        features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
+        virtio_add_feature(&features, VIRTIO_CONSOLE_F_MULTIPORT);
     }
     return features;
 }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index e574bd4..f1aa100 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -446,23 +446,23 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
     VirtIONet *n = VIRTIO_NET(vdev);
     NetClientState *nc = qemu_get_queue(n->nic);
 
-    features |= (1 << VIRTIO_NET_F_MAC);
+    virtio_add_feature(&features, VIRTIO_NET_F_MAC);
 
     if (!peer_has_vnet_hdr(n)) {
-        features &= ~(0x1 << VIRTIO_NET_F_CSUM);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);
+        virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
 
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
     }
 
     if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
+        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
+        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
     }
 
     if (!get_vhost_net(nc->peer)) {
@@ -477,11 +477,11 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
 
     /* Linux kernel 2.6.25.  It understood MAC (as everyone must),
      * but also these: */
-    features |= (1 << VIRTIO_NET_F_MAC);
-    features |= (1 << VIRTIO_NET_F_CSUM);
-    features |= (1 << VIRTIO_NET_F_HOST_TSO4);
-    features |= (1 << VIRTIO_NET_F_HOST_TSO6);
-    features |= (1 << VIRTIO_NET_F_HOST_ECN);
+    virtio_add_feature(&features, VIRTIO_NET_F_MAC);
+    virtio_add_feature(&features, VIRTIO_NET_F_CSUM);
+    virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO4);
+    virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO6);
+    virtio_add_feature(&features, VIRTIO_NET_F_HOST_ECN);
 
     return features;
 }
@@ -1560,7 +1560,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
 void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
 {
     int i, config_size = 0;
-    host_features |= (1 << VIRTIO_NET_F_MAC);
+    virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
     for (i = 0; feature_sizes[i].flags != 0; i++) {
         if (host_features & feature_sizes[i].flags) {
             config_size = MAX(feature_sizes[i].end, config_size);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 84f17bc..3fee4aa 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -743,8 +743,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
                                                          dev->host_features[0]);
 
-    dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
-    dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
+    virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE);
 
     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                           parent->hotplugged, 1);
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 2450c13..10123f3 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -349,7 +349,7 @@ static void virtio_mmio_device_plugged(DeviceState *opaque)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
 
-    proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
     proxy->host_features = virtio_bus_get_vdev_features(&proxy->bus,
                                                         proxy->host_features);
 }
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index dde1d73..e7969bf 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -996,8 +996,8 @@ static void virtio_pci_device_plugged(DeviceState *d)
         proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
     }
 
-    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
-    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
+    virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&proxy->host_features, VIRTIO_F_BAD_FEATURE);
     proxy->host_features = virtio_bus_get_vdev_features(bus,
                                                       proxy->host_features);
 }
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 0726d76..2fede2e 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -266,6 +266,18 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
 void virtio_queue_notify_vq(VirtQueue *vq);
 void virtio_irq(VirtQueue *vq);
 
+static inline void virtio_add_feature(uint32_t *features, unsigned int fbit)
+{
+    assert(fbit < 32);
+    *features |= (1 << fbit);
+}
+
+static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
+{
+    assert(fbit < 32);
+    *features &= ~(1 << fbit);
+}
+
 static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 {
     assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Add a helper function for checking whether a bit is set in the guest
features for a vdev as well as one that works on a feature bit set.

Convert code that open-coded this: It cleans up the code and makes it
easier to extend the guest feature bits.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/block/virtio-blk.c       |    7 ++-----
 hw/char/virtio-serial-bus.c |    2 +-
 hw/net/virtio-net.c         |   23 +++++++++++++----------
 hw/scsi/virtio-scsi.c       |    8 ++++----
 hw/virtio/dataplane/vring.c |   10 +++++-----
 hw/virtio/virtio-balloon.c  |    2 +-
 hw/virtio/virtio.c          |   10 +++++-----
 include/hw/virtio/virtio.h  |   11 +++++++++++
 8 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 3f76e2a..27f263a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -590,7 +590,6 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
 static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
-    uint32_t features;
 
     if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
                                     VIRTIO_CONFIG_S_DRIVER_OK))) {
@@ -601,8 +600,6 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
         return;
     }
 
-    features = vdev->guest_features;
-
     /* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send
      * cache flushes.  Thus, the "auto writethrough" behavior is never
      * necessary for guests that support the VIRTIO_BLK_F_CONFIG_WCE feature.
@@ -618,10 +615,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
      *
      * s->blk would erroneously be placed in writethrough mode.
      */
-    if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
+    if (!virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) {
         aio_context_acquire(blk_get_aio_context(s->blk));
         blk_set_enable_write_cache(s->blk,
-                                   !!(features & (1 << VIRTIO_BLK_F_WCE)));
+                                   virtio_has_feature(vdev, VIRTIO_BLK_F_WCE));
         aio_context_release(blk_get_aio_context(s->blk));
     }
 }
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 0f637db..d49883f 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -75,7 +75,7 @@ static VirtIOSerialPort *find_port_by_name(char *name)
 static bool use_multiport(VirtIOSerial *vser)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(vser);
-    return vdev->guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
+    return virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT);
 }
 
 static size_t write_to_port(VirtIOSerialPort *port,
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f1aa100..9f3c58a 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -86,7 +86,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
 
     memcpy(&netcfg, config, n->config_size);
 
-    if (!(vdev->guest_features >> VIRTIO_NET_F_CTRL_MAC_ADDR & 1) &&
+    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
         memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
         memcpy(n->mac, netcfg.mac, ETH_ALEN);
         qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
@@ -305,7 +305,7 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
     info->multicast_table = str_list;
     info->vlan_table = get_vlan_table(n);
 
-    if (!((1 << VIRTIO_NET_F_CTRL_VLAN) & vdev->guest_features)) {
+    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VLAN)) {
         info->vlan = RX_STATE_ALL;
     } else if (!info->vlan_table) {
         info->vlan = RX_STATE_NONE;
@@ -519,9 +519,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
     VirtIONet *n = VIRTIO_NET(vdev);
     int i;
 
-    virtio_net_set_multiqueue(n, !!(features & (1 << VIRTIO_NET_F_MQ)));
+    virtio_net_set_multiqueue(n,
+                              __virtio_has_feature(features, VIRTIO_NET_F_MQ));
 
-    virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
+    virtio_net_set_mrg_rx_bufs(n,
+                               __virtio_has_feature(features,
+                                                    VIRTIO_NET_F_MRG_RXBUF));
 
     if (n->has_vnet_hdr) {
         n->curr_guest_offloads =
@@ -538,7 +541,7 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
         vhost_net_ack_features(get_vhost_net(nc->peer), features);
     }
 
-    if ((1 << VIRTIO_NET_F_CTRL_VLAN) & features) {
+    if (__virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) {
         memset(n->vlans, 0, MAX_VLAN >> 3);
     } else {
         memset(n->vlans, 0xff, MAX_VLAN >> 3);
@@ -585,7 +588,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
     uint64_t offloads;
     size_t s;
 
-    if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
+    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
         return VIRTIO_NET_ERR;
     }
 
@@ -1378,7 +1381,7 @@ static void virtio_net_save_device(VirtIODevice *vdev, QEMUFile *f)
         }
     }
 
-    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+    if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
         qemu_put_be64(f, n->curr_guest_offloads);
     }
 }
@@ -1486,7 +1489,7 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
         }
     }
 
-    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+    if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
         n->curr_guest_offloads = qemu_get_be64(f);
     } else {
         n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
@@ -1513,8 +1516,8 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
         qemu_get_subqueue(n->nic, i)->link_down = link_down;
     }
 
-    if (vdev->guest_features & (0x1 << VIRTIO_NET_F_GUEST_ANNOUNCE) &&
-        vdev->guest_features & (0x1 << VIRTIO_NET_F_CTRL_VQ)) {
+    if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE) &&
+        virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) {
         n->announce_counter = SELF_ANNOUNCE_ROUNDS;
         timer_mod(n->announce_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL));
     }
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ef48550..56c92fb 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
      *
      * TODO: always disable this workaround for virtio 1.0 devices.
      */
-    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
+    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
         req_size = req->elem.out_sg[0].iov_len;
         resp_size = req->elem.in_sg[0].iov_len;
     }
@@ -748,7 +748,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
     VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
     VirtIODevice *vdev = VIRTIO_DEVICE(s);
 
-    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
+    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
         dev->type != TYPE_ROM) {
         virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
                                sense.asc | (sense.ascq << 8));
@@ -769,7 +769,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
         blk_op_block_all(sd->conf.blk, s->blocker);
     }
 
-    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
+    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
         virtio_scsi_push_event(s, sd,
                                VIRTIO_SCSI_T_TRANSPORT_RESET,
                                VIRTIO_SCSI_EVT_RESET_RESCAN);
@@ -783,7 +783,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
     VirtIOSCSI *s = VIRTIO_SCSI(vdev);
     SCSIDevice *sd = SCSI_DEVICE(dev);
 
-    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
+    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
         virtio_scsi_push_event(s, sd,
                                VIRTIO_SCSI_T_TRANSPORT_RESET,
                                VIRTIO_SCSI_EVT_RESET_REMOVED);
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 61f6d83..6e283fc 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -103,7 +103,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
 /* Disable guest->host notifies */
 void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 {
-    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring->vr.used->flags |= VRING_USED_F_NO_NOTIFY;
     }
 }
@@ -114,7 +114,7 @@ void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
  */
 bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
 {
-    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(&vring->vr) = vring->vr.avail->idx;
     } else {
         vring->vr.used->flags &= ~VRING_USED_F_NO_NOTIFY;
@@ -133,12 +133,12 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
      * interrupts. */
     smp_mb();
 
-    if ((vdev->guest_features & VIRTIO_F_NOTIFY_ON_EMPTY) &&
+    if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
         unlikely(vring->vr.avail->idx == vring->last_avail_idx)) {
         return true;
     }
 
-    if (!(vdev->guest_features & VIRTIO_RING_F_EVENT_IDX)) {
+    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         return !(vring->vr.avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
     }
     old = vring->signalled_used;
@@ -388,7 +388,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 
     /* On success, increment avail index. */
     vring->last_avail_idx++;
-    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(&vring->vr) = vring->last_avail_idx;
     }
 
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 7bfbb75..21e449a 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -69,7 +69,7 @@ static inline void reset_stats(VirtIOBalloon *dev)
 static bool balloon_stats_supported(const VirtIOBalloon *s)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(s);
-    return vdev->guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ);
+    return virtio_has_feature(vdev, VIRTIO_BALLOON_F_STATS_VQ);
 }
 
 static bool balloon_stats_enabled(const VirtIOBalloon *s)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 013979a..5814433 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -217,7 +217,7 @@ static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
 void virtio_queue_set_notification(VirtQueue *vq, int enable)
 {
     vq->notification = enable;
-    if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(vq, vring_avail_idx(vq));
     } else if (enable) {
         vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
@@ -468,7 +468,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
     max = vq->vring.num;
 
     i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
-    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(vq, vq->last_avail_idx);
     }
 
@@ -839,12 +839,12 @@ static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
     /* We need to expose used array entries before checking used event. */
     smp_mb();
     /* Always notify when queue is empty (when feature acknowledge) */
-    if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
-         !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
+    if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
+        !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx) {
         return true;
     }
 
-    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
     }
 
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 2fede2e..f6c0379 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -278,6 +278,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
     *features &= ~(1 << fbit);
 }
 
+static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
+{
+    assert(fbit < 32);
+    return !!(features & (1 << fbit));
+}
+
+static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
+{
+    return __virtio_has_feature(vdev->guest_features, fbit);
+}
+
 static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 {
     assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 04/20] virtio: add feature checking helpers
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Add a helper function for checking whether a bit is set in the guest
features for a vdev as well as one that works on a feature bit set.

Convert code that open-coded this: It cleans up the code and makes it
easier to extend the guest feature bits.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/block/virtio-blk.c       |    7 ++-----
 hw/char/virtio-serial-bus.c |    2 +-
 hw/net/virtio-net.c         |   23 +++++++++++++----------
 hw/scsi/virtio-scsi.c       |    8 ++++----
 hw/virtio/dataplane/vring.c |   10 +++++-----
 hw/virtio/virtio-balloon.c  |    2 +-
 hw/virtio/virtio.c          |   10 +++++-----
 include/hw/virtio/virtio.h  |   11 +++++++++++
 8 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 3f76e2a..27f263a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -590,7 +590,6 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
 static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
-    uint32_t features;
 
     if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
                                     VIRTIO_CONFIG_S_DRIVER_OK))) {
@@ -601,8 +600,6 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
         return;
     }
 
-    features = vdev->guest_features;
-
     /* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send
      * cache flushes.  Thus, the "auto writethrough" behavior is never
      * necessary for guests that support the VIRTIO_BLK_F_CONFIG_WCE feature.
@@ -618,10 +615,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
      *
      * s->blk would erroneously be placed in writethrough mode.
      */
-    if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
+    if (!virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) {
         aio_context_acquire(blk_get_aio_context(s->blk));
         blk_set_enable_write_cache(s->blk,
-                                   !!(features & (1 << VIRTIO_BLK_F_WCE)));
+                                   virtio_has_feature(vdev, VIRTIO_BLK_F_WCE));
         aio_context_release(blk_get_aio_context(s->blk));
     }
 }
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 0f637db..d49883f 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -75,7 +75,7 @@ static VirtIOSerialPort *find_port_by_name(char *name)
 static bool use_multiport(VirtIOSerial *vser)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(vser);
-    return vdev->guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
+    return virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT);
 }
 
 static size_t write_to_port(VirtIOSerialPort *port,
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f1aa100..9f3c58a 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -86,7 +86,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
 
     memcpy(&netcfg, config, n->config_size);
 
-    if (!(vdev->guest_features >> VIRTIO_NET_F_CTRL_MAC_ADDR & 1) &&
+    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
         memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
         memcpy(n->mac, netcfg.mac, ETH_ALEN);
         qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
@@ -305,7 +305,7 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
     info->multicast_table = str_list;
     info->vlan_table = get_vlan_table(n);
 
-    if (!((1 << VIRTIO_NET_F_CTRL_VLAN) & vdev->guest_features)) {
+    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VLAN)) {
         info->vlan = RX_STATE_ALL;
     } else if (!info->vlan_table) {
         info->vlan = RX_STATE_NONE;
@@ -519,9 +519,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
     VirtIONet *n = VIRTIO_NET(vdev);
     int i;
 
-    virtio_net_set_multiqueue(n, !!(features & (1 << VIRTIO_NET_F_MQ)));
+    virtio_net_set_multiqueue(n,
+                              __virtio_has_feature(features, VIRTIO_NET_F_MQ));
 
-    virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
+    virtio_net_set_mrg_rx_bufs(n,
+                               __virtio_has_feature(features,
+                                                    VIRTIO_NET_F_MRG_RXBUF));
 
     if (n->has_vnet_hdr) {
         n->curr_guest_offloads =
@@ -538,7 +541,7 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
         vhost_net_ack_features(get_vhost_net(nc->peer), features);
     }
 
-    if ((1 << VIRTIO_NET_F_CTRL_VLAN) & features) {
+    if (__virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) {
         memset(n->vlans, 0, MAX_VLAN >> 3);
     } else {
         memset(n->vlans, 0xff, MAX_VLAN >> 3);
@@ -585,7 +588,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
     uint64_t offloads;
     size_t s;
 
-    if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
+    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
         return VIRTIO_NET_ERR;
     }
 
@@ -1378,7 +1381,7 @@ static void virtio_net_save_device(VirtIODevice *vdev, QEMUFile *f)
         }
     }
 
-    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+    if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
         qemu_put_be64(f, n->curr_guest_offloads);
     }
 }
@@ -1486,7 +1489,7 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
         }
     }
 
-    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+    if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
         n->curr_guest_offloads = qemu_get_be64(f);
     } else {
         n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
@@ -1513,8 +1516,8 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
         qemu_get_subqueue(n->nic, i)->link_down = link_down;
     }
 
-    if (vdev->guest_features & (0x1 << VIRTIO_NET_F_GUEST_ANNOUNCE) &&
-        vdev->guest_features & (0x1 << VIRTIO_NET_F_CTRL_VQ)) {
+    if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE) &&
+        virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) {
         n->announce_counter = SELF_ANNOUNCE_ROUNDS;
         timer_mod(n->announce_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL));
     }
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ef48550..56c92fb 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
      *
      * TODO: always disable this workaround for virtio 1.0 devices.
      */
-    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
+    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
         req_size = req->elem.out_sg[0].iov_len;
         resp_size = req->elem.in_sg[0].iov_len;
     }
@@ -748,7 +748,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
     VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
     VirtIODevice *vdev = VIRTIO_DEVICE(s);
 
-    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
+    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
         dev->type != TYPE_ROM) {
         virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
                                sense.asc | (sense.ascq << 8));
@@ -769,7 +769,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
         blk_op_block_all(sd->conf.blk, s->blocker);
     }
 
-    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
+    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
         virtio_scsi_push_event(s, sd,
                                VIRTIO_SCSI_T_TRANSPORT_RESET,
                                VIRTIO_SCSI_EVT_RESET_RESCAN);
@@ -783,7 +783,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
     VirtIOSCSI *s = VIRTIO_SCSI(vdev);
     SCSIDevice *sd = SCSI_DEVICE(dev);
 
-    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
+    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
         virtio_scsi_push_event(s, sd,
                                VIRTIO_SCSI_T_TRANSPORT_RESET,
                                VIRTIO_SCSI_EVT_RESET_REMOVED);
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 61f6d83..6e283fc 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -103,7 +103,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
 /* Disable guest->host notifies */
 void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 {
-    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring->vr.used->flags |= VRING_USED_F_NO_NOTIFY;
     }
 }
@@ -114,7 +114,7 @@ void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
  */
 bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
 {
-    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(&vring->vr) = vring->vr.avail->idx;
     } else {
         vring->vr.used->flags &= ~VRING_USED_F_NO_NOTIFY;
@@ -133,12 +133,12 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
      * interrupts. */
     smp_mb();
 
-    if ((vdev->guest_features & VIRTIO_F_NOTIFY_ON_EMPTY) &&
+    if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
         unlikely(vring->vr.avail->idx == vring->last_avail_idx)) {
         return true;
     }
 
-    if (!(vdev->guest_features & VIRTIO_RING_F_EVENT_IDX)) {
+    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         return !(vring->vr.avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
     }
     old = vring->signalled_used;
@@ -388,7 +388,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 
     /* On success, increment avail index. */
     vring->last_avail_idx++;
-    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(&vring->vr) = vring->last_avail_idx;
     }
 
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 7bfbb75..21e449a 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -69,7 +69,7 @@ static inline void reset_stats(VirtIOBalloon *dev)
 static bool balloon_stats_supported(const VirtIOBalloon *s)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(s);
-    return vdev->guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ);
+    return virtio_has_feature(vdev, VIRTIO_BALLOON_F_STATS_VQ);
 }
 
 static bool balloon_stats_enabled(const VirtIOBalloon *s)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 013979a..5814433 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -217,7 +217,7 @@ static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
 void virtio_queue_set_notification(VirtQueue *vq, int enable)
 {
     vq->notification = enable;
-    if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(vq, vring_avail_idx(vq));
     } else if (enable) {
         vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
@@ -468,7 +468,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
     max = vq->vring.num;
 
     i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
-    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(vq, vq->last_avail_idx);
     }
 
@@ -839,12 +839,12 @@ static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
     /* We need to expose used array entries before checking used event. */
     smp_mb();
     /* Always notify when queue is empty (when feature acknowledge) */
-    if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
-         !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
+    if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
+        !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx) {
         return true;
     }
 
-    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
     }
 
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 2fede2e..f6c0379 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -278,6 +278,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
     *features &= ~(1 << fbit);
 }
 
+static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
+{
+    assert(fbit < 32);
+    return !!(features & (1 << fbit));
+}
+
+static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
+{
+    return __virtio_has_feature(vdev->guest_features, fbit);
+}
+
 static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 {
     assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

With virtio-1, we support more than 32 feature bits. Let's extend both
host and guest features to 64, which should suffice for a while.

vhost and migration have been ignored for now.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/9pfs/virtio-9p-device.c      |    2 +-
 hw/block/virtio-blk.c           |    2 +-
 hw/char/virtio-serial-bus.c     |    2 +-
 hw/core/qdev-properties.c       |   58 +++++++++++++++++++++++++++++++++++++++
 hw/net/virtio-net.c             |   22 +++++++--------
 hw/s390x/s390-virtio-bus.c      |    3 +-
 hw/s390x/s390-virtio-bus.h      |    2 +-
 hw/s390x/virtio-ccw.c           |   39 +++++++++++++++-----------
 hw/s390x/virtio-ccw.h           |    5 +---
 hw/scsi/vhost-scsi.c            |    3 +-
 hw/scsi/virtio-scsi.c           |    4 +--
 hw/virtio/virtio-balloon.c      |    2 +-
 hw/virtio/virtio-bus.c          |    6 ++--
 hw/virtio/virtio-mmio.c         |    4 +--
 hw/virtio/virtio-pci.c          |    3 +-
 hw/virtio/virtio-pci.h          |    2 +-
 hw/virtio/virtio-rng.c          |    2 +-
 hw/virtio/virtio.c              |   13 +++++----
 include/hw/qdev-properties.h    |   12 ++++++++
 include/hw/virtio/virtio-bus.h  |    8 +++---
 include/hw/virtio/virtio-net.h  |   46 +++++++++++++++----------------
 include/hw/virtio/virtio-scsi.h |    6 ++--
 include/hw/virtio/virtio.h      |   38 ++++++++++++++-----------
 23 files changed, 184 insertions(+), 100 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 30492ec..60f9ff9 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -21,7 +21,7 @@
 #include "virtio-9p-coth.h"
 #include "hw/virtio/virtio-access.h"
 
-static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features)
 {
     virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
     return features;
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 27f263a..9cfae66 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -564,7 +564,7 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
     aio_context_release(blk_get_aio_context(s->blk));
 }
 
-static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index d49883f..2d2ed9c 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -467,7 +467,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
 {
 }
 
-static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t get_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIOSerial *vser;
 
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 2e47f70..1b24818 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -125,6 +125,64 @@ PropertyInfo qdev_prop_bit = {
     .set   = prop_set_bit,
 };
 
+/* Bit on a 64 bit value*/
+
+static uint64_t qdev_get_prop_mask64(Property *prop)
+{
+    assert(prop->info == &qdev_prop_bit64);
+    return 0x1ULL << prop->bitnr;
+}
+
+static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
+{
+    uint64_t *p = qdev_get_prop_ptr(dev, props);
+    uint64_t mask = qdev_get_prop_mask64(props);
+    if (val) {
+        *p |= mask;
+    } else {
+        *p &= ~mask;
+    }
+}
+
+static void prop_get_bit64(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint64_t *p = qdev_get_prop_ptr(dev, prop);
+    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
+
+    visit_type_bool(v, &value, name, errp);
+}
+
+static void prop_set_bit64(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    bool value;
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
+    visit_type_bool(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    bit64_prop_set(dev, prop, value);
+}
+
+PropertyInfo qdev_prop_bit64 = {
+    .name  = "bool",
+    .description = "on/off",
+    .get   = prop_get_bit64,
+    .set   = prop_set_bit64,
+};
+
 /* --- bool --- */
 
 static void get_bool(Object *obj, Visitor *v, void *opaque,
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9f3c58a..d6d1b98 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -38,16 +38,16 @@
     (offsetof(container, field) + sizeof(((container *)0)->field))
 
 typedef struct VirtIOFeature {
-    uint32_t flags;
+    uint64_t flags;
     size_t end;
 } VirtIOFeature;
 
 static VirtIOFeature feature_sizes[] = {
-    {.flags = 1 << VIRTIO_NET_F_MAC,
+    {.flags = 1ULL << VIRTIO_NET_F_MAC,
      .end = endof(struct virtio_net_config, mac)},
-    {.flags = 1 << VIRTIO_NET_F_STATUS,
+    {.flags = 1ULL << VIRTIO_NET_F_STATUS,
      .end = endof(struct virtio_net_config, status)},
-    {.flags = 1 << VIRTIO_NET_F_MQ,
+    {.flags = 1ULL << VIRTIO_NET_F_MQ,
      .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
     {}
 };
@@ -441,7 +441,7 @@ static void virtio_net_set_queues(VirtIONet *n)
 
 static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
 
-static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     NetClientState *nc = qemu_get_queue(n->nic);
@@ -471,9 +471,9 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
     return vhost_net_get_features(get_vhost_net(nc->peer), features);
 }
 
-static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
+static uint64_t virtio_net_bad_features(VirtIODevice *vdev)
 {
-    uint32_t features = 0;
+    uint64_t features = 0;
 
     /* Linux kernel 2.6.25.  It understood MAC (as everyone must),
      * but also these: */
@@ -496,7 +496,7 @@ static void virtio_net_apply_guest_offloads(VirtIONet *n)
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
 }
 
-static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
+static uint64_t virtio_net_guest_offloads_by_features(uint64_t features)
 {
     static const uint64_t guest_offloads_mask =
         (1ULL << VIRTIO_NET_F_GUEST_CSUM) |
@@ -514,7 +514,7 @@ static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
     return virtio_net_guest_offloads_by_features(vdev->guest_features);
 }
 
-static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
+static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     int i;
@@ -1036,7 +1036,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
                 return -1;
             error_report("virtio-net unexpected empty queue: "
                     "i %zd mergeable %d offset %zd, size %zd, "
-                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
+                    "guest hdr len %zd, host hdr len %zd guest features 0x%lx",
                     i, n->mergeable_rx_bufs, offset, size,
                     n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
             exit(1);
@@ -1560,7 +1560,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
                              vdev, idx, mask);
 }
 
-void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
+void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
 {
     int i, config_size = 0;
     virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 39dc201..3635909 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -490,9 +490,10 @@ static void virtio_s390_notify(DeviceState *d, uint16_t vector)
     s390_virtio_irq(0, token);
 }
 
-static unsigned virtio_s390_get_features(DeviceState *d)
+static uint64_t virtio_s390_get_features(DeviceState *d)
 {
     VirtIOS390Device *dev = to_virtio_s390_device(d);
+
     return dev->host_features;
 }
 
diff --git a/hw/s390x/s390-virtio-bus.h b/hw/s390x/s390-virtio-bus.h
index ffd0df7..e49d4ba 100644
--- a/hw/s390x/s390-virtio-bus.h
+++ b/hw/s390x/s390-virtio-bus.h
@@ -90,7 +90,7 @@ struct VirtIOS390Device {
     ram_addr_t feat_offs;
     uint8_t feat_len;
     VirtIODevice *vdev;
-    uint32_t host_features;
+    uint64_t host_features;
     VirtioBusState bus;
 };
 
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 3fee4aa..fbd909d 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -371,8 +371,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
         } else {
             features.index = ldub_phys(&address_space_memory,
                                        ccw.cda + sizeof(features.features));
-            if (features.index < ARRAY_SIZE(dev->host_features)) {
-                features.features = dev->host_features[features.index];
+            if (features.index == 0) {
+                features.features = (uint32_t)dev->host_features;
+            } else if (features.index == 1) {
+                features.features = (uint32_t)(dev->host_features >> 32);
             } else {
                 /* Return zeroes if the guest supports more feature bits. */
                 features.features = 0;
@@ -399,8 +401,14 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             features.index = ldub_phys(&address_space_memory,
                                        ccw.cda + sizeof(features.features));
             features.features = ldl_le_phys(&address_space_memory, ccw.cda);
-            if (features.index < ARRAY_SIZE(dev->host_features)) {
-                virtio_set_features(vdev, features.features);
+            if (features.index == 0) {
+                virtio_set_features(vdev,
+                                    (vdev->guest_features & 0xffffffff00000000) |
+                                    features.features);
+            } else if (features.index == 1) {
+                virtio_set_features(vdev,
+                                    (vdev->guest_features & 0x00000000ffffffff) |
+                                    ((uint64_t)features.features << 32));
             } else {
                 /*
                  * If the guest supports more feature bits, assert that it
@@ -739,12 +747,12 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
     sch->id.cu_model = vdev->device_id;
 
-    /* Only the first 32 feature bits are used. */
-    dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
-                                                         dev->host_features[0]);
+    /* Set default feature bits that are offered by the host. */
+    virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
 
-    virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY);
-    virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE);
+    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
+                                                      dev->host_features);
 
     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                           parent->hotplugged, 1);
@@ -777,7 +785,7 @@ static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
     VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
 
-    virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
+    virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features);
     virtio_net_set_netclient_name(&dev->vdev, qdev->id,
                                   object_get_typename(OBJECT(qdev)));
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
@@ -1063,12 +1071,11 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
     }
 }
 
-static unsigned virtio_ccw_get_features(DeviceState *d)
+static uint64_t virtio_ccw_get_features(DeviceState *d)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 
-    /* Only the first 32 feature bits are used. */
-    return dev->host_features[0];
+    return dev->host_features;
 }
 
 static void virtio_ccw_reset(DeviceState *d)
@@ -1381,7 +1388,7 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
 
 static Property virtio_ccw_net_properties[] = {
     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
-    DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
+    DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_END_OF_LIST(),
@@ -1486,7 +1493,7 @@ static const TypeInfo virtio_ccw_balloon = {
 
 static Property virtio_ccw_scsi_properties[] = {
     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
-    DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
+    DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_END_OF_LIST(),
@@ -1614,7 +1621,7 @@ static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
 }
 
 static Property virtio_ccw_properties[] = {
-    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 5a1f16e..9087f7a 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -68,9 +68,6 @@ typedef struct VirtIOCCWDeviceClass {
     int (*exit)(VirtioCcwDevice *dev);
 } VirtIOCCWDeviceClass;
 
-/* Change here if we want to support more feature bits. */
-#define VIRTIO_CCW_FEATURE_SIZE 1
-
 /* Performance improves when virtqueue kick processing is decoupled from the
  * vcpu thread using ioeventfd for some devices. */
 #define VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT 1
@@ -88,7 +85,7 @@ struct VirtioCcwDevice {
     DeviceState parent_obj;
     SubchDev *sch;
     char *bus_id;
-    uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE];
+    uint64_t host_features;
     VirtioBusState bus;
     bool ioeventfd_started;
     bool ioeventfd_disabled;
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index dcb2bc5..b5d7959 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -150,8 +150,7 @@ static void vhost_scsi_stop(VHostSCSI *s)
     vhost_dev_disable_notifiers(&s->dev, vdev);
 }
 
-static uint32_t vhost_scsi_get_features(VirtIODevice *vdev,
-                                        uint32_t features)
+static uint64_t vhost_scsi_get_features(VirtIODevice *vdev, uint64_t features)
 {
     VHostSCSI *s = VHOST_SCSI(vdev);
 
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 56c92fb..fbac794 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -627,8 +627,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
     vs->cdb_size = virtio_ldl_p(vdev, &scsiconf->cdb_size);
 }
 
-static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
-                                         uint32_t requested_features)
+static uint64_t virtio_scsi_get_features(VirtIODevice *vdev,
+                                         uint64_t requested_features)
 {
     return requested_features;
 }
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 21e449a..d2d7c3e 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -303,7 +303,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
     }
 }
 
-static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
+static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f)
 {
     f |= (1 << VIRTIO_BALLOON_F_STATS_VQ);
     return f;
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index a8ffa07..32e3fab 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -97,8 +97,8 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
 }
 
 /* Get the features of the plugged device. */
-uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
-                                    uint32_t requested_features)
+uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
+                                      uint64_t requested_features)
 {
     VirtIODevice *vdev = virtio_bus_get_device(bus);
     VirtioDeviceClass *k;
@@ -110,7 +110,7 @@ uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
 }
 
 /* Get bad features of the plugged device. */
-uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
+uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
 {
     VirtIODevice *vdev = virtio_bus_get_device(bus);
     VirtioDeviceClass *k;
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 10123f3..43b7e02 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -80,7 +80,7 @@ typedef struct {
     SysBusDevice parent_obj;
     MemoryRegion iomem;
     qemu_irq irq;
-    uint32_t host_features;
+    uint64_t host_features;
     /* Guest accessible state needing migration and reset */
     uint32_t host_features_sel;
     uint32_t guest_features_sel;
@@ -306,7 +306,7 @@ static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
     qemu_set_irq(proxy->irq, level);
 }
 
-static unsigned int virtio_mmio_get_features(DeviceState *opaque)
+static uint64_t virtio_mmio_get_features(DeviceState *opaque)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
 
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e7969bf..7382705 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -478,9 +478,10 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
     }
 }
 
-static unsigned virtio_pci_get_features(DeviceState *d)
+static uint64_t virtio_pci_get_features(DeviceState *d)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
+
     return proxy->host_features;
 }
 
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 8873b6d..85f102d 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -91,7 +91,7 @@ struct VirtIOPCIProxy {
     uint32_t flags;
     uint32_t class_code;
     uint32_t nvectors;
-    uint32_t host_features;
+    uint64_t host_features;
     bool ioeventfd_disabled;
     bool ioeventfd_started;
     VirtIOIRQFD *vector_irqfd;
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 473c044..edd39cc 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -99,7 +99,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
     virtio_rng_process(vrng);
 }
 
-static uint32_t get_features(VirtIODevice *vdev, uint32_t f)
+static uint64_t get_features(VirtIODevice *vdev, uint64_t f)
 {
     return f;
 }
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 5814433..7f74ae5 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -593,6 +593,7 @@ void virtio_reset(void *opaque)
     }
 
     vdev->guest_features = 0;
+
     vdev->queue_sel = 0;
     vdev->status = 0;
     vdev->isr = 0;
@@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     qemu_put_8s(f, &vdev->status);
     qemu_put_8s(f, &vdev->isr);
     qemu_put_be16s(f, &vdev->queue_sel);
-    qemu_put_be32s(f, &vdev->guest_features);
+    /* XXX features >= 32 */
+    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);
     qemu_put_be32(f, vdev->config_len);
     qemu_put_buffer(f, vdev->config, vdev->config_len);
 
@@ -958,12 +960,12 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     vmstate_save_state(f, &vmstate_virtio, vdev);
 }
 
-int virtio_set_features(VirtIODevice *vdev, uint32_t val)
+int virtio_set_features(VirtIODevice *vdev, uint64_t val)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-    uint32_t supported_features = vbusk->get_features(qbus->parent);
+    uint64_t supported_features = vbusk->get_features(qbus->parent);
     bool bad = (val & ~supported_features) != 0;
 
     val &= supported_features;
@@ -980,7 +982,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     int32_t config_len;
     uint32_t num;
     uint32_t features;
-    uint32_t supported_features;
+    uint64_t supported_features;
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
@@ -1005,9 +1007,10 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     }
     qemu_get_be32s(f, &features);
 
+    /* XXX features >= 32 */
     if (virtio_set_features(vdev, features) < 0) {
         supported_features = k->get_features(qbus->parent);
-        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
+        error_report("Features 0x%x unsupported. Allowed features: 0x%lx",
                      features, supported_features);
         return -1;
     }
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 070006c..81e5d0b 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -6,6 +6,7 @@
 /*** qdev-properties.c ***/
 
 extern PropertyInfo qdev_prop_bit;
+extern PropertyInfo qdev_prop_bit64;
 extern PropertyInfo qdev_prop_bool;
 extern PropertyInfo qdev_prop_uint8;
 extern PropertyInfo qdev_prop_uint16;
@@ -51,6 +52,17 @@ extern PropertyInfo qdev_prop_arraylen;
         .defval    = (bool)_defval,                              \
         }
 
+#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {  \
+        .name      = (_name),                                    \
+        .info      = &(qdev_prop_bit64),                           \
+        .bitnr    = (_bit),                                      \
+        .offset    = offsetof(_state, _field)                    \
+            + type_check(uint64_t,typeof_field(_state, _field)), \
+        .qtype     = QTYPE_QBOOL,                                \
+        .defval    = (bool)_defval,                              \
+        }
+
+
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
         .name      = (_name),                                    \
         .info      = &(qdev_prop_bool),                          \
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 0d2e7b4..0a4dde1 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -47,7 +47,7 @@ typedef struct VirtioBusClass {
     int (*load_config)(DeviceState *d, QEMUFile *f);
     int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
     int (*load_done)(DeviceState *d, QEMUFile *f);
-    unsigned (*get_features)(DeviceState *d);
+    uint64_t (*get_features)(DeviceState *d);
     bool (*query_guest_notifiers)(DeviceState *d);
     int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
     int (*set_host_notifier)(DeviceState *d, int n, bool assigned);
@@ -82,10 +82,10 @@ uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus);
 /* Get the config_len field of the plugged device. */
 size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
 /* Get the features of the plugged device. */
-uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
-                                    uint32_t requested_features);
+uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
+                                      uint64_t requested_features);
 /* Get bad features of the plugged device. */
-uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
+uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
 /* Get config of the plugged device. */
 void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config);
 /* Set config of the plugged device. */
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index 6ceb5aa..5c58b4b 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -258,35 +258,35 @@ struct virtio_net_ctrl_mq {
  #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET        0
 
 #define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
-        DEFINE_PROP_BIT("any_layout", _state, _field, VIRTIO_F_ANY_LAYOUT, true), \
-        DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
-        DEFINE_PROP_BIT("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \
-        DEFINE_PROP_BIT("gso", _state, _field, VIRTIO_NET_F_GSO, true), \
-        DEFINE_PROP_BIT("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \
-        DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
-        DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
-        DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
-        DEFINE_PROP_BIT("guest_announce", _state, _field, VIRTIO_NET_F_GUEST_ANNOUNCE, true), \
-        DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
-        DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
-        DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \
-        DEFINE_PROP_BIT("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \
-        DEFINE_PROP_BIT("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \
-        DEFINE_PROP_BIT("status", _state, _field, VIRTIO_NET_F_STATUS, true), \
-        DEFINE_PROP_BIT("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \
-        DEFINE_PROP_BIT("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \
-        DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
-        DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
-        DEFINE_PROP_BIT("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
-        DEFINE_PROP_BIT("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true), \
-        DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, false)
+        DEFINE_PROP_BIT64("any_layout", _state, _field, VIRTIO_F_ANY_LAYOUT, true), \
+        DEFINE_PROP_BIT64("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
+        DEFINE_PROP_BIT64("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \
+        DEFINE_PROP_BIT64("gso", _state, _field, VIRTIO_NET_F_GSO, true), \
+        DEFINE_PROP_BIT64("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \
+        DEFINE_PROP_BIT64("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
+        DEFINE_PROP_BIT64("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
+        DEFINE_PROP_BIT64("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
+        DEFINE_PROP_BIT64("guest_announce", _state, _field, VIRTIO_NET_F_GUEST_ANNOUNCE, true), \
+        DEFINE_PROP_BIT64("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
+        DEFINE_PROP_BIT64("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
+        DEFINE_PROP_BIT64("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \
+        DEFINE_PROP_BIT64("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \
+        DEFINE_PROP_BIT64("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \
+        DEFINE_PROP_BIT64("status", _state, _field, VIRTIO_NET_F_STATUS, true), \
+        DEFINE_PROP_BIT64("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \
+        DEFINE_PROP_BIT64("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \
+        DEFINE_PROP_BIT64("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
+        DEFINE_PROP_BIT64("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
+        DEFINE_PROP_BIT64("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
+        DEFINE_PROP_BIT64("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true), \
+        DEFINE_PROP_BIT64("mq", _state, _field, VIRTIO_NET_F_MQ, false)
 
 #define DEFINE_VIRTIO_NET_PROPERTIES(_state, _field)                           \
     DEFINE_PROP_UINT32("x-txtimer", _state, _field.txtimer, TX_TIMER_INTERVAL),\
     DEFINE_PROP_INT32("x-txburst", _state, _field.txburst, TX_BURST),          \
     DEFINE_PROP_STRING("tx", _state, _field.tx)
 
-void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features);
+void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features);
 void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
                                    const char *type);
 
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index bf17cc9..f0c0a6e 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -253,11 +253,11 @@ QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) !=
     DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
 
 #define DEFINE_VIRTIO_SCSI_FEATURES(_state, _feature_field)                    \
-    DEFINE_PROP_BIT("any_layout", _state, _feature_field,                      \
+    DEFINE_PROP_BIT64("any_layout", _state, _feature_field,                      \
                     VIRTIO_F_ANY_LAYOUT, true),                                \
-    DEFINE_PROP_BIT("hotplug", _state, _feature_field, VIRTIO_SCSI_F_HOTPLUG,  \
+    DEFINE_PROP_BIT64("hotplug", _state, _feature_field, VIRTIO_SCSI_F_HOTPLUG,  \
                                                        true),                  \
-    DEFINE_PROP_BIT("param_change", _state, _feature_field,                    \
+    DEFINE_PROP_BIT64("param_change", _state, _feature_field,                    \
                                             VIRTIO_SCSI_F_CHANGE, true)
 
 typedef void (*HandleOutput)(VirtIODevice *, VirtQueue *);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index f6c0379..08141c7 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -55,6 +55,12 @@
 /* A guest should never accept this.  It implies negotiation is broken. */
 #define VIRTIO_F_BAD_FEATURE		30
 
+/* v1.0 compliant. */
+#define VIRTIO_F_VERSION_1              32
+
+/* The highest feature bit that we support */
+#define VIRTIO_HIGHEST_FEATURE_BIT      32
+
 /* from Linux's linux/virtio_ring.h */
 
 /* This marks a buffer as continuing via the next field. */
@@ -117,7 +123,7 @@ struct VirtIODevice
     uint8_t status;
     uint8_t isr;
     uint16_t queue_sel;
-    uint32_t guest_features;
+    uint64_t guest_features;
     size_t config_len;
     void *config;
     uint16_t config_vector;
@@ -138,9 +144,9 @@ typedef struct VirtioDeviceClass {
     /* This is what a VirtioDevice must implement */
     DeviceRealize realize;
     DeviceUnrealize unrealize;
-    uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
-    uint32_t (*bad_features)(VirtIODevice *vdev);
-    void (*set_features)(VirtIODevice *vdev, uint32_t val);
+    uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
+    uint64_t (*bad_features)(VirtIODevice *vdev);
+    void (*set_features)(VirtIODevice *vdev, uint64_t val);
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
     void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
     void (*reset)(VirtIODevice *vdev);
@@ -225,7 +231,7 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
 void virtio_set_status(VirtIODevice *vdev, uint8_t val);
 void virtio_reset(void *opaque);
 void virtio_update_irq(VirtIODevice *vdev);
-int virtio_set_features(VirtIODevice *vdev, uint32_t val);
+int virtio_set_features(VirtIODevice *vdev, uint64_t val);
 
 /* Base devices.  */
 typedef struct VirtIOBlkConf VirtIOBlkConf;
@@ -238,9 +244,9 @@ typedef struct VirtIOSCSIConf VirtIOSCSIConf;
 typedef struct VirtIORNGConf VirtIORNGConf;
 
 #define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
-	DEFINE_PROP_BIT("indirect_desc", _state, _field, \
+	DEFINE_PROP_BIT64("indirect_desc", _state, _field, \
 			VIRTIO_RING_F_INDIRECT_DESC, true), \
-	DEFINE_PROP_BIT("event_idx", _state, _field, \
+	DEFINE_PROP_BIT64("event_idx", _state, _field, \
 			VIRTIO_RING_F_EVENT_IDX, true)
 
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
@@ -266,22 +272,22 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
 void virtio_queue_notify_vq(VirtQueue *vq);
 void virtio_irq(VirtQueue *vq);
 
-static inline void virtio_add_feature(uint32_t *features, unsigned int fbit)
+static inline void virtio_add_feature(uint64_t *features, unsigned int fbit)
 {
-    assert(fbit < 32);
-    *features |= (1 << fbit);
+    assert(fbit < 64);
+    *features |= (1ULL << fbit);
 }
 
-static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
+static inline void virtio_clear_feature(uint64_t *features, unsigned int fbit)
 {
-    assert(fbit < 32);
-    *features &= ~(1 << fbit);
+    assert(fbit < 64);
+    *features &= ~(1ULL << fbit);
 }
 
-static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
+static inline bool __virtio_has_feature(uint64_t features, unsigned int fbit)
 {
-    assert(fbit < 32);
-    return !!(features & (1 << fbit));
+    assert(fbit < 64);
+    return !!(features & (1ULL << fbit));
 }
 
 static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

With virtio-1, we support more than 32 feature bits. Let's extend both
host and guest features to 64, which should suffice for a while.

vhost and migration have been ignored for now.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/9pfs/virtio-9p-device.c      |    2 +-
 hw/block/virtio-blk.c           |    2 +-
 hw/char/virtio-serial-bus.c     |    2 +-
 hw/core/qdev-properties.c       |   58 +++++++++++++++++++++++++++++++++++++++
 hw/net/virtio-net.c             |   22 +++++++--------
 hw/s390x/s390-virtio-bus.c      |    3 +-
 hw/s390x/s390-virtio-bus.h      |    2 +-
 hw/s390x/virtio-ccw.c           |   39 +++++++++++++++-----------
 hw/s390x/virtio-ccw.h           |    5 +---
 hw/scsi/vhost-scsi.c            |    3 +-
 hw/scsi/virtio-scsi.c           |    4 +--
 hw/virtio/virtio-balloon.c      |    2 +-
 hw/virtio/virtio-bus.c          |    6 ++--
 hw/virtio/virtio-mmio.c         |    4 +--
 hw/virtio/virtio-pci.c          |    3 +-
 hw/virtio/virtio-pci.h          |    2 +-
 hw/virtio/virtio-rng.c          |    2 +-
 hw/virtio/virtio.c              |   13 +++++----
 include/hw/qdev-properties.h    |   12 ++++++++
 include/hw/virtio/virtio-bus.h  |    8 +++---
 include/hw/virtio/virtio-net.h  |   46 +++++++++++++++----------------
 include/hw/virtio/virtio-scsi.h |    6 ++--
 include/hw/virtio/virtio.h      |   38 ++++++++++++++-----------
 23 files changed, 184 insertions(+), 100 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 30492ec..60f9ff9 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -21,7 +21,7 @@
 #include "virtio-9p-coth.h"
 #include "hw/virtio/virtio-access.h"
 
-static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features)
 {
     virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
     return features;
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 27f263a..9cfae66 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -564,7 +564,7 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
     aio_context_release(blk_get_aio_context(s->blk));
 }
 
-static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index d49883f..2d2ed9c 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -467,7 +467,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
 {
 }
 
-static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t get_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIOSerial *vser;
 
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 2e47f70..1b24818 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -125,6 +125,64 @@ PropertyInfo qdev_prop_bit = {
     .set   = prop_set_bit,
 };
 
+/* Bit on a 64 bit value*/
+
+static uint64_t qdev_get_prop_mask64(Property *prop)
+{
+    assert(prop->info == &qdev_prop_bit64);
+    return 0x1ULL << prop->bitnr;
+}
+
+static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
+{
+    uint64_t *p = qdev_get_prop_ptr(dev, props);
+    uint64_t mask = qdev_get_prop_mask64(props);
+    if (val) {
+        *p |= mask;
+    } else {
+        *p &= ~mask;
+    }
+}
+
+static void prop_get_bit64(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint64_t *p = qdev_get_prop_ptr(dev, prop);
+    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
+
+    visit_type_bool(v, &value, name, errp);
+}
+
+static void prop_set_bit64(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    bool value;
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
+    visit_type_bool(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    bit64_prop_set(dev, prop, value);
+}
+
+PropertyInfo qdev_prop_bit64 = {
+    .name  = "bool",
+    .description = "on/off",
+    .get   = prop_get_bit64,
+    .set   = prop_set_bit64,
+};
+
 /* --- bool --- */
 
 static void get_bool(Object *obj, Visitor *v, void *opaque,
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9f3c58a..d6d1b98 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -38,16 +38,16 @@
     (offsetof(container, field) + sizeof(((container *)0)->field))
 
 typedef struct VirtIOFeature {
-    uint32_t flags;
+    uint64_t flags;
     size_t end;
 } VirtIOFeature;
 
 static VirtIOFeature feature_sizes[] = {
-    {.flags = 1 << VIRTIO_NET_F_MAC,
+    {.flags = 1ULL << VIRTIO_NET_F_MAC,
      .end = endof(struct virtio_net_config, mac)},
-    {.flags = 1 << VIRTIO_NET_F_STATUS,
+    {.flags = 1ULL << VIRTIO_NET_F_STATUS,
      .end = endof(struct virtio_net_config, status)},
-    {.flags = 1 << VIRTIO_NET_F_MQ,
+    {.flags = 1ULL << VIRTIO_NET_F_MQ,
      .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
     {}
 };
@@ -441,7 +441,7 @@ static void virtio_net_set_queues(VirtIONet *n)
 
 static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
 
-static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
+static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     NetClientState *nc = qemu_get_queue(n->nic);
@@ -471,9 +471,9 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
     return vhost_net_get_features(get_vhost_net(nc->peer), features);
 }
 
-static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
+static uint64_t virtio_net_bad_features(VirtIODevice *vdev)
 {
-    uint32_t features = 0;
+    uint64_t features = 0;
 
     /* Linux kernel 2.6.25.  It understood MAC (as everyone must),
      * but also these: */
@@ -496,7 +496,7 @@ static void virtio_net_apply_guest_offloads(VirtIONet *n)
             !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
 }
 
-static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
+static uint64_t virtio_net_guest_offloads_by_features(uint64_t features)
 {
     static const uint64_t guest_offloads_mask =
         (1ULL << VIRTIO_NET_F_GUEST_CSUM) |
@@ -514,7 +514,7 @@ static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
     return virtio_net_guest_offloads_by_features(vdev->guest_features);
 }
 
-static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
+static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     int i;
@@ -1036,7 +1036,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
                 return -1;
             error_report("virtio-net unexpected empty queue: "
                     "i %zd mergeable %d offset %zd, size %zd, "
-                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
+                    "guest hdr len %zd, host hdr len %zd guest features 0x%lx",
                     i, n->mergeable_rx_bufs, offset, size,
                     n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
             exit(1);
@@ -1560,7 +1560,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
                              vdev, idx, mask);
 }
 
-void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
+void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
 {
     int i, config_size = 0;
     virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 39dc201..3635909 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -490,9 +490,10 @@ static void virtio_s390_notify(DeviceState *d, uint16_t vector)
     s390_virtio_irq(0, token);
 }
 
-static unsigned virtio_s390_get_features(DeviceState *d)
+static uint64_t virtio_s390_get_features(DeviceState *d)
 {
     VirtIOS390Device *dev = to_virtio_s390_device(d);
+
     return dev->host_features;
 }
 
diff --git a/hw/s390x/s390-virtio-bus.h b/hw/s390x/s390-virtio-bus.h
index ffd0df7..e49d4ba 100644
--- a/hw/s390x/s390-virtio-bus.h
+++ b/hw/s390x/s390-virtio-bus.h
@@ -90,7 +90,7 @@ struct VirtIOS390Device {
     ram_addr_t feat_offs;
     uint8_t feat_len;
     VirtIODevice *vdev;
-    uint32_t host_features;
+    uint64_t host_features;
     VirtioBusState bus;
 };
 
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 3fee4aa..fbd909d 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -371,8 +371,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
         } else {
             features.index = ldub_phys(&address_space_memory,
                                        ccw.cda + sizeof(features.features));
-            if (features.index < ARRAY_SIZE(dev->host_features)) {
-                features.features = dev->host_features[features.index];
+            if (features.index == 0) {
+                features.features = (uint32_t)dev->host_features;
+            } else if (features.index == 1) {
+                features.features = (uint32_t)(dev->host_features >> 32);
             } else {
                 /* Return zeroes if the guest supports more feature bits. */
                 features.features = 0;
@@ -399,8 +401,14 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             features.index = ldub_phys(&address_space_memory,
                                        ccw.cda + sizeof(features.features));
             features.features = ldl_le_phys(&address_space_memory, ccw.cda);
-            if (features.index < ARRAY_SIZE(dev->host_features)) {
-                virtio_set_features(vdev, features.features);
+            if (features.index == 0) {
+                virtio_set_features(vdev,
+                                    (vdev->guest_features & 0xffffffff00000000) |
+                                    features.features);
+            } else if (features.index == 1) {
+                virtio_set_features(vdev,
+                                    (vdev->guest_features & 0x00000000ffffffff) |
+                                    ((uint64_t)features.features << 32));
             } else {
                 /*
                  * If the guest supports more feature bits, assert that it
@@ -739,12 +747,12 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
     sch->id.cu_model = vdev->device_id;
 
-    /* Only the first 32 feature bits are used. */
-    dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
-                                                         dev->host_features[0]);
+    /* Set default feature bits that are offered by the host. */
+    virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
+    virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
 
-    virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY);
-    virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE);
+    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
+                                                      dev->host_features);
 
     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                           parent->hotplugged, 1);
@@ -777,7 +785,7 @@ static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
     VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
 
-    virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
+    virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features);
     virtio_net_set_netclient_name(&dev->vdev, qdev->id,
                                   object_get_typename(OBJECT(qdev)));
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
@@ -1063,12 +1071,11 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
     }
 }
 
-static unsigned virtio_ccw_get_features(DeviceState *d)
+static uint64_t virtio_ccw_get_features(DeviceState *d)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 
-    /* Only the first 32 feature bits are used. */
-    return dev->host_features[0];
+    return dev->host_features;
 }
 
 static void virtio_ccw_reset(DeviceState *d)
@@ -1381,7 +1388,7 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
 
 static Property virtio_ccw_net_properties[] = {
     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
-    DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
+    DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_END_OF_LIST(),
@@ -1486,7 +1493,7 @@ static const TypeInfo virtio_ccw_balloon = {
 
 static Property virtio_ccw_scsi_properties[] = {
     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
-    DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
+    DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_END_OF_LIST(),
@@ -1614,7 +1621,7 @@ static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
 }
 
 static Property virtio_ccw_properties[] = {
-    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 5a1f16e..9087f7a 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -68,9 +68,6 @@ typedef struct VirtIOCCWDeviceClass {
     int (*exit)(VirtioCcwDevice *dev);
 } VirtIOCCWDeviceClass;
 
-/* Change here if we want to support more feature bits. */
-#define VIRTIO_CCW_FEATURE_SIZE 1
-
 /* Performance improves when virtqueue kick processing is decoupled from the
  * vcpu thread using ioeventfd for some devices. */
 #define VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT 1
@@ -88,7 +85,7 @@ struct VirtioCcwDevice {
     DeviceState parent_obj;
     SubchDev *sch;
     char *bus_id;
-    uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE];
+    uint64_t host_features;
     VirtioBusState bus;
     bool ioeventfd_started;
     bool ioeventfd_disabled;
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index dcb2bc5..b5d7959 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -150,8 +150,7 @@ static void vhost_scsi_stop(VHostSCSI *s)
     vhost_dev_disable_notifiers(&s->dev, vdev);
 }
 
-static uint32_t vhost_scsi_get_features(VirtIODevice *vdev,
-                                        uint32_t features)
+static uint64_t vhost_scsi_get_features(VirtIODevice *vdev, uint64_t features)
 {
     VHostSCSI *s = VHOST_SCSI(vdev);
 
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 56c92fb..fbac794 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -627,8 +627,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
     vs->cdb_size = virtio_ldl_p(vdev, &scsiconf->cdb_size);
 }
 
-static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
-                                         uint32_t requested_features)
+static uint64_t virtio_scsi_get_features(VirtIODevice *vdev,
+                                         uint64_t requested_features)
 {
     return requested_features;
 }
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 21e449a..d2d7c3e 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -303,7 +303,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
     }
 }
 
-static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
+static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f)
 {
     f |= (1 << VIRTIO_BALLOON_F_STATS_VQ);
     return f;
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index a8ffa07..32e3fab 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -97,8 +97,8 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
 }
 
 /* Get the features of the plugged device. */
-uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
-                                    uint32_t requested_features)
+uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
+                                      uint64_t requested_features)
 {
     VirtIODevice *vdev = virtio_bus_get_device(bus);
     VirtioDeviceClass *k;
@@ -110,7 +110,7 @@ uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
 }
 
 /* Get bad features of the plugged device. */
-uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
+uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
 {
     VirtIODevice *vdev = virtio_bus_get_device(bus);
     VirtioDeviceClass *k;
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 10123f3..43b7e02 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -80,7 +80,7 @@ typedef struct {
     SysBusDevice parent_obj;
     MemoryRegion iomem;
     qemu_irq irq;
-    uint32_t host_features;
+    uint64_t host_features;
     /* Guest accessible state needing migration and reset */
     uint32_t host_features_sel;
     uint32_t guest_features_sel;
@@ -306,7 +306,7 @@ static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
     qemu_set_irq(proxy->irq, level);
 }
 
-static unsigned int virtio_mmio_get_features(DeviceState *opaque)
+static uint64_t virtio_mmio_get_features(DeviceState *opaque)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
 
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e7969bf..7382705 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -478,9 +478,10 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
     }
 }
 
-static unsigned virtio_pci_get_features(DeviceState *d)
+static uint64_t virtio_pci_get_features(DeviceState *d)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
+
     return proxy->host_features;
 }
 
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 8873b6d..85f102d 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -91,7 +91,7 @@ struct VirtIOPCIProxy {
     uint32_t flags;
     uint32_t class_code;
     uint32_t nvectors;
-    uint32_t host_features;
+    uint64_t host_features;
     bool ioeventfd_disabled;
     bool ioeventfd_started;
     VirtIOIRQFD *vector_irqfd;
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 473c044..edd39cc 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -99,7 +99,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
     virtio_rng_process(vrng);
 }
 
-static uint32_t get_features(VirtIODevice *vdev, uint32_t f)
+static uint64_t get_features(VirtIODevice *vdev, uint64_t f)
 {
     return f;
 }
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 5814433..7f74ae5 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -593,6 +593,7 @@ void virtio_reset(void *opaque)
     }
 
     vdev->guest_features = 0;
+
     vdev->queue_sel = 0;
     vdev->status = 0;
     vdev->isr = 0;
@@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     qemu_put_8s(f, &vdev->status);
     qemu_put_8s(f, &vdev->isr);
     qemu_put_be16s(f, &vdev->queue_sel);
-    qemu_put_be32s(f, &vdev->guest_features);
+    /* XXX features >= 32 */
+    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);
     qemu_put_be32(f, vdev->config_len);
     qemu_put_buffer(f, vdev->config, vdev->config_len);
 
@@ -958,12 +960,12 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     vmstate_save_state(f, &vmstate_virtio, vdev);
 }
 
-int virtio_set_features(VirtIODevice *vdev, uint32_t val)
+int virtio_set_features(VirtIODevice *vdev, uint64_t val)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-    uint32_t supported_features = vbusk->get_features(qbus->parent);
+    uint64_t supported_features = vbusk->get_features(qbus->parent);
     bool bad = (val & ~supported_features) != 0;
 
     val &= supported_features;
@@ -980,7 +982,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     int32_t config_len;
     uint32_t num;
     uint32_t features;
-    uint32_t supported_features;
+    uint64_t supported_features;
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
@@ -1005,9 +1007,10 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     }
     qemu_get_be32s(f, &features);
 
+    /* XXX features >= 32 */
     if (virtio_set_features(vdev, features) < 0) {
         supported_features = k->get_features(qbus->parent);
-        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
+        error_report("Features 0x%x unsupported. Allowed features: 0x%lx",
                      features, supported_features);
         return -1;
     }
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 070006c..81e5d0b 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -6,6 +6,7 @@
 /*** qdev-properties.c ***/
 
 extern PropertyInfo qdev_prop_bit;
+extern PropertyInfo qdev_prop_bit64;
 extern PropertyInfo qdev_prop_bool;
 extern PropertyInfo qdev_prop_uint8;
 extern PropertyInfo qdev_prop_uint16;
@@ -51,6 +52,17 @@ extern PropertyInfo qdev_prop_arraylen;
         .defval    = (bool)_defval,                              \
         }
 
+#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {  \
+        .name      = (_name),                                    \
+        .info      = &(qdev_prop_bit64),                           \
+        .bitnr    = (_bit),                                      \
+        .offset    = offsetof(_state, _field)                    \
+            + type_check(uint64_t,typeof_field(_state, _field)), \
+        .qtype     = QTYPE_QBOOL,                                \
+        .defval    = (bool)_defval,                              \
+        }
+
+
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
         .name      = (_name),                                    \
         .info      = &(qdev_prop_bool),                          \
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 0d2e7b4..0a4dde1 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -47,7 +47,7 @@ typedef struct VirtioBusClass {
     int (*load_config)(DeviceState *d, QEMUFile *f);
     int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
     int (*load_done)(DeviceState *d, QEMUFile *f);
-    unsigned (*get_features)(DeviceState *d);
+    uint64_t (*get_features)(DeviceState *d);
     bool (*query_guest_notifiers)(DeviceState *d);
     int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
     int (*set_host_notifier)(DeviceState *d, int n, bool assigned);
@@ -82,10 +82,10 @@ uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus);
 /* Get the config_len field of the plugged device. */
 size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
 /* Get the features of the plugged device. */
-uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
-                                    uint32_t requested_features);
+uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
+                                      uint64_t requested_features);
 /* Get bad features of the plugged device. */
-uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
+uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
 /* Get config of the plugged device. */
 void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config);
 /* Set config of the plugged device. */
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index 6ceb5aa..5c58b4b 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -258,35 +258,35 @@ struct virtio_net_ctrl_mq {
  #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET        0
 
 #define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
-        DEFINE_PROP_BIT("any_layout", _state, _field, VIRTIO_F_ANY_LAYOUT, true), \
-        DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
-        DEFINE_PROP_BIT("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \
-        DEFINE_PROP_BIT("gso", _state, _field, VIRTIO_NET_F_GSO, true), \
-        DEFINE_PROP_BIT("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \
-        DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
-        DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
-        DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
-        DEFINE_PROP_BIT("guest_announce", _state, _field, VIRTIO_NET_F_GUEST_ANNOUNCE, true), \
-        DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
-        DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
-        DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \
-        DEFINE_PROP_BIT("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \
-        DEFINE_PROP_BIT("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \
-        DEFINE_PROP_BIT("status", _state, _field, VIRTIO_NET_F_STATUS, true), \
-        DEFINE_PROP_BIT("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \
-        DEFINE_PROP_BIT("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \
-        DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
-        DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
-        DEFINE_PROP_BIT("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
-        DEFINE_PROP_BIT("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true), \
-        DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, false)
+        DEFINE_PROP_BIT64("any_layout", _state, _field, VIRTIO_F_ANY_LAYOUT, true), \
+        DEFINE_PROP_BIT64("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
+        DEFINE_PROP_BIT64("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \
+        DEFINE_PROP_BIT64("gso", _state, _field, VIRTIO_NET_F_GSO, true), \
+        DEFINE_PROP_BIT64("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \
+        DEFINE_PROP_BIT64("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
+        DEFINE_PROP_BIT64("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
+        DEFINE_PROP_BIT64("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
+        DEFINE_PROP_BIT64("guest_announce", _state, _field, VIRTIO_NET_F_GUEST_ANNOUNCE, true), \
+        DEFINE_PROP_BIT64("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
+        DEFINE_PROP_BIT64("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
+        DEFINE_PROP_BIT64("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \
+        DEFINE_PROP_BIT64("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \
+        DEFINE_PROP_BIT64("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \
+        DEFINE_PROP_BIT64("status", _state, _field, VIRTIO_NET_F_STATUS, true), \
+        DEFINE_PROP_BIT64("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \
+        DEFINE_PROP_BIT64("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \
+        DEFINE_PROP_BIT64("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
+        DEFINE_PROP_BIT64("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
+        DEFINE_PROP_BIT64("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
+        DEFINE_PROP_BIT64("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true), \
+        DEFINE_PROP_BIT64("mq", _state, _field, VIRTIO_NET_F_MQ, false)
 
 #define DEFINE_VIRTIO_NET_PROPERTIES(_state, _field)                           \
     DEFINE_PROP_UINT32("x-txtimer", _state, _field.txtimer, TX_TIMER_INTERVAL),\
     DEFINE_PROP_INT32("x-txburst", _state, _field.txburst, TX_BURST),          \
     DEFINE_PROP_STRING("tx", _state, _field.tx)
 
-void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features);
+void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features);
 void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
                                    const char *type);
 
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index bf17cc9..f0c0a6e 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -253,11 +253,11 @@ QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) !=
     DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
 
 #define DEFINE_VIRTIO_SCSI_FEATURES(_state, _feature_field)                    \
-    DEFINE_PROP_BIT("any_layout", _state, _feature_field,                      \
+    DEFINE_PROP_BIT64("any_layout", _state, _feature_field,                      \
                     VIRTIO_F_ANY_LAYOUT, true),                                \
-    DEFINE_PROP_BIT("hotplug", _state, _feature_field, VIRTIO_SCSI_F_HOTPLUG,  \
+    DEFINE_PROP_BIT64("hotplug", _state, _feature_field, VIRTIO_SCSI_F_HOTPLUG,  \
                                                        true),                  \
-    DEFINE_PROP_BIT("param_change", _state, _feature_field,                    \
+    DEFINE_PROP_BIT64("param_change", _state, _feature_field,                    \
                                             VIRTIO_SCSI_F_CHANGE, true)
 
 typedef void (*HandleOutput)(VirtIODevice *, VirtQueue *);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index f6c0379..08141c7 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -55,6 +55,12 @@
 /* A guest should never accept this.  It implies negotiation is broken. */
 #define VIRTIO_F_BAD_FEATURE		30
 
+/* v1.0 compliant. */
+#define VIRTIO_F_VERSION_1              32
+
+/* The highest feature bit that we support */
+#define VIRTIO_HIGHEST_FEATURE_BIT      32
+
 /* from Linux's linux/virtio_ring.h */
 
 /* This marks a buffer as continuing via the next field. */
@@ -117,7 +123,7 @@ struct VirtIODevice
     uint8_t status;
     uint8_t isr;
     uint16_t queue_sel;
-    uint32_t guest_features;
+    uint64_t guest_features;
     size_t config_len;
     void *config;
     uint16_t config_vector;
@@ -138,9 +144,9 @@ typedef struct VirtioDeviceClass {
     /* This is what a VirtioDevice must implement */
     DeviceRealize realize;
     DeviceUnrealize unrealize;
-    uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
-    uint32_t (*bad_features)(VirtIODevice *vdev);
-    void (*set_features)(VirtIODevice *vdev, uint32_t val);
+    uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
+    uint64_t (*bad_features)(VirtIODevice *vdev);
+    void (*set_features)(VirtIODevice *vdev, uint64_t val);
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
     void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
     void (*reset)(VirtIODevice *vdev);
@@ -225,7 +231,7 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
 void virtio_set_status(VirtIODevice *vdev, uint8_t val);
 void virtio_reset(void *opaque);
 void virtio_update_irq(VirtIODevice *vdev);
-int virtio_set_features(VirtIODevice *vdev, uint32_t val);
+int virtio_set_features(VirtIODevice *vdev, uint64_t val);
 
 /* Base devices.  */
 typedef struct VirtIOBlkConf VirtIOBlkConf;
@@ -238,9 +244,9 @@ typedef struct VirtIOSCSIConf VirtIOSCSIConf;
 typedef struct VirtIORNGConf VirtIORNGConf;
 
 #define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
-	DEFINE_PROP_BIT("indirect_desc", _state, _field, \
+	DEFINE_PROP_BIT64("indirect_desc", _state, _field, \
 			VIRTIO_RING_F_INDIRECT_DESC, true), \
-	DEFINE_PROP_BIT("event_idx", _state, _field, \
+	DEFINE_PROP_BIT64("event_idx", _state, _field, \
 			VIRTIO_RING_F_EVENT_IDX, true)
 
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
@@ -266,22 +272,22 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
 void virtio_queue_notify_vq(VirtQueue *vq);
 void virtio_irq(VirtQueue *vq);
 
-static inline void virtio_add_feature(uint32_t *features, unsigned int fbit)
+static inline void virtio_add_feature(uint64_t *features, unsigned int fbit)
 {
-    assert(fbit < 32);
-    *features |= (1 << fbit);
+    assert(fbit < 64);
+    *features |= (1ULL << fbit);
 }
 
-static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
+static inline void virtio_clear_feature(uint64_t *features, unsigned int fbit)
 {
-    assert(fbit < 32);
-    *features &= ~(1 << fbit);
+    assert(fbit < 64);
+    *features &= ~(1ULL << fbit);
 }
 
-static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
+static inline bool __virtio_has_feature(uint64_t features, unsigned int fbit)
 {
-    assert(fbit < 32);
-    return !!(features & (1 << fbit));
+    assert(fbit < 64);
+    return !!(features & (1ULL << fbit));
 }
 
 static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Add code that checks for the VERSION_1 feature bit in order to make
decisions about the device's endianness. This allows us to support
transitional devices.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/virtio/virtio.c                |    6 +++++-
 include/hw/virtio/virtio-access.h |    4 ++++
 include/hw/virtio/virtio.h        |    8 ++++++--
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 7f74ae5..8f69ffa 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -881,7 +881,11 @@ static bool virtio_device_endian_needed(void *opaque)
     VirtIODevice *vdev = opaque;
 
     assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-    return vdev->device_endian != virtio_default_endian();
+    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        return vdev->device_endian != virtio_default_endian();
+    }
+    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
+    return vdev->device_endian != VIRTIO_DEVICE_ENDIAN_LITTLE;
 }
 
 static const VMStateDescription vmstate_virtio_device_endian = {
diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
index 46456fd..ee28c21 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -19,6 +19,10 @@
 
 static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
 {
+    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        /* Devices conforming to VIRTIO 1.0 or later are always LE. */
+        return false;
+    }
 #if defined(TARGET_IS_BIENDIAN)
     return virtio_is_big_endian(vdev);
 #elif defined(TARGET_WORDS_BIGENDIAN)
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 08141c7..68c40db 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -297,7 +297,11 @@ static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
 
 static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 {
-    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-    return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
+    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
+        return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
+    }
+    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
+    return false;
 }
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Add code that checks for the VERSION_1 feature bit in order to make
decisions about the device's endianness. This allows us to support
transitional devices.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/virtio/virtio.c                |    6 +++++-
 include/hw/virtio/virtio-access.h |    4 ++++
 include/hw/virtio/virtio.h        |    8 ++++++--
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 7f74ae5..8f69ffa 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -881,7 +881,11 @@ static bool virtio_device_endian_needed(void *opaque)
     VirtIODevice *vdev = opaque;
 
     assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-    return vdev->device_endian != virtio_default_endian();
+    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        return vdev->device_endian != virtio_default_endian();
+    }
+    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
+    return vdev->device_endian != VIRTIO_DEVICE_ENDIAN_LITTLE;
 }
 
 static const VMStateDescription vmstate_virtio_device_endian = {
diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
index 46456fd..ee28c21 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -19,6 +19,10 @@
 
 static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
 {
+    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        /* Devices conforming to VIRTIO 1.0 or later are always LE. */
+        return false;
+    }
 #if defined(TARGET_IS_BIENDIAN)
     return virtio_is_big_endian(vdev);
 #elif defined(TARGET_WORDS_BIGENDIAN)
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 08141c7..68c40db 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -297,7 +297,11 @@ static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
 
 static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 {
-    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
-    return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
+    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
+        return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
+    }
+    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
+    return false;
 }
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

For virtio-1 devices, we allow a more complex queue layout that doesn't
require descriptor table and rings on a physically-contigous memory area:
add virtio_queue_set_rings() to allow transports to set this up.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/virtio/virtio-mmio.c    |    3 +++
 hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
 include/hw/virtio/virtio.h |    3 +++
 3 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 43b7e02..0c9b63b 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
     case VIRTIO_MMIO_QUEUENUM:
         DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
         virtio_queue_set_num(vdev, vdev->queue_sel, value);
+        /* Note: only call this function for legacy devices */
+        virtio_queue_update_rings(vdev, vdev->queue_sel);
         break;
     case VIRTIO_MMIO_QUEUEALIGN:
+        /* Note: this is only valid for legacy devices */
         virtio_queue_set_align(vdev, vdev->queue_sel, value);
         break;
     case VIRTIO_MMIO_QUEUEPFN:
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 8f69ffa..57190ba 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -69,7 +69,6 @@ typedef struct VRing
 struct VirtQueue
 {
     VRing vring;
-    hwaddr pa;
     uint16_t last_avail_idx;
     /* Last used index value we have signalled on */
     uint16_t signalled_used;
@@ -92,15 +91,18 @@ struct VirtQueue
 };
 
 /* virt queue functions */
-static void virtqueue_init(VirtQueue *vq)
+void virtio_queue_update_rings(VirtIODevice *vdev, int n)
 {
-    hwaddr pa = vq->pa;
+    VRing *vring = &vdev->vq[n].vring;
 
-    vq->vring.desc = pa;
-    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
-    vq->vring.used = vring_align(vq->vring.avail +
-                                 offsetof(VRingAvail, ring[vq->vring.num]),
-                                 vq->vring.align);
+    if (!vring->desc) {
+        /* not yet setup -> nothing to do */
+        return;
+    }
+    vring->avail = vring->desc + vring->num * sizeof(VRingDesc);
+    vring->used = vring_align(vring->avail +
+                              offsetof(VRingAvail, ring[vring->num]),
+                              vring->align);
 }
 
 static inline uint64_t vring_desc_addr(VirtIODevice *vdev, hwaddr desc_pa,
@@ -605,7 +607,6 @@ void virtio_reset(void *opaque)
         vdev->vq[i].vring.avail = 0;
         vdev->vq[i].vring.used = 0;
         vdev->vq[i].last_avail_idx = 0;
-        vdev->vq[i].pa = 0;
         vdev->vq[i].vector = VIRTIO_NO_VECTOR;
         vdev->vq[i].signalled_used = 0;
         vdev->vq[i].signalled_used_valid = false;
@@ -708,13 +709,21 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
 
 void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr)
 {
-    vdev->vq[n].pa = addr;
-    virtqueue_init(&vdev->vq[n]);
+    vdev->vq[n].vring.desc = addr;
+    virtio_queue_update_rings(vdev, n);
 }
 
 hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n)
 {
-    return vdev->vq[n].pa;
+    return vdev->vq[n].vring.desc;
+}
+
+void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
+                            hwaddr avail, hwaddr used)
+{
+    vdev->vq[n].vring.desc = desc;
+    vdev->vq[n].vring.avail = avail;
+    vdev->vq[n].vring.used = used;
 }
 
 void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
@@ -728,7 +737,6 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
         return;
     }
     vdev->vq[n].vring.num = num;
-    virtqueue_init(&vdev->vq[n]);
 }
 
 int virtio_queue_get_num(VirtIODevice *vdev, int n)
@@ -748,6 +756,11 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
 
+    /* virtio-1 compliant devices cannot change the aligment */
+    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        error_report("tried to modify queue alignment for virtio-1 device");
+        return;
+    }
     /* Check that the transport told us it was going to do this
      * (so a buggy transport will immediately assert rather than
      * silently failing to migrate this state)
@@ -755,7 +768,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
     assert(k->has_variable_vring_alignment);
 
     vdev->vq[n].vring.align = align;
-    virtqueue_init(&vdev->vq[n]);
+    virtio_queue_update_rings(vdev, n);
 }
 
 void virtio_queue_notify_vq(VirtQueue *vq)
@@ -949,7 +962,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
         if (k->has_variable_vring_alignment) {
             qemu_put_be32(f, vdev->vq[i].vring.align);
         }
-        qemu_put_be64(f, vdev->vq[i].pa);
+        /* XXX virtio-1 devices */
+        qemu_put_be64(f, vdev->vq[i].vring.desc);
         qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
         if (k->save_queue) {
             k->save_queue(qbus->parent, i, f);
@@ -1044,13 +1058,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
         if (k->has_variable_vring_alignment) {
             vdev->vq[i].vring.align = qemu_get_be32(f);
         }
-        vdev->vq[i].pa = qemu_get_be64(f);
+        vdev->vq[i].vring.desc = qemu_get_be64(f);
         qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
         vdev->vq[i].signalled_used_valid = false;
         vdev->vq[i].notification = true;
 
-        if (vdev->vq[i].pa) {
-            virtqueue_init(&vdev->vq[i]);
+        if (vdev->vq[i].vring.desc) {
+            /* XXX virtio-1 devices */
+            virtio_queue_update_rings(vdev, i);
         } else if (vdev->vq[i].last_avail_idx) {
             error_report("VQ %d address 0x0 "
                          "inconsistent with Host index 0x%x",
@@ -1084,7 +1099,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     }
 
     for (i = 0; i < num; i++) {
-        if (vdev->vq[i].pa) {
+        if (vdev->vq[i].vring.desc) {
             uint16_t nheads;
             nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
             /* Check it isn't doing strange things with descriptor numbers. */
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 68c40db..b63ced3 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -224,6 +224,9 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr);
 hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n);
 void virtio_queue_set_num(VirtIODevice *vdev, int n, int num);
 int virtio_queue_get_num(VirtIODevice *vdev, int n);
+void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
+                            hwaddr avail, hwaddr used);
+void virtio_queue_update_rings(VirtIODevice *vdev, int n);
 void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
 void virtio_queue_notify(VirtIODevice *vdev, int n);
 uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

For virtio-1 devices, we allow a more complex queue layout that doesn't
require descriptor table and rings on a physically-contigous memory area:
add virtio_queue_set_rings() to allow transports to set this up.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/virtio/virtio-mmio.c    |    3 +++
 hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
 include/hw/virtio/virtio.h |    3 +++
 3 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 43b7e02..0c9b63b 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
     case VIRTIO_MMIO_QUEUENUM:
         DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
         virtio_queue_set_num(vdev, vdev->queue_sel, value);
+        /* Note: only call this function for legacy devices */
+        virtio_queue_update_rings(vdev, vdev->queue_sel);
         break;
     case VIRTIO_MMIO_QUEUEALIGN:
+        /* Note: this is only valid for legacy devices */
         virtio_queue_set_align(vdev, vdev->queue_sel, value);
         break;
     case VIRTIO_MMIO_QUEUEPFN:
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 8f69ffa..57190ba 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -69,7 +69,6 @@ typedef struct VRing
 struct VirtQueue
 {
     VRing vring;
-    hwaddr pa;
     uint16_t last_avail_idx;
     /* Last used index value we have signalled on */
     uint16_t signalled_used;
@@ -92,15 +91,18 @@ struct VirtQueue
 };
 
 /* virt queue functions */
-static void virtqueue_init(VirtQueue *vq)
+void virtio_queue_update_rings(VirtIODevice *vdev, int n)
 {
-    hwaddr pa = vq->pa;
+    VRing *vring = &vdev->vq[n].vring;
 
-    vq->vring.desc = pa;
-    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
-    vq->vring.used = vring_align(vq->vring.avail +
-                                 offsetof(VRingAvail, ring[vq->vring.num]),
-                                 vq->vring.align);
+    if (!vring->desc) {
+        /* not yet setup -> nothing to do */
+        return;
+    }
+    vring->avail = vring->desc + vring->num * sizeof(VRingDesc);
+    vring->used = vring_align(vring->avail +
+                              offsetof(VRingAvail, ring[vring->num]),
+                              vring->align);
 }
 
 static inline uint64_t vring_desc_addr(VirtIODevice *vdev, hwaddr desc_pa,
@@ -605,7 +607,6 @@ void virtio_reset(void *opaque)
         vdev->vq[i].vring.avail = 0;
         vdev->vq[i].vring.used = 0;
         vdev->vq[i].last_avail_idx = 0;
-        vdev->vq[i].pa = 0;
         vdev->vq[i].vector = VIRTIO_NO_VECTOR;
         vdev->vq[i].signalled_used = 0;
         vdev->vq[i].signalled_used_valid = false;
@@ -708,13 +709,21 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
 
 void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr)
 {
-    vdev->vq[n].pa = addr;
-    virtqueue_init(&vdev->vq[n]);
+    vdev->vq[n].vring.desc = addr;
+    virtio_queue_update_rings(vdev, n);
 }
 
 hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n)
 {
-    return vdev->vq[n].pa;
+    return vdev->vq[n].vring.desc;
+}
+
+void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
+                            hwaddr avail, hwaddr used)
+{
+    vdev->vq[n].vring.desc = desc;
+    vdev->vq[n].vring.avail = avail;
+    vdev->vq[n].vring.used = used;
 }
 
 void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
@@ -728,7 +737,6 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
         return;
     }
     vdev->vq[n].vring.num = num;
-    virtqueue_init(&vdev->vq[n]);
 }
 
 int virtio_queue_get_num(VirtIODevice *vdev, int n)
@@ -748,6 +756,11 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
 
+    /* virtio-1 compliant devices cannot change the aligment */
+    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        error_report("tried to modify queue alignment for virtio-1 device");
+        return;
+    }
     /* Check that the transport told us it was going to do this
      * (so a buggy transport will immediately assert rather than
      * silently failing to migrate this state)
@@ -755,7 +768,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
     assert(k->has_variable_vring_alignment);
 
     vdev->vq[n].vring.align = align;
-    virtqueue_init(&vdev->vq[n]);
+    virtio_queue_update_rings(vdev, n);
 }
 
 void virtio_queue_notify_vq(VirtQueue *vq)
@@ -949,7 +962,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
         if (k->has_variable_vring_alignment) {
             qemu_put_be32(f, vdev->vq[i].vring.align);
         }
-        qemu_put_be64(f, vdev->vq[i].pa);
+        /* XXX virtio-1 devices */
+        qemu_put_be64(f, vdev->vq[i].vring.desc);
         qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
         if (k->save_queue) {
             k->save_queue(qbus->parent, i, f);
@@ -1044,13 +1058,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
         if (k->has_variable_vring_alignment) {
             vdev->vq[i].vring.align = qemu_get_be32(f);
         }
-        vdev->vq[i].pa = qemu_get_be64(f);
+        vdev->vq[i].vring.desc = qemu_get_be64(f);
         qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
         vdev->vq[i].signalled_used_valid = false;
         vdev->vq[i].notification = true;
 
-        if (vdev->vq[i].pa) {
-            virtqueue_init(&vdev->vq[i]);
+        if (vdev->vq[i].vring.desc) {
+            /* XXX virtio-1 devices */
+            virtio_queue_update_rings(vdev, i);
         } else if (vdev->vq[i].last_avail_idx) {
             error_report("VQ %d address 0x0 "
                          "inconsistent with Host index 0x%x",
@@ -1084,7 +1099,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     }
 
     for (i = 0; i < num; i++) {
-        if (vdev->vq[i].pa) {
+        if (vdev->vq[i].vring.desc) {
             uint16_t nheads;
             nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
             /* Check it isn't doing strange things with descriptor numbers. */
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 68c40db..b63ced3 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -224,6 +224,9 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr);
 hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n);
 void virtio_queue_set_num(VirtIODevice *vdev, int n, int num);
 int virtio_queue_get_num(VirtIODevice *vdev, int n);
+void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
+                            hwaddr avail, hwaddr used);
+void virtio_queue_update_rings(VirtIODevice *vdev, int n);
 void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
 void virtio_queue_notify(VirtIODevice *vdev, int n);
 uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Handle endianness conversion for virtio-1 virtqueues correctly.

Note that dataplane now needs to be built per-target.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/block/dataplane/virtio-blk.c               |    4 +-
 hw/scsi/virtio-scsi-dataplane.c               |    2 +-
 hw/virtio/Makefile.objs                       |    2 +-
 hw/virtio/dataplane/Makefile.objs             |    2 +-
 hw/virtio/dataplane/vring.c                   |   86 ++++++++++++++-----------
 include/hw/virtio/dataplane/vring-accessors.h |   75 +++++++++++++++++++++
 include/hw/virtio/dataplane/vring.h           |   14 +---
 7 files changed, 131 insertions(+), 54 deletions(-)
 create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 1222a37..2d8cc15 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -16,7 +16,9 @@
 #include "qemu/iov.h"
 #include "qemu/thread.h"
 #include "qemu/error-report.h"
+#include "hw/virtio/virtio-access.h"
 #include "hw/virtio/dataplane/vring.h"
+#include "hw/virtio/dataplane/vring-accessors.h"
 #include "sysemu/block-backend.h"
 #include "hw/virtio/virtio-blk.h"
 #include "virtio-blk.h"
@@ -75,7 +77,7 @@ static void complete_request_vring(VirtIOBlockReq *req, unsigned char status)
     VirtIOBlockDataPlane *s = req->dev->dataplane;
     stb_p(&req->in->status, status);
 
-    vring_push(&req->dev->dataplane->vring, &req->elem,
+    vring_push(s->vdev, &req->dev->dataplane->vring, &req->elem,
                req->qiov.size + sizeof(*req->in));
 
     /* Suppress notification to guest by BH and its scheduled
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 03a1e8c..418d73b 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -94,7 +94,7 @@ void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(req->vring->parent);
 
-    vring_push(&req->vring->vring, &req->elem,
+    vring_push(vdev, &req->vring->vring, &req->elem,
                req->qsgl.size + req->resp_iov.size);
 
     if (vring_should_notify(vdev, &req->vring->vring)) {
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index d21c397..19b224a 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -2,7 +2,7 @@ common-obj-y += virtio-rng.o
 common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 common-obj-y += virtio-bus.o
 common-obj-y += virtio-mmio.o
-common-obj-$(CONFIG_VIRTIO) += dataplane/
+obj-$(CONFIG_VIRTIO) += dataplane/
 
 obj-y += virtio.o virtio-balloon.o 
 obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
diff --git a/hw/virtio/dataplane/Makefile.objs b/hw/virtio/dataplane/Makefile.objs
index 9a8cfc0..753a9ca 100644
--- a/hw/virtio/dataplane/Makefile.objs
+++ b/hw/virtio/dataplane/Makefile.objs
@@ -1 +1 @@
-common-obj-y += vring.o
+obj-y += vring.o
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 6e283fc..a44c8c8 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -18,7 +18,9 @@
 #include "hw/hw.h"
 #include "exec/memory.h"
 #include "exec/address-spaces.h"
+#include "hw/virtio/virtio-access.h"
 #include "hw/virtio/dataplane/vring.h"
+#include "hw/virtio/dataplane/vring-accessors.h"
 #include "qemu/error-report.h"
 
 /* vring_map can be coupled with vring_unmap or (if you still have the
@@ -83,7 +85,7 @@ bool vring_setup(Vring *vring, VirtIODevice *vdev, int n)
     vring_init(&vring->vr, virtio_queue_get_num(vdev, n), vring_ptr, 4096);
 
     vring->last_avail_idx = virtio_queue_get_last_avail_idx(vdev, n);
-    vring->last_used_idx = vring->vr.used->idx;
+    vring->last_used_idx = vring_get_used_idx(vdev, vring);
     vring->signalled_used = 0;
     vring->signalled_used_valid = false;
 
@@ -104,7 +106,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
 void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 {
     if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
-        vring->vr.used->flags |= VRING_USED_F_NO_NOTIFY;
+        vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
     }
 }
 
@@ -117,10 +119,10 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
     if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(&vring->vr) = vring->vr.avail->idx;
     } else {
-        vring->vr.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+        vring_clear_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
     }
     smp_mb(); /* ensure update is seen before reading avail_idx */
-    return !vring_more_avail(vring);
+    return !vring_more_avail(vdev, vring);
 }
 
 /* This is stolen from linux/drivers/vhost/vhost.c:vhost_notify() */
@@ -134,12 +136,13 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
     smp_mb();
 
     if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
-        unlikely(vring->vr.avail->idx == vring->last_avail_idx)) {
+        unlikely(!vring_more_avail(vdev, vring))) {
         return true;
     }
 
     if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
-        return !(vring->vr.avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
+        return !(vring_get_avail_flags(vdev, vring) &
+                 VRING_AVAIL_F_NO_INTERRUPT);
     }
     old = vring->signalled_used;
     v = vring->signalled_used_valid;
@@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
 }
 
 
-static int get_desc(Vring *vring, VirtQueueElement *elem,
+static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
                     struct vring_desc *desc)
 {
     unsigned *num;
     struct iovec *iov;
     hwaddr *addr;
     MemoryRegion *mr;
+    int is_write = virtio_tswap16(vdev, desc->flags) & VRING_DESC_F_WRITE;
+    uint32_t len = virtio_tswap32(vdev, desc->len);
+    uint64_t desc_addr = virtio_tswap64(vdev, desc->addr);
 
-    if (desc->flags & VRING_DESC_F_WRITE) {
+    if (is_write) {
         num = &elem->in_num;
         iov = &elem->in_sg[*num];
         addr = &elem->in_addr[*num];
@@ -186,44 +192,45 @@ static int get_desc(Vring *vring, VirtQueueElement *elem,
     }
 
     /* TODO handle non-contiguous memory across region boundaries */
-    iov->iov_base = vring_map(&mr, desc->addr, desc->len,
-                              desc->flags & VRING_DESC_F_WRITE);
+    iov->iov_base = vring_map(&mr, desc_addr, len, is_write);
     if (!iov->iov_base) {
         error_report("Failed to map descriptor addr %#" PRIx64 " len %u",
-                     (uint64_t)desc->addr, desc->len);
+                     (uint64_t)desc_addr, len);
         return -EFAULT;
     }
 
     /* The MemoryRegion is looked up again and unref'ed later, leave the
      * ref in place.  */
-    iov->iov_len = desc->len;
-    *addr = desc->addr;
+    iov->iov_len = len;
+    *addr = desc_addr;
     *num += 1;
     return 0;
 }
 
 /* This is stolen from linux/drivers/vhost/vhost.c. */
-static int get_indirect(Vring *vring, VirtQueueElement *elem,
-                        struct vring_desc *indirect)
+static int get_indirect(VirtIODevice *vdev, Vring *vring,
+                        VirtQueueElement *elem, struct vring_desc *indirect)
 {
     struct vring_desc desc;
     unsigned int i = 0, count, found = 0;
     int ret;
+    uint32_t len = virtio_tswap32(vdev, indirect->len);
+    uint64_t addr = virtio_tswap64(vdev, indirect->addr);
 
     /* Sanity check */
-    if (unlikely(indirect->len % sizeof(desc))) {
+    if (unlikely(len % sizeof(desc))) {
         error_report("Invalid length in indirect descriptor: "
                      "len %#x not multiple of %#zx",
-                     indirect->len, sizeof(desc));
+                     len, sizeof(desc));
         vring->broken = true;
         return -EFAULT;
     }
 
-    count = indirect->len / sizeof(desc);
+    count = len / sizeof(desc);
     /* Buffers are chained via a 16 bit next field, so
      * we can have at most 2^16 of these. */
     if (unlikely(count > USHRT_MAX + 1)) {
-        error_report("Indirect buffer length too big: %d", indirect->len);
+        error_report("Indirect buffer length too big: %d", len);
         vring->broken = true;
         return -EFAULT;
     }
@@ -234,12 +241,12 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem,
 
         /* Translate indirect descriptor */
         desc_ptr = vring_map(&mr,
-                             indirect->addr + found * sizeof(desc),
+                             addr + found * sizeof(desc),
                              sizeof(desc), false);
         if (!desc_ptr) {
             error_report("Failed to map indirect descriptor "
                          "addr %#" PRIx64 " len %zu",
-                         (uint64_t)indirect->addr + found * sizeof(desc),
+                         (uint64_t)addr + found * sizeof(desc),
                          sizeof(desc));
             vring->broken = true;
             return -EFAULT;
@@ -257,19 +264,20 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem,
             return -EFAULT;
         }
 
-        if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) {
+        if (unlikely(virtio_tswap16(vdev, desc.flags)
+                     & VRING_DESC_F_INDIRECT)) {
             error_report("Nested indirect descriptor");
             vring->broken = true;
             return -EFAULT;
         }
 
-        ret = get_desc(vring, elem, &desc);
+        ret = get_desc(vdev, vring, elem, &desc);
         if (ret < 0) {
             vring->broken |= (ret == -EFAULT);
             return ret;
         }
-        i = desc.next;
-    } while (desc.flags & VRING_DESC_F_NEXT);
+        i = virtio_tswap16(vdev, desc.next);
+    } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
     return 0;
 }
 
@@ -320,7 +328,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 
     /* Check it isn't doing very strange things with descriptor numbers. */
     last_avail_idx = vring->last_avail_idx;
-    avail_idx = vring->vr.avail->idx;
+    avail_idx = vring_get_avail_idx(vdev, vring);
     barrier(); /* load indices now and not again later */
 
     if (unlikely((uint16_t)(avail_idx - last_avail_idx) > num)) {
@@ -341,7 +349,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 
     /* Grab the next descriptor number they're advertising, and increment
      * the index we've seen. */
-    head = vring->vr.avail->ring[last_avail_idx % num];
+    head = vring_get_avail_ring(vdev, vring, last_avail_idx % num);
 
     elem->index = head;
 
@@ -370,21 +378,21 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
         /* Ensure descriptor is loaded before accessing fields */
         barrier();
 
-        if (desc.flags & VRING_DESC_F_INDIRECT) {
-            ret = get_indirect(vring, elem, &desc);
+        if (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_INDIRECT) {
+            ret = get_indirect(vdev, vring, elem, &desc);
             if (ret < 0) {
                 goto out;
             }
             continue;
         }
 
-        ret = get_desc(vring, elem, &desc);
+        ret = get_desc(vdev, vring, elem, &desc);
         if (ret < 0) {
             goto out;
         }
 
-        i = desc.next;
-    } while (desc.flags & VRING_DESC_F_NEXT);
+        i = virtio_tswap16(vdev, desc.next);
+    } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
 
     /* On success, increment avail index. */
     vring->last_avail_idx++;
@@ -407,9 +415,9 @@ out:
  *
  * Stolen from linux/drivers/vhost/vhost.c.
  */
-void vring_push(Vring *vring, VirtQueueElement *elem, int len)
+void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
+                int len)
 {
-    struct vring_used_elem *used;
     unsigned int head = elem->index;
     uint16_t new;
 
@@ -422,14 +430,16 @@ void vring_push(Vring *vring, VirtQueueElement *elem, int len)
 
     /* The virtqueue contains a ring of used buffers.  Get a pointer to the
      * next entry in that used ring. */
-    used = &vring->vr.used->ring[vring->last_used_idx % vring->vr.num];
-    used->id = head;
-    used->len = len;
+    vring_set_used_ring_id(vdev, vring, vring->last_used_idx % vring->vr.num,
+                           head);
+    vring_set_used_ring_len(vdev, vring, vring->last_used_idx % vring->vr.num,
+                            len);
 
     /* Make sure buffer is written before we update index. */
     smp_wmb();
 
-    new = vring->vr.used->idx = ++vring->last_used_idx;
+    new = ++vring->last_used_idx;
+    vring_set_used_idx(vdev, vring, new);
     if (unlikely((int16_t)(new - vring->signalled_used) < (uint16_t)1)) {
         vring->signalled_used_valid = false;
     }
diff --git a/include/hw/virtio/dataplane/vring-accessors.h b/include/hw/virtio/dataplane/vring-accessors.h
new file mode 100644
index 0000000..b508b87
--- /dev/null
+++ b/include/hw/virtio/dataplane/vring-accessors.h
@@ -0,0 +1,75 @@
+#ifndef VRING_ACCESSORS_H
+#define VRING_ACCESSORS_H
+
+#include "hw/virtio/virtio_ring.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-access.h"
+
+static inline uint16_t vring_get_used_idx(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.used->idx);
+}
+
+static inline void vring_set_used_idx(VirtIODevice *vdev, Vring *vring,
+                                      uint16_t idx)
+{
+    vring->vr.used->idx = virtio_tswap16(vdev, idx);
+}
+
+static inline uint16_t vring_get_avail_idx(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.avail->idx);
+}
+
+static inline uint16_t vring_get_avail_ring(VirtIODevice *vdev, Vring *vring,
+                                            int i)
+{
+    return virtio_tswap16(vdev, vring->vr.avail->ring[i]);
+}
+
+static inline void vring_set_used_ring_id(VirtIODevice *vdev, Vring *vring,
+                                          int i, uint32_t id)
+{
+    vring->vr.used->ring[i].id = virtio_tswap32(vdev, id);
+}
+
+static inline void vring_set_used_ring_len(VirtIODevice *vdev, Vring *vring,
+                                          int i, uint32_t len)
+{
+    vring->vr.used->ring[i].len = virtio_tswap32(vdev, len);
+}
+
+static inline uint16_t vring_get_used_flags(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.used->flags);
+}
+
+static inline uint16_t vring_get_avail_flags(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.avail->flags);
+}
+
+static inline void vring_set_used_flags(VirtIODevice *vdev, Vring *vring,
+                                        uint16_t flags)
+{
+    vring->vr.used->flags |= virtio_tswap16(vdev, flags);
+}
+
+static inline void vring_clear_used_flags(VirtIODevice *vdev, Vring *vring,
+                                          uint16_t flags)
+{
+    vring->vr.used->flags &= virtio_tswap16(vdev, ~flags);
+}
+
+static inline unsigned int vring_get_num(Vring *vring)
+{
+    return vring->vr.num;
+}
+
+/* Are there more descriptors available? */
+static inline bool vring_more_avail(VirtIODevice *vdev, Vring *vring)
+{
+    return vring_get_avail_idx(vdev, vring) != vring->last_avail_idx;
+}
+
+#endif
diff --git a/include/hw/virtio/dataplane/vring.h b/include/hw/virtio/dataplane/vring.h
index d3e086a..e42c0fc 100644
--- a/include/hw/virtio/dataplane/vring.h
+++ b/include/hw/virtio/dataplane/vring.h
@@ -31,17 +31,6 @@ typedef struct {
     bool broken;                    /* was there a fatal error? */
 } Vring;
 
-static inline unsigned int vring_get_num(Vring *vring)
-{
-    return vring->vr.num;
-}
-
-/* Are there more descriptors available? */
-static inline bool vring_more_avail(Vring *vring)
-{
-    return vring->vr.avail->idx != vring->last_avail_idx;
-}
-
 /* Fail future vring_pop() and vring_push() calls until reset */
 static inline void vring_set_broken(Vring *vring)
 {
@@ -54,6 +43,7 @@ void vring_disable_notification(VirtIODevice *vdev, Vring *vring);
 bool vring_enable_notification(VirtIODevice *vdev, Vring *vring);
 bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
 int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem);
-void vring_push(Vring *vring, VirtQueueElement *elem, int len);
+void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
+                int len);
 
 #endif /* VRING_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Handle endianness conversion for virtio-1 virtqueues correctly.

Note that dataplane now needs to be built per-target.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/block/dataplane/virtio-blk.c               |    4 +-
 hw/scsi/virtio-scsi-dataplane.c               |    2 +-
 hw/virtio/Makefile.objs                       |    2 +-
 hw/virtio/dataplane/Makefile.objs             |    2 +-
 hw/virtio/dataplane/vring.c                   |   86 ++++++++++++++-----------
 include/hw/virtio/dataplane/vring-accessors.h |   75 +++++++++++++++++++++
 include/hw/virtio/dataplane/vring.h           |   14 +---
 7 files changed, 131 insertions(+), 54 deletions(-)
 create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 1222a37..2d8cc15 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -16,7 +16,9 @@
 #include "qemu/iov.h"
 #include "qemu/thread.h"
 #include "qemu/error-report.h"
+#include "hw/virtio/virtio-access.h"
 #include "hw/virtio/dataplane/vring.h"
+#include "hw/virtio/dataplane/vring-accessors.h"
 #include "sysemu/block-backend.h"
 #include "hw/virtio/virtio-blk.h"
 #include "virtio-blk.h"
@@ -75,7 +77,7 @@ static void complete_request_vring(VirtIOBlockReq *req, unsigned char status)
     VirtIOBlockDataPlane *s = req->dev->dataplane;
     stb_p(&req->in->status, status);
 
-    vring_push(&req->dev->dataplane->vring, &req->elem,
+    vring_push(s->vdev, &req->dev->dataplane->vring, &req->elem,
                req->qiov.size + sizeof(*req->in));
 
     /* Suppress notification to guest by BH and its scheduled
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 03a1e8c..418d73b 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -94,7 +94,7 @@ void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(req->vring->parent);
 
-    vring_push(&req->vring->vring, &req->elem,
+    vring_push(vdev, &req->vring->vring, &req->elem,
                req->qsgl.size + req->resp_iov.size);
 
     if (vring_should_notify(vdev, &req->vring->vring)) {
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index d21c397..19b224a 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -2,7 +2,7 @@ common-obj-y += virtio-rng.o
 common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 common-obj-y += virtio-bus.o
 common-obj-y += virtio-mmio.o
-common-obj-$(CONFIG_VIRTIO) += dataplane/
+obj-$(CONFIG_VIRTIO) += dataplane/
 
 obj-y += virtio.o virtio-balloon.o 
 obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
diff --git a/hw/virtio/dataplane/Makefile.objs b/hw/virtio/dataplane/Makefile.objs
index 9a8cfc0..753a9ca 100644
--- a/hw/virtio/dataplane/Makefile.objs
+++ b/hw/virtio/dataplane/Makefile.objs
@@ -1 +1 @@
-common-obj-y += vring.o
+obj-y += vring.o
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 6e283fc..a44c8c8 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -18,7 +18,9 @@
 #include "hw/hw.h"
 #include "exec/memory.h"
 #include "exec/address-spaces.h"
+#include "hw/virtio/virtio-access.h"
 #include "hw/virtio/dataplane/vring.h"
+#include "hw/virtio/dataplane/vring-accessors.h"
 #include "qemu/error-report.h"
 
 /* vring_map can be coupled with vring_unmap or (if you still have the
@@ -83,7 +85,7 @@ bool vring_setup(Vring *vring, VirtIODevice *vdev, int n)
     vring_init(&vring->vr, virtio_queue_get_num(vdev, n), vring_ptr, 4096);
 
     vring->last_avail_idx = virtio_queue_get_last_avail_idx(vdev, n);
-    vring->last_used_idx = vring->vr.used->idx;
+    vring->last_used_idx = vring_get_used_idx(vdev, vring);
     vring->signalled_used = 0;
     vring->signalled_used_valid = false;
 
@@ -104,7 +106,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
 void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 {
     if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
-        vring->vr.used->flags |= VRING_USED_F_NO_NOTIFY;
+        vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
     }
 }
 
@@ -117,10 +119,10 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
     if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(&vring->vr) = vring->vr.avail->idx;
     } else {
-        vring->vr.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+        vring_clear_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
     }
     smp_mb(); /* ensure update is seen before reading avail_idx */
-    return !vring_more_avail(vring);
+    return !vring_more_avail(vdev, vring);
 }
 
 /* This is stolen from linux/drivers/vhost/vhost.c:vhost_notify() */
@@ -134,12 +136,13 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
     smp_mb();
 
     if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
-        unlikely(vring->vr.avail->idx == vring->last_avail_idx)) {
+        unlikely(!vring_more_avail(vdev, vring))) {
         return true;
     }
 
     if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
-        return !(vring->vr.avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
+        return !(vring_get_avail_flags(vdev, vring) &
+                 VRING_AVAIL_F_NO_INTERRUPT);
     }
     old = vring->signalled_used;
     v = vring->signalled_used_valid;
@@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
 }
 
 
-static int get_desc(Vring *vring, VirtQueueElement *elem,
+static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
                     struct vring_desc *desc)
 {
     unsigned *num;
     struct iovec *iov;
     hwaddr *addr;
     MemoryRegion *mr;
+    int is_write = virtio_tswap16(vdev, desc->flags) & VRING_DESC_F_WRITE;
+    uint32_t len = virtio_tswap32(vdev, desc->len);
+    uint64_t desc_addr = virtio_tswap64(vdev, desc->addr);
 
-    if (desc->flags & VRING_DESC_F_WRITE) {
+    if (is_write) {
         num = &elem->in_num;
         iov = &elem->in_sg[*num];
         addr = &elem->in_addr[*num];
@@ -186,44 +192,45 @@ static int get_desc(Vring *vring, VirtQueueElement *elem,
     }
 
     /* TODO handle non-contiguous memory across region boundaries */
-    iov->iov_base = vring_map(&mr, desc->addr, desc->len,
-                              desc->flags & VRING_DESC_F_WRITE);
+    iov->iov_base = vring_map(&mr, desc_addr, len, is_write);
     if (!iov->iov_base) {
         error_report("Failed to map descriptor addr %#" PRIx64 " len %u",
-                     (uint64_t)desc->addr, desc->len);
+                     (uint64_t)desc_addr, len);
         return -EFAULT;
     }
 
     /* The MemoryRegion is looked up again and unref'ed later, leave the
      * ref in place.  */
-    iov->iov_len = desc->len;
-    *addr = desc->addr;
+    iov->iov_len = len;
+    *addr = desc_addr;
     *num += 1;
     return 0;
 }
 
 /* This is stolen from linux/drivers/vhost/vhost.c. */
-static int get_indirect(Vring *vring, VirtQueueElement *elem,
-                        struct vring_desc *indirect)
+static int get_indirect(VirtIODevice *vdev, Vring *vring,
+                        VirtQueueElement *elem, struct vring_desc *indirect)
 {
     struct vring_desc desc;
     unsigned int i = 0, count, found = 0;
     int ret;
+    uint32_t len = virtio_tswap32(vdev, indirect->len);
+    uint64_t addr = virtio_tswap64(vdev, indirect->addr);
 
     /* Sanity check */
-    if (unlikely(indirect->len % sizeof(desc))) {
+    if (unlikely(len % sizeof(desc))) {
         error_report("Invalid length in indirect descriptor: "
                      "len %#x not multiple of %#zx",
-                     indirect->len, sizeof(desc));
+                     len, sizeof(desc));
         vring->broken = true;
         return -EFAULT;
     }
 
-    count = indirect->len / sizeof(desc);
+    count = len / sizeof(desc);
     /* Buffers are chained via a 16 bit next field, so
      * we can have at most 2^16 of these. */
     if (unlikely(count > USHRT_MAX + 1)) {
-        error_report("Indirect buffer length too big: %d", indirect->len);
+        error_report("Indirect buffer length too big: %d", len);
         vring->broken = true;
         return -EFAULT;
     }
@@ -234,12 +241,12 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem,
 
         /* Translate indirect descriptor */
         desc_ptr = vring_map(&mr,
-                             indirect->addr + found * sizeof(desc),
+                             addr + found * sizeof(desc),
                              sizeof(desc), false);
         if (!desc_ptr) {
             error_report("Failed to map indirect descriptor "
                          "addr %#" PRIx64 " len %zu",
-                         (uint64_t)indirect->addr + found * sizeof(desc),
+                         (uint64_t)addr + found * sizeof(desc),
                          sizeof(desc));
             vring->broken = true;
             return -EFAULT;
@@ -257,19 +264,20 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem,
             return -EFAULT;
         }
 
-        if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) {
+        if (unlikely(virtio_tswap16(vdev, desc.flags)
+                     & VRING_DESC_F_INDIRECT)) {
             error_report("Nested indirect descriptor");
             vring->broken = true;
             return -EFAULT;
         }
 
-        ret = get_desc(vring, elem, &desc);
+        ret = get_desc(vdev, vring, elem, &desc);
         if (ret < 0) {
             vring->broken |= (ret == -EFAULT);
             return ret;
         }
-        i = desc.next;
-    } while (desc.flags & VRING_DESC_F_NEXT);
+        i = virtio_tswap16(vdev, desc.next);
+    } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
     return 0;
 }
 
@@ -320,7 +328,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 
     /* Check it isn't doing very strange things with descriptor numbers. */
     last_avail_idx = vring->last_avail_idx;
-    avail_idx = vring->vr.avail->idx;
+    avail_idx = vring_get_avail_idx(vdev, vring);
     barrier(); /* load indices now and not again later */
 
     if (unlikely((uint16_t)(avail_idx - last_avail_idx) > num)) {
@@ -341,7 +349,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 
     /* Grab the next descriptor number they're advertising, and increment
      * the index we've seen. */
-    head = vring->vr.avail->ring[last_avail_idx % num];
+    head = vring_get_avail_ring(vdev, vring, last_avail_idx % num);
 
     elem->index = head;
 
@@ -370,21 +378,21 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
         /* Ensure descriptor is loaded before accessing fields */
         barrier();
 
-        if (desc.flags & VRING_DESC_F_INDIRECT) {
-            ret = get_indirect(vring, elem, &desc);
+        if (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_INDIRECT) {
+            ret = get_indirect(vdev, vring, elem, &desc);
             if (ret < 0) {
                 goto out;
             }
             continue;
         }
 
-        ret = get_desc(vring, elem, &desc);
+        ret = get_desc(vdev, vring, elem, &desc);
         if (ret < 0) {
             goto out;
         }
 
-        i = desc.next;
-    } while (desc.flags & VRING_DESC_F_NEXT);
+        i = virtio_tswap16(vdev, desc.next);
+    } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
 
     /* On success, increment avail index. */
     vring->last_avail_idx++;
@@ -407,9 +415,9 @@ out:
  *
  * Stolen from linux/drivers/vhost/vhost.c.
  */
-void vring_push(Vring *vring, VirtQueueElement *elem, int len)
+void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
+                int len)
 {
-    struct vring_used_elem *used;
     unsigned int head = elem->index;
     uint16_t new;
 
@@ -422,14 +430,16 @@ void vring_push(Vring *vring, VirtQueueElement *elem, int len)
 
     /* The virtqueue contains a ring of used buffers.  Get a pointer to the
      * next entry in that used ring. */
-    used = &vring->vr.used->ring[vring->last_used_idx % vring->vr.num];
-    used->id = head;
-    used->len = len;
+    vring_set_used_ring_id(vdev, vring, vring->last_used_idx % vring->vr.num,
+                           head);
+    vring_set_used_ring_len(vdev, vring, vring->last_used_idx % vring->vr.num,
+                            len);
 
     /* Make sure buffer is written before we update index. */
     smp_wmb();
 
-    new = vring->vr.used->idx = ++vring->last_used_idx;
+    new = ++vring->last_used_idx;
+    vring_set_used_idx(vdev, vring, new);
     if (unlikely((int16_t)(new - vring->signalled_used) < (uint16_t)1)) {
         vring->signalled_used_valid = false;
     }
diff --git a/include/hw/virtio/dataplane/vring-accessors.h b/include/hw/virtio/dataplane/vring-accessors.h
new file mode 100644
index 0000000..b508b87
--- /dev/null
+++ b/include/hw/virtio/dataplane/vring-accessors.h
@@ -0,0 +1,75 @@
+#ifndef VRING_ACCESSORS_H
+#define VRING_ACCESSORS_H
+
+#include "hw/virtio/virtio_ring.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-access.h"
+
+static inline uint16_t vring_get_used_idx(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.used->idx);
+}
+
+static inline void vring_set_used_idx(VirtIODevice *vdev, Vring *vring,
+                                      uint16_t idx)
+{
+    vring->vr.used->idx = virtio_tswap16(vdev, idx);
+}
+
+static inline uint16_t vring_get_avail_idx(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.avail->idx);
+}
+
+static inline uint16_t vring_get_avail_ring(VirtIODevice *vdev, Vring *vring,
+                                            int i)
+{
+    return virtio_tswap16(vdev, vring->vr.avail->ring[i]);
+}
+
+static inline void vring_set_used_ring_id(VirtIODevice *vdev, Vring *vring,
+                                          int i, uint32_t id)
+{
+    vring->vr.used->ring[i].id = virtio_tswap32(vdev, id);
+}
+
+static inline void vring_set_used_ring_len(VirtIODevice *vdev, Vring *vring,
+                                          int i, uint32_t len)
+{
+    vring->vr.used->ring[i].len = virtio_tswap32(vdev, len);
+}
+
+static inline uint16_t vring_get_used_flags(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.used->flags);
+}
+
+static inline uint16_t vring_get_avail_flags(VirtIODevice *vdev, Vring *vring)
+{
+    return virtio_tswap16(vdev, vring->vr.avail->flags);
+}
+
+static inline void vring_set_used_flags(VirtIODevice *vdev, Vring *vring,
+                                        uint16_t flags)
+{
+    vring->vr.used->flags |= virtio_tswap16(vdev, flags);
+}
+
+static inline void vring_clear_used_flags(VirtIODevice *vdev, Vring *vring,
+                                          uint16_t flags)
+{
+    vring->vr.used->flags &= virtio_tswap16(vdev, ~flags);
+}
+
+static inline unsigned int vring_get_num(Vring *vring)
+{
+    return vring->vr.num;
+}
+
+/* Are there more descriptors available? */
+static inline bool vring_more_avail(VirtIODevice *vdev, Vring *vring)
+{
+    return vring_get_avail_idx(vdev, vring) != vring->last_avail_idx;
+}
+
+#endif
diff --git a/include/hw/virtio/dataplane/vring.h b/include/hw/virtio/dataplane/vring.h
index d3e086a..e42c0fc 100644
--- a/include/hw/virtio/dataplane/vring.h
+++ b/include/hw/virtio/dataplane/vring.h
@@ -31,17 +31,6 @@ typedef struct {
     bool broken;                    /* was there a fatal error? */
 } Vring;
 
-static inline unsigned int vring_get_num(Vring *vring)
-{
-    return vring->vr.num;
-}
-
-/* Are there more descriptors available? */
-static inline bool vring_more_avail(Vring *vring)
-{
-    return vring->vr.avail->idx != vring->last_avail_idx;
-}
-
 /* Fail future vring_pop() and vring_push() calls until reset */
 static inline void vring_set_broken(Vring *vring)
 {
@@ -54,6 +43,7 @@ void vring_disable_notification(VirtIODevice *vdev, Vring *vring);
 bool vring_enable_notification(VirtIODevice *vdev, Vring *vring);
 bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
 int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem);
-void vring_push(Vring *vring, VirtQueueElement *elem, int len);
+void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
+                int len);
 
 #endif /* VRING_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 09/20] s390x/css: Add a callback for when subchannel gets disabled
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

From: Thomas Huth <thuth@linux.vnet.ibm.com>

We need a possibility to run code when a subchannel gets disabled.
This patch adds the necessary infrastructure.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/css.c |   12 ++++++++++++
 hw/s390x/css.h |    1 +
 2 files changed, 13 insertions(+)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index b67c039..735ec55 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -588,6 +588,7 @@ int css_do_msch(SubchDev *sch, SCHIB *orig_schib)
 {
     SCSW *s = &sch->curr_status.scsw;
     PMCW *p = &sch->curr_status.pmcw;
+    uint16_t oldflags;
     int ret;
     SCHIB schib;
 
@@ -610,6 +611,7 @@ int css_do_msch(SubchDev *sch, SCHIB *orig_schib)
     copy_schib_from_guest(&schib, orig_schib);
     /* Only update the program-modifiable fields. */
     p->intparm = schib.pmcw.intparm;
+    oldflags = p->flags;
     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
                   PMCW_FLAGS_MASK_MP);
@@ -625,6 +627,12 @@ int css_do_msch(SubchDev *sch, SCHIB *orig_schib)
             (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
     sch->curr_status.mba = schib.mba;
 
+    /* Has the channel been disabled? */
+    if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
+        && (p->flags & PMCW_FLAGS_MASK_ENA) == 0) {
+        sch->disable_cb(sch);
+    }
+
     ret = 0;
 
 out:
@@ -1443,6 +1451,10 @@ void css_reset_sch(SubchDev *sch)
 {
     PMCW *p = &sch->curr_status.pmcw;
 
+    if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
+        sch->disable_cb(sch);
+    }
+
     p->intparm = 0;
     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 33104ac..7fa807b 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -81,6 +81,7 @@ struct SubchDev {
     uint8_t ccw_no_data_cnt;
     /* transport-provided data: */
     int (*ccw_cb) (SubchDev *, CCW1);
+    void (*disable_cb)(SubchDev *);
     SenseId id;
     void *driver_data;
 };
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 09/20] s390x/css: Add a callback for when subchannel gets disabled
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

From: Thomas Huth <thuth@linux.vnet.ibm.com>

We need a possibility to run code when a subchannel gets disabled.
This patch adds the necessary infrastructure.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/css.c |   12 ++++++++++++
 hw/s390x/css.h |    1 +
 2 files changed, 13 insertions(+)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index b67c039..735ec55 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -588,6 +588,7 @@ int css_do_msch(SubchDev *sch, SCHIB *orig_schib)
 {
     SCSW *s = &sch->curr_status.scsw;
     PMCW *p = &sch->curr_status.pmcw;
+    uint16_t oldflags;
     int ret;
     SCHIB schib;
 
@@ -610,6 +611,7 @@ int css_do_msch(SubchDev *sch, SCHIB *orig_schib)
     copy_schib_from_guest(&schib, orig_schib);
     /* Only update the program-modifiable fields. */
     p->intparm = schib.pmcw.intparm;
+    oldflags = p->flags;
     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
                   PMCW_FLAGS_MASK_MP);
@@ -625,6 +627,12 @@ int css_do_msch(SubchDev *sch, SCHIB *orig_schib)
             (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE);
     sch->curr_status.mba = schib.mba;
 
+    /* Has the channel been disabled? */
+    if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0
+        && (p->flags & PMCW_FLAGS_MASK_ENA) == 0) {
+        sch->disable_cb(sch);
+    }
+
     ret = 0;
 
 out:
@@ -1443,6 +1451,10 @@ void css_reset_sch(SubchDev *sch)
 {
     PMCW *p = &sch->curr_status.pmcw;
 
+    if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) {
+        sch->disable_cb(sch);
+    }
+
     p->intparm = 0;
     p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA |
                   PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME |
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index 33104ac..7fa807b 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -81,6 +81,7 @@ struct SubchDev {
     uint8_t ccw_no_data_cnt;
     /* transport-provided data: */
     int (*ccw_cb) (SubchDev *, CCW1);
+    void (*disable_cb)(SubchDev *);
     SenseId id;
     void *driver_data;
 };
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

From: Thomas Huth <thuth@linux.vnet.ibm.com>

Handle the virtio-ccw revision according to what the guest sets.
When revision 1 is selected, we have a virtio-1 standard device
with byteswapping for the virtio rings.

When a channel gets disabled, we have to revert to the legacy behavior
in case the next user of the device does not negotiate the revision 1
anymore (e.g. the boot firmware uses revision 1, but the operating
system only uses the legacy mode).

Note that revisions > 0 are still disabled.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/s390x/virtio-ccw.h |    8 ++++++++
 2 files changed, 60 insertions(+)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index fbd909d..ea2c6f0 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -20,9 +20,11 @@
 #include "hw/virtio/virtio-net.h"
 #include "hw/sysbus.h"
 #include "qemu/bitops.h"
+#include "hw/virtio/virtio-access.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/s390x/adapter.h"
 #include "hw/s390x/s390_flic.h"
+#include "linux/virtio_config.h"
 
 #include "ioinst.h"
 #include "css.h"
@@ -260,6 +262,12 @@ typedef struct VirtioThinintInfo {
     uint8_t isc;
 } QEMU_PACKED VirtioThinintInfo;
 
+typedef struct VirtioRevInfo {
+    uint16_t revision;
+    uint16_t length;
+    uint8_t data[0];
+} QEMU_PACKED VirtioRevInfo;
+
 /* Specify where the virtqueues for the subchannel are in guest memory. */
 static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
                               uint16_t index, uint16_t num)
@@ -299,6 +307,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
 {
     int ret;
     VqInfoBlock info;
+    VirtioRevInfo revinfo;
     uint8_t status;
     VirtioFeatDesc features;
     void *config;
@@ -375,6 +384,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
                 features.features = (uint32_t)dev->host_features;
             } else if (features.index == 1) {
                 features.features = (uint32_t)(dev->host_features >> 32);
+                /*
+                 * Don't offer version 1 to the guest if it did not
+                 * negotiate at least revision 1.
+                 */
+                if (dev->revision <= 0) {
+                    features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32));
+                }
             } else {
                 /* Return zeroes if the guest supports more feature bits. */
                 features.features = 0;
@@ -406,6 +422,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
                                     (vdev->guest_features & 0xffffffff00000000) |
                                     features.features);
             } else if (features.index == 1) {
+                /*
+                 * The guest should not set version 1 if it didn't
+                 * negotiate a revision >= 1.
+                 */
+                if (dev->revision <= 0) {
+                    features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32));
+                }
                 virtio_set_features(vdev,
                                     (vdev->guest_features & 0x00000000ffffffff) |
                                     ((uint64_t)features.features << 32));
@@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             }
         }
         break;
+    case CCW_CMD_SET_VIRTIO_REV:
+        len = sizeof(revinfo);
+        if (ccw.count < len || (check_len && ccw.count > len)) {
+            ret = -EINVAL;
+            break;
+        }
+        if (!ccw.cda) {
+            ret = -EFAULT;
+            break;
+        }
+        cpu_physical_memory_read(ccw.cda, &revinfo, len);
+        if (dev->revision >= 0 ||
+            revinfo.revision > virtio_ccw_rev_max(dev)) {
+            ret = -ENOSYS;
+            break;
+        }
+        ret = 0;
+        dev->revision = revinfo.revision;
+        break;
     default:
         ret = -ENOSYS;
         break;
@@ -615,6 +657,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
     return ret;
 }
 
+static void virtio_sch_disable_cb(SubchDev *sch)
+{
+    VirtioCcwDevice *dev = sch->driver_data;
+
+    dev->revision = -1;
+}
+
 static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
 {
     unsigned int cssid = 0;
@@ -740,6 +789,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
 
     sch->ccw_cb = virtio_ccw_cb;
+    sch->disable_cb = virtio_sch_disable_cb;
 
     /* Build senseid data. */
     memset(&sch->id, 0, sizeof(SenseId));
@@ -747,6 +797,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
     sch->id.cu_model = vdev->device_id;
 
+    dev->revision = -1;
+
     /* Set default feature bits that are offered by the host. */
     virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
     virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 9087f7a..778ccb9 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -40,6 +40,7 @@
 #define CCW_CMD_SET_CONF_IND 0x53
 #define CCW_CMD_READ_VQ_CONF 0x32
 #define CCW_CMD_SET_IND_ADAPTER 0x73
+#define CCW_CMD_SET_VIRTIO_REV 0x83
 
 #define TYPE_VIRTIO_CCW_DEVICE "virtio-ccw-device"
 #define VIRTIO_CCW_DEVICE(obj) \
@@ -86,6 +87,7 @@ struct VirtioCcwDevice {
     SubchDev *sch;
     char *bus_id;
     uint64_t host_features;
+    int revision;
     VirtioBusState bus;
     bool ioeventfd_started;
     bool ioeventfd_disabled;
@@ -99,6 +101,12 @@ struct VirtioCcwDevice {
     uint64_t ind_bit;
 };
 
+/* The maximum virtio revision we support. */
+static inline int virtio_ccw_rev_max(VirtioCcwDevice *dev)
+{
+    return 0;
+}
+
 /* virtual css bus type */
 typedef struct VirtualCssBus {
     BusState parent_obj;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

From: Thomas Huth <thuth@linux.vnet.ibm.com>

Handle the virtio-ccw revision according to what the guest sets.
When revision 1 is selected, we have a virtio-1 standard device
with byteswapping for the virtio rings.

When a channel gets disabled, we have to revert to the legacy behavior
in case the next user of the device does not negotiate the revision 1
anymore (e.g. the boot firmware uses revision 1, but the operating
system only uses the legacy mode).

Note that revisions > 0 are still disabled.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/s390x/virtio-ccw.h |    8 ++++++++
 2 files changed, 60 insertions(+)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index fbd909d..ea2c6f0 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -20,9 +20,11 @@
 #include "hw/virtio/virtio-net.h"
 #include "hw/sysbus.h"
 #include "qemu/bitops.h"
+#include "hw/virtio/virtio-access.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/s390x/adapter.h"
 #include "hw/s390x/s390_flic.h"
+#include "linux/virtio_config.h"
 
 #include "ioinst.h"
 #include "css.h"
@@ -260,6 +262,12 @@ typedef struct VirtioThinintInfo {
     uint8_t isc;
 } QEMU_PACKED VirtioThinintInfo;
 
+typedef struct VirtioRevInfo {
+    uint16_t revision;
+    uint16_t length;
+    uint8_t data[0];
+} QEMU_PACKED VirtioRevInfo;
+
 /* Specify where the virtqueues for the subchannel are in guest memory. */
 static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
                               uint16_t index, uint16_t num)
@@ -299,6 +307,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
 {
     int ret;
     VqInfoBlock info;
+    VirtioRevInfo revinfo;
     uint8_t status;
     VirtioFeatDesc features;
     void *config;
@@ -375,6 +384,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
                 features.features = (uint32_t)dev->host_features;
             } else if (features.index == 1) {
                 features.features = (uint32_t)(dev->host_features >> 32);
+                /*
+                 * Don't offer version 1 to the guest if it did not
+                 * negotiate at least revision 1.
+                 */
+                if (dev->revision <= 0) {
+                    features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32));
+                }
             } else {
                 /* Return zeroes if the guest supports more feature bits. */
                 features.features = 0;
@@ -406,6 +422,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
                                     (vdev->guest_features & 0xffffffff00000000) |
                                     features.features);
             } else if (features.index == 1) {
+                /*
+                 * The guest should not set version 1 if it didn't
+                 * negotiate a revision >= 1.
+                 */
+                if (dev->revision <= 0) {
+                    features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32));
+                }
                 virtio_set_features(vdev,
                                     (vdev->guest_features & 0x00000000ffffffff) |
                                     ((uint64_t)features.features << 32));
@@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             }
         }
         break;
+    case CCW_CMD_SET_VIRTIO_REV:
+        len = sizeof(revinfo);
+        if (ccw.count < len || (check_len && ccw.count > len)) {
+            ret = -EINVAL;
+            break;
+        }
+        if (!ccw.cda) {
+            ret = -EFAULT;
+            break;
+        }
+        cpu_physical_memory_read(ccw.cda, &revinfo, len);
+        if (dev->revision >= 0 ||
+            revinfo.revision > virtio_ccw_rev_max(dev)) {
+            ret = -ENOSYS;
+            break;
+        }
+        ret = 0;
+        dev->revision = revinfo.revision;
+        break;
     default:
         ret = -ENOSYS;
         break;
@@ -615,6 +657,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
     return ret;
 }
 
+static void virtio_sch_disable_cb(SubchDev *sch)
+{
+    VirtioCcwDevice *dev = sch->driver_data;
+
+    dev->revision = -1;
+}
+
 static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
 {
     unsigned int cssid = 0;
@@ -740,6 +789,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
 
     sch->ccw_cb = virtio_ccw_cb;
+    sch->disable_cb = virtio_sch_disable_cb;
 
     /* Build senseid data. */
     memset(&sch->id, 0, sizeof(SenseId));
@@ -747,6 +797,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
     sch->id.cu_model = vdev->device_id;
 
+    dev->revision = -1;
+
     /* Set default feature bits that are offered by the host. */
     virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
     virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 9087f7a..778ccb9 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -40,6 +40,7 @@
 #define CCW_CMD_SET_CONF_IND 0x53
 #define CCW_CMD_READ_VQ_CONF 0x32
 #define CCW_CMD_SET_IND_ADAPTER 0x73
+#define CCW_CMD_SET_VIRTIO_REV 0x83
 
 #define TYPE_VIRTIO_CCW_DEVICE "virtio-ccw-device"
 #define VIRTIO_CCW_DEVICE(obj) \
@@ -86,6 +87,7 @@ struct VirtioCcwDevice {
     SubchDev *sch;
     char *bus_id;
     uint64_t host_features;
+    int revision;
     VirtioBusState bus;
     bool ioeventfd_started;
     bool ioeventfd_disabled;
@@ -99,6 +101,12 @@ struct VirtioCcwDevice {
     uint64_t ind_bit;
 };
 
+/* The maximum virtio revision we support. */
+static inline int virtio_ccw_rev_max(VirtioCcwDevice *dev)
+{
+    return 0;
+}
+
 /* virtual css bus type */
 typedef struct VirtualCssBus {
     BusState parent_obj;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 11/20] s390x/virtio-ccw: support virtio-1 set_vq format
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Support the new CCW_CMD_SET_VQ format for virtio-1 devices.

While we're at it, refactor the code a bit and enforce big endian
fields (which had always been required, even for legacy).

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c |  114 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 80 insertions(+), 34 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index ea2c6f0..e09e0da 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -238,11 +238,20 @@ VirtualCssBus *virtual_css_bus_init(void)
 }
 
 /* Communication blocks used by several channel commands. */
-typedef struct VqInfoBlock {
+typedef struct VqInfoBlockLegacy {
     uint64_t queue;
     uint32_t align;
     uint16_t index;
     uint16_t num;
+} QEMU_PACKED VqInfoBlockLegacy;
+
+typedef struct VqInfoBlock {
+    uint64_t desc;
+    uint32_t res0;
+    uint16_t index;
+    uint16_t num;
+    uint64_t avail;
+    uint64_t used;
 } QEMU_PACKED VqInfoBlock;
 
 typedef struct VqConfigBlock {
@@ -269,17 +278,20 @@ typedef struct VirtioRevInfo {
 } QEMU_PACKED VirtioRevInfo;
 
 /* Specify where the virtqueues for the subchannel are in guest memory. */
-static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
-                              uint16_t index, uint16_t num)
+static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
+                              VqInfoBlockLegacy *linfo)
 {
     VirtIODevice *vdev = virtio_ccw_get_vdev(sch);
+    uint16_t index = info ? info->index : linfo->index;
+    uint16_t num = info ? info->num : linfo->num;
+    uint64_t desc = info ? info->desc : linfo->queue;
 
     if (index > VIRTIO_PCI_QUEUE_MAX) {
         return -EINVAL;
     }
 
     /* Current code in virtio.c relies on 4K alignment. */
-    if (addr && (align != 4096)) {
+    if (linfo && desc && (linfo->align != 4096)) {
         return -EINVAL;
     }
 
@@ -287,8 +299,12 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
         return -EINVAL;
     }
 
-    virtio_queue_set_addr(vdev, index, addr);
-    if (!addr) {
+    if (info) {
+        virtio_queue_set_rings(vdev, index, desc, info->avail, info->used);
+    } else {
+        virtio_queue_set_addr(vdev, index, desc);
+    }
+    if (!desc) {
         virtio_queue_set_vector(vdev, index, 0);
     } else {
         /* Fail if we don't have a big enough queue. */
@@ -303,10 +319,66 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
     return 0;
 }
 
-static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,
+                                    bool is_legacy)
 {
     int ret;
     VqInfoBlock info;
+    VqInfoBlockLegacy linfo;
+    size_t info_len = is_legacy ? sizeof(linfo) : sizeof(info);
+
+    if (check_len) {
+        if (ccw.count != info_len) {
+            return -EINVAL;
+        }
+    } else if (ccw.count < info_len) {
+        /* Can't execute command. */
+        return -EINVAL;
+    }
+    if (!ccw.cda) {
+        return -EFAULT;
+    }
+    if (is_legacy) {
+        linfo.queue = ldq_be_phys(&address_space_memory, ccw.cda);
+        linfo.align = ldl_be_phys(&address_space_memory,
+                                  ccw.cda + sizeof(linfo.queue));
+        linfo.index = lduw_be_phys(&address_space_memory,
+                                   ccw.cda + sizeof(linfo.queue)
+                                   + sizeof(linfo.align));
+        linfo.num = lduw_be_phys(&address_space_memory,
+                                 ccw.cda + sizeof(linfo.queue)
+                                 + sizeof(linfo.align)
+                                 + sizeof(linfo.index));
+        ret = virtio_ccw_set_vqs(sch, NULL, &linfo);
+    } else {
+        info.desc = ldq_be_phys(&address_space_memory, ccw.cda);
+        info.index = lduw_be_phys(&address_space_memory,
+                                  ccw.cda + sizeof(info.desc)
+                                  + sizeof(info.res0));
+        info.num = lduw_be_phys(&address_space_memory,
+                                ccw.cda + sizeof(info.desc)
+                              + sizeof(info.res0)
+                              + sizeof(info.index));
+        info.avail = ldq_be_phys(&address_space_memory,
+                                 ccw.cda + sizeof(info.desc)
+                                 + sizeof(info.res0)
+                                 + sizeof(info.index)
+                                 + sizeof(info.num));
+        info.used = ldq_be_phys(&address_space_memory,
+                                ccw.cda + sizeof(info.desc)
+                                + sizeof(info.res0)
+                                + sizeof(info.index)
+                                + sizeof(info.num)
+                                + sizeof(info.avail));
+        ret = virtio_ccw_set_vqs(sch, &info, NULL);
+    }
+    sch->curr_status.scsw.count = 0;
+    return ret;
+}
+
+static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+{
+    int ret;
     VirtioRevInfo revinfo;
     uint8_t status;
     VirtioFeatDesc features;
@@ -331,33 +403,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
     /* Look at the command. */
     switch (ccw.cmd_code) {
     case CCW_CMD_SET_VQ:
-        if (check_len) {
-            if (ccw.count != sizeof(info)) {
-                ret = -EINVAL;
-                break;
-            }
-        } else if (ccw.count < sizeof(info)) {
-            /* Can't execute command. */
-            ret = -EINVAL;
-            break;
-        }
-        if (!ccw.cda) {
-            ret = -EFAULT;
-        } else {
-            info.queue = ldq_phys(&address_space_memory, ccw.cda);
-            info.align = ldl_phys(&address_space_memory,
-                                  ccw.cda + sizeof(info.queue));
-            info.index = lduw_phys(&address_space_memory,
-                                   ccw.cda + sizeof(info.queue)
-                                   + sizeof(info.align));
-            info.num = lduw_phys(&address_space_memory,
-                                 ccw.cda + sizeof(info.queue)
-                                 + sizeof(info.align)
-                                 + sizeof(info.index));
-            ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index,
-                                     info.num);
-            sch->curr_status.scsw.count = 0;
-        }
+        ret = virtio_ccw_handle_set_vq(sch, ccw, check_len, dev->revision < 1);
         break;
     case CCW_CMD_VDEV_RESET:
         virtio_ccw_stop_ioeventfd(dev);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 11/20] s390x/virtio-ccw: support virtio-1 set_vq format
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Support the new CCW_CMD_SET_VQ format for virtio-1 devices.

While we're at it, refactor the code a bit and enforce big endian
fields (which had always been required, even for legacy).

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c |  114 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 80 insertions(+), 34 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index ea2c6f0..e09e0da 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -238,11 +238,20 @@ VirtualCssBus *virtual_css_bus_init(void)
 }
 
 /* Communication blocks used by several channel commands. */
-typedef struct VqInfoBlock {
+typedef struct VqInfoBlockLegacy {
     uint64_t queue;
     uint32_t align;
     uint16_t index;
     uint16_t num;
+} QEMU_PACKED VqInfoBlockLegacy;
+
+typedef struct VqInfoBlock {
+    uint64_t desc;
+    uint32_t res0;
+    uint16_t index;
+    uint16_t num;
+    uint64_t avail;
+    uint64_t used;
 } QEMU_PACKED VqInfoBlock;
 
 typedef struct VqConfigBlock {
@@ -269,17 +278,20 @@ typedef struct VirtioRevInfo {
 } QEMU_PACKED VirtioRevInfo;
 
 /* Specify where the virtqueues for the subchannel are in guest memory. */
-static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
-                              uint16_t index, uint16_t num)
+static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
+                              VqInfoBlockLegacy *linfo)
 {
     VirtIODevice *vdev = virtio_ccw_get_vdev(sch);
+    uint16_t index = info ? info->index : linfo->index;
+    uint16_t num = info ? info->num : linfo->num;
+    uint64_t desc = info ? info->desc : linfo->queue;
 
     if (index > VIRTIO_PCI_QUEUE_MAX) {
         return -EINVAL;
     }
 
     /* Current code in virtio.c relies on 4K alignment. */
-    if (addr && (align != 4096)) {
+    if (linfo && desc && (linfo->align != 4096)) {
         return -EINVAL;
     }
 
@@ -287,8 +299,12 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
         return -EINVAL;
     }
 
-    virtio_queue_set_addr(vdev, index, addr);
-    if (!addr) {
+    if (info) {
+        virtio_queue_set_rings(vdev, index, desc, info->avail, info->used);
+    } else {
+        virtio_queue_set_addr(vdev, index, desc);
+    }
+    if (!desc) {
         virtio_queue_set_vector(vdev, index, 0);
     } else {
         /* Fail if we don't have a big enough queue. */
@@ -303,10 +319,66 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
     return 0;
 }
 
-static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,
+                                    bool is_legacy)
 {
     int ret;
     VqInfoBlock info;
+    VqInfoBlockLegacy linfo;
+    size_t info_len = is_legacy ? sizeof(linfo) : sizeof(info);
+
+    if (check_len) {
+        if (ccw.count != info_len) {
+            return -EINVAL;
+        }
+    } else if (ccw.count < info_len) {
+        /* Can't execute command. */
+        return -EINVAL;
+    }
+    if (!ccw.cda) {
+        return -EFAULT;
+    }
+    if (is_legacy) {
+        linfo.queue = ldq_be_phys(&address_space_memory, ccw.cda);
+        linfo.align = ldl_be_phys(&address_space_memory,
+                                  ccw.cda + sizeof(linfo.queue));
+        linfo.index = lduw_be_phys(&address_space_memory,
+                                   ccw.cda + sizeof(linfo.queue)
+                                   + sizeof(linfo.align));
+        linfo.num = lduw_be_phys(&address_space_memory,
+                                 ccw.cda + sizeof(linfo.queue)
+                                 + sizeof(linfo.align)
+                                 + sizeof(linfo.index));
+        ret = virtio_ccw_set_vqs(sch, NULL, &linfo);
+    } else {
+        info.desc = ldq_be_phys(&address_space_memory, ccw.cda);
+        info.index = lduw_be_phys(&address_space_memory,
+                                  ccw.cda + sizeof(info.desc)
+                                  + sizeof(info.res0));
+        info.num = lduw_be_phys(&address_space_memory,
+                                ccw.cda + sizeof(info.desc)
+                              + sizeof(info.res0)
+                              + sizeof(info.index));
+        info.avail = ldq_be_phys(&address_space_memory,
+                                 ccw.cda + sizeof(info.desc)
+                                 + sizeof(info.res0)
+                                 + sizeof(info.index)
+                                 + sizeof(info.num));
+        info.used = ldq_be_phys(&address_space_memory,
+                                ccw.cda + sizeof(info.desc)
+                                + sizeof(info.res0)
+                                + sizeof(info.index)
+                                + sizeof(info.num)
+                                + sizeof(info.avail));
+        ret = virtio_ccw_set_vqs(sch, &info, NULL);
+    }
+    sch->curr_status.scsw.count = 0;
+    return ret;
+}
+
+static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
+{
+    int ret;
     VirtioRevInfo revinfo;
     uint8_t status;
     VirtioFeatDesc features;
@@ -331,33 +403,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
     /* Look at the command. */
     switch (ccw.cmd_code) {
     case CCW_CMD_SET_VQ:
-        if (check_len) {
-            if (ccw.count != sizeof(info)) {
-                ret = -EINVAL;
-                break;
-            }
-        } else if (ccw.count < sizeof(info)) {
-            /* Can't execute command. */
-            ret = -EINVAL;
-            break;
-        }
-        if (!ccw.cda) {
-            ret = -EFAULT;
-        } else {
-            info.queue = ldq_phys(&address_space_memory, ccw.cda);
-            info.align = ldl_phys(&address_space_memory,
-                                  ccw.cda + sizeof(info.queue));
-            info.index = lduw_phys(&address_space_memory,
-                                   ccw.cda + sizeof(info.queue)
-                                   + sizeof(info.align));
-            info.num = lduw_phys(&address_space_memory,
-                                 ccw.cda + sizeof(info.queue)
-                                 + sizeof(info.align)
-                                 + sizeof(info.index));
-            ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index,
-                                     info.num);
-            sch->curr_status.scsw.count = 0;
-        }
+        ret = virtio_ccw_handle_set_vq(sch, ccw, check_len, dev->revision < 1);
         break;
     case CCW_CMD_VDEV_RESET:
         virtio_ccw_stop_ioeventfd(dev);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

For virtio-1 devices, the driver must not attempt to set feature bits
after it set FEATURES_OK in the device status. Simply reject it in
that case.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/virtio/virtio.c         |   16 ++++++++++++++--
 include/hw/virtio/virtio.h |    2 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 57190ba..a3dd67b 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     vmstate_save_state(f, &vmstate_virtio, vdev);
 }
 
-int virtio_set_features(VirtIODevice *vdev, uint64_t val)
+static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
@@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
     return bad ? -1 : 0;
 }
 
+int virtio_set_features(VirtIODevice *vdev, uint64_t val)
+{
+   /*
+     * The driver must not attempt to set features after feature negotiation
+     * has finished.
+     */
+    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
+        return -EINVAL;
+    }
+    return __virtio_set_features(vdev, val);
+}
+
 int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
 {
     int i, ret;
@@ -1026,7 +1038,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     qemu_get_be32s(f, &features);
 
     /* XXX features >= 32 */
-    if (virtio_set_features(vdev, features) < 0) {
+    if (__virtio_set_features(vdev, features) < 0) {
         supported_features = k->get_features(qbus->parent);
         error_report("Features 0x%x unsupported. Allowed features: 0x%lx",
                      features, supported_features);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b63ced3..a24e403 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -32,6 +32,8 @@
 #define VIRTIO_CONFIG_S_DRIVER          2
 /* Driver has used its parts of the config, and is happy */
 #define VIRTIO_CONFIG_S_DRIVER_OK       4
+/* Driver has finished configuring features */
+#define VIRTIO_CONFIG_S_FEATURES_OK     8
 /* We've given up on this device. */
 #define VIRTIO_CONFIG_S_FAILED          0x80
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

For virtio-1 devices, the driver must not attempt to set feature bits
after it set FEATURES_OK in the device status. Simply reject it in
that case.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/virtio/virtio.c         |   16 ++++++++++++++--
 include/hw/virtio/virtio.h |    2 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 57190ba..a3dd67b 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     vmstate_save_state(f, &vmstate_virtio, vdev);
 }
 
-int virtio_set_features(VirtIODevice *vdev, uint64_t val)
+static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
@@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
     return bad ? -1 : 0;
 }
 
+int virtio_set_features(VirtIODevice *vdev, uint64_t val)
+{
+   /*
+     * The driver must not attempt to set features after feature negotiation
+     * has finished.
+     */
+    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
+        return -EINVAL;
+    }
+    return __virtio_set_features(vdev, val);
+}
+
 int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
 {
     int i, ret;
@@ -1026,7 +1038,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     qemu_get_be32s(f, &features);
 
     /* XXX features >= 32 */
-    if (virtio_set_features(vdev, features) < 0) {
+    if (__virtio_set_features(vdev, features) < 0) {
         supported_features = k->get_features(qbus->parent);
         error_report("Features 0x%x unsupported. Allowed features: 0x%lx",
                      features, supported_features);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b63ced3..a24e403 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -32,6 +32,8 @@
 #define VIRTIO_CONFIG_S_DRIVER          2
 /* Driver has used its parts of the config, and is happy */
 #define VIRTIO_CONFIG_S_DRIVER_OK       4
+/* Driver has finished configuring features */
+#define VIRTIO_CONFIG_S_FEATURES_OK     8
 /* We've given up on this device. */
 #define VIRTIO_CONFIG_S_FAILED          0x80
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 13/20] virtio: allow to fail setting status
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

virtio-1 allow setting of the FEATURES_OK status bit to fail if
the negotiated feature bits are inconsistent: let's fail
virtio_set_status() in that case and update virtio-ccw to post an
error to the guest.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c      |   20 ++++++++++++--------
 hw/virtio/virtio.c         |   24 +++++++++++++++++++++++-
 include/hw/virtio/virtio.h |    3 ++-
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index e09e0da..a55e851 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -555,15 +555,19 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
                 virtio_ccw_stop_ioeventfd(dev);
             }
-            virtio_set_status(vdev, status);
-            if (vdev->status == 0) {
-                virtio_reset(vdev);
-            }
-            if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
-                virtio_ccw_start_ioeventfd(dev);
+            if (virtio_set_status(vdev, status) == 0) {
+                if (vdev->status == 0) {
+                    virtio_reset(vdev);
+                }
+                if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
+                    virtio_ccw_start_ioeventfd(dev);
+                }
+                sch->curr_status.scsw.count = ccw.count - sizeof(status);
+                ret = 0;
+            } else {
+                /* Trigger a command reject. */
+                ret = -ENOSYS;
             }
-            sch->curr_status.scsw.count = ccw.count - sizeof(status);
-            ret = 0;
         }
         break;
     case CCW_CMD_SET_IND:
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index a3dd67b..90eedd3 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -543,15 +543,37 @@ void virtio_update_irq(VirtIODevice *vdev)
     virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
 }
 
-void virtio_set_status(VirtIODevice *vdev, uint8_t val)
+static int virtio_validate_features(VirtIODevice *vdev)
+{
+    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+
+    if (k->validate_features) {
+        return k->validate_features(vdev);
+    } else {
+        return 0;
+    }
+}
+
+int virtio_set_status(VirtIODevice *vdev, uint8_t val)
 {
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
     trace_virtio_set_status(vdev, val);
 
+    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        if (!(vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) &&
+            val & VIRTIO_CONFIG_S_FEATURES_OK) {
+            int ret = virtio_validate_features(vdev);
+
+            if (ret) {
+                return ret;
+            }
+        }
+    }
     if (k->set_status) {
         k->set_status(vdev, val);
     }
     vdev->status = val;
+    return 0;
 }
 
 bool target_words_bigendian(void);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index a24e403..068211e 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -149,6 +149,7 @@ typedef struct VirtioDeviceClass {
     uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
     uint64_t (*bad_features)(VirtIODevice *vdev);
     void (*set_features)(VirtIODevice *vdev, uint64_t val);
+    int (*validate_features)(VirtIODevice *vdev);
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
     void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
     void (*reset)(VirtIODevice *vdev);
@@ -233,7 +234,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
 void virtio_queue_notify(VirtIODevice *vdev, int n);
 uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
 void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
-void virtio_set_status(VirtIODevice *vdev, uint8_t val);
+int virtio_set_status(VirtIODevice *vdev, uint8_t val);
 void virtio_reset(void *opaque);
 void virtio_update_irq(VirtIODevice *vdev);
 int virtio_set_features(VirtIODevice *vdev, uint64_t val);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 13/20] virtio: allow to fail setting status
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

virtio-1 allow setting of the FEATURES_OK status bit to fail if
the negotiated feature bits are inconsistent: let's fail
virtio_set_status() in that case and update virtio-ccw to post an
error to the guest.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c      |   20 ++++++++++++--------
 hw/virtio/virtio.c         |   24 +++++++++++++++++++++++-
 include/hw/virtio/virtio.h |    3 ++-
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index e09e0da..a55e851 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -555,15 +555,19 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
                 virtio_ccw_stop_ioeventfd(dev);
             }
-            virtio_set_status(vdev, status);
-            if (vdev->status == 0) {
-                virtio_reset(vdev);
-            }
-            if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
-                virtio_ccw_start_ioeventfd(dev);
+            if (virtio_set_status(vdev, status) == 0) {
+                if (vdev->status == 0) {
+                    virtio_reset(vdev);
+                }
+                if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
+                    virtio_ccw_start_ioeventfd(dev);
+                }
+                sch->curr_status.scsw.count = ccw.count - sizeof(status);
+                ret = 0;
+            } else {
+                /* Trigger a command reject. */
+                ret = -ENOSYS;
             }
-            sch->curr_status.scsw.count = ccw.count - sizeof(status);
-            ret = 0;
         }
         break;
     case CCW_CMD_SET_IND:
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index a3dd67b..90eedd3 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -543,15 +543,37 @@ void virtio_update_irq(VirtIODevice *vdev)
     virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
 }
 
-void virtio_set_status(VirtIODevice *vdev, uint8_t val)
+static int virtio_validate_features(VirtIODevice *vdev)
+{
+    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+
+    if (k->validate_features) {
+        return k->validate_features(vdev);
+    } else {
+        return 0;
+    }
+}
+
+int virtio_set_status(VirtIODevice *vdev, uint8_t val)
 {
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
     trace_virtio_set_status(vdev, val);
 
+    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+        if (!(vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) &&
+            val & VIRTIO_CONFIG_S_FEATURES_OK) {
+            int ret = virtio_validate_features(vdev);
+
+            if (ret) {
+                return ret;
+            }
+        }
+    }
     if (k->set_status) {
         k->set_status(vdev, val);
     }
     vdev->status = val;
+    return 0;
 }
 
 bool target_words_bigendian(void);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index a24e403..068211e 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -149,6 +149,7 @@ typedef struct VirtioDeviceClass {
     uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
     uint64_t (*bad_features)(VirtIODevice *vdev);
     void (*set_features)(VirtIODevice *vdev, uint64_t val);
+    int (*validate_features)(VirtIODevice *vdev);
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
     void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
     void (*reset)(VirtIODevice *vdev);
@@ -233,7 +234,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
 void virtio_queue_notify(VirtIODevice *vdev, int n);
 uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
 void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
-void virtio_set_status(VirtIODevice *vdev, uint8_t val);
+int virtio_set_status(VirtIODevice *vdev, uint8_t val);
 void virtio_reset(void *opaque);
 void virtio_update_irq(VirtIODevice *vdev);
 int virtio_set_features(VirtIODevice *vdev, uint64_t val);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 14/20] s390x/virtio-ccw: enable virtio 1.0
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

virtio-ccw should now have everything in place to operate virtio 1.0
devices, so let's enable revision 1.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 778ccb9..37a9840 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -104,7 +104,7 @@ struct VirtioCcwDevice {
 /* The maximum virtio revision we support. */
 static inline int virtio_ccw_rev_max(VirtioCcwDevice *dev)
 {
-    return 0;
+    return dev->host_features & (1ULL << VIRTIO_F_VERSION_1) ? 1 : 0;
 }
 
 /* virtual css bus type */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 14/20] s390x/virtio-ccw: enable virtio 1.0
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

virtio-ccw should now have everything in place to operate virtio 1.0
devices, so let's enable revision 1.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 778ccb9..37a9840 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -104,7 +104,7 @@ struct VirtioCcwDevice {
 /* The maximum virtio revision we support. */
 static inline int virtio_ccw_rev_max(VirtioCcwDevice *dev)
 {
-    return 0;
+    return dev->host_features & (1ULL << VIRTIO_F_VERSION_1) ? 1 : 0;
 }
 
 /* virtual css bus type */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 15/20] virtio-net: no writeable mac for virtio-1
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Devices operating as virtio 1.0 may not allow writes to the mac
address in config space.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/virtio-net.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index d6d1b98..ebbea60 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -87,6 +87,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
     memcpy(&netcfg, config, n->config_size);
 
     if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
+        !virtio_has_feature(vdev, VIRTIO_F_VERSION_1) &&
         memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
         memcpy(n->mac, netcfg.mac, ETH_ALEN);
         qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 15/20] virtio-net: no writeable mac for virtio-1
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Devices operating as virtio 1.0 may not allow writes to the mac
address in config space.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/virtio-net.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index d6d1b98..ebbea60 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -87,6 +87,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
     memcpy(&netcfg, config, n->config_size);
 
     if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
+        !virtio_has_feature(vdev, VIRTIO_F_VERSION_1) &&
         memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
         memcpy(n->mac, netcfg.mac, ETH_ALEN);
         qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 16/20] virtio-net: support longer header
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

virtio-1 devices always use num_buffers in the header, even if
mergeable rx buffers have not been negotiated.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/virtio-net.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index ebbea60..7ee2bd6 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -373,15 +373,21 @@ static int peer_has_ufo(VirtIONet *n)
     return n->has_ufo;
 }
 
-static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
+static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
+                                       int version_1)
 {
     int i;
     NetClientState *nc;
 
     n->mergeable_rx_bufs = mergeable_rx_bufs;
 
-    n->guest_hdr_len = n->mergeable_rx_bufs ?
-        sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);
+    if (version_1) {
+        n->guest_hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
+    } else {
+        n->guest_hdr_len = n->mergeable_rx_bufs ?
+            sizeof(struct virtio_net_hdr_mrg_rxbuf) :
+            sizeof(struct virtio_net_hdr);
+    }
 
     for (i = 0; i < n->max_queues; i++) {
         nc = qemu_get_subqueue(n->nic, i);
@@ -525,7 +531,9 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features)
 
     virtio_net_set_mrg_rx_bufs(n,
                                __virtio_has_feature(features,
-                                                    VIRTIO_NET_F_MRG_RXBUF));
+                                                    VIRTIO_NET_F_MRG_RXBUF),
+                               __virtio_has_feature(features,
+                                                    VIRTIO_F_VERSION_1));
 
     if (n->has_vnet_hdr) {
         n->curr_guest_offloads =
@@ -1407,7 +1415,8 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
     qemu_get_buffer(f, n->mac, ETH_ALEN);
     n->vqs[0].tx_waiting = qemu_get_be32(f);
 
-    virtio_net_set_mrg_rx_bufs(n, qemu_get_be32(f));
+    virtio_net_set_mrg_rx_bufs(n, qemu_get_be32(f),
+                               virtio_has_feature(vdev, VIRTIO_F_VERSION_1));
 
     if (version_id >= 3)
         n->status = qemu_get_be16(f);
@@ -1653,7 +1662,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
 
     n->vqs[0].tx_waiting = 0;
     n->tx_burst = n->net_conf.txburst;
-    virtio_net_set_mrg_rx_bufs(n, 0);
+    virtio_net_set_mrg_rx_bufs(n, 0, 0);
     n->promisc = 1; /* for compatibility */
 
     n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 16/20] virtio-net: support longer header
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

virtio-1 devices always use num_buffers in the header, even if
mergeable rx buffers have not been negotiated.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/virtio-net.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index ebbea60..7ee2bd6 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -373,15 +373,21 @@ static int peer_has_ufo(VirtIONet *n)
     return n->has_ufo;
 }
 
-static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
+static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
+                                       int version_1)
 {
     int i;
     NetClientState *nc;
 
     n->mergeable_rx_bufs = mergeable_rx_bufs;
 
-    n->guest_hdr_len = n->mergeable_rx_bufs ?
-        sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);
+    if (version_1) {
+        n->guest_hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
+    } else {
+        n->guest_hdr_len = n->mergeable_rx_bufs ?
+            sizeof(struct virtio_net_hdr_mrg_rxbuf) :
+            sizeof(struct virtio_net_hdr);
+    }
 
     for (i = 0; i < n->max_queues; i++) {
         nc = qemu_get_subqueue(n->nic, i);
@@ -525,7 +531,9 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features)
 
     virtio_net_set_mrg_rx_bufs(n,
                                __virtio_has_feature(features,
-                                                    VIRTIO_NET_F_MRG_RXBUF));
+                                                    VIRTIO_NET_F_MRG_RXBUF),
+                               __virtio_has_feature(features,
+                                                    VIRTIO_F_VERSION_1));
 
     if (n->has_vnet_hdr) {
         n->curr_guest_offloads =
@@ -1407,7 +1415,8 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
     qemu_get_buffer(f, n->mac, ETH_ALEN);
     n->vqs[0].tx_waiting = qemu_get_be32(f);
 
-    virtio_net_set_mrg_rx_bufs(n, qemu_get_be32(f));
+    virtio_net_set_mrg_rx_bufs(n, qemu_get_be32(f),
+                               virtio_has_feature(vdev, VIRTIO_F_VERSION_1));
 
     if (version_id >= 3)
         n->status = qemu_get_be16(f);
@@ -1653,7 +1662,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
 
     n->vqs[0].tx_waiting = 0;
     n->tx_burst = n->net_conf.txburst;
-    virtio_net_set_mrg_rx_bufs(n, 0);
+    virtio_net_set_mrg_rx_bufs(n, 0, 0);
     n->promisc = 1; /* for compatibility */
 
     n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 17/20] virtio-net: enable virtio 1.0
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

virtio-net (non-vhost) now should have everything in place to support
virtio 1.0: let's enable the feature bit for it.

Note that VIRTIO_F_VERSION_1 is technically a transport feature; once
every device is ready for virtio 1.0, we can move setting this
feature bit out of the individual devices.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/virtio-net.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 7ee2bd6..b5dd356 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -473,6 +473,7 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
     }
 
     if (!get_vhost_net(nc->peer)) {
+        virtio_add_feature(&features, VIRTIO_F_VERSION_1);
         return features;
     }
     return vhost_net_get_features(get_vhost_net(nc->peer), features);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 17/20] virtio-net: enable virtio 1.0
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

virtio-net (non-vhost) now should have everything in place to support
virtio 1.0: let's enable the feature bit for it.

Note that VIRTIO_F_VERSION_1 is technically a transport feature; once
every device is ready for virtio 1.0, we can move setting this
feature bit out of the individual devices.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/virtio-net.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 7ee2bd6..b5dd356 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -473,6 +473,7 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
     }
 
     if (!get_vhost_net(nc->peer)) {
+        virtio_add_feature(&features, VIRTIO_F_VERSION_1);
         return features;
     }
     return vhost_net_get_features(get_vhost_net(nc->peer), features);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Devices may support different sets of feature bits depending on which
revision they're operating at. Let's give the transport a way to
re-query the device about its features when the revision has been
changed.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c          |   12 ++++++++++--
 hw/virtio/virtio-bus.c         |   14 ++++++++++++--
 include/hw/virtio/virtio-bus.h |    3 +++
 include/hw/virtio/virtio.h     |    3 +++
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index a55e851..8b6b2ab 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -699,6 +699,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
         }
         ret = 0;
         dev->revision = revinfo.revision;
+        /* Re-evaluate which features the device wants to offer. */
+        dev->host_features =
+            virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features,
+                                             dev->revision >= 1 ? 1 : 0);
         break;
     default:
         ret = -ENOSYS;
@@ -712,6 +716,9 @@ static void virtio_sch_disable_cb(SubchDev *sch)
     VirtioCcwDevice *dev = sch->driver_data;
 
     dev->revision = -1;
+    /* Reset the device's features to legacy. */
+    dev->host_features =
+        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
 }
 
 static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
@@ -853,8 +860,9 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
     virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
 
-    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
-                                                      dev->host_features);
+    /* All devices start in legacy mode. */
+    dev->host_features =
+        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
 
     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                           parent->hotplugged, 1);
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index 32e3fab..a30826c 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -97,18 +97,28 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
 }
 
 /* Get the features of the plugged device. */
-uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
-                                      uint64_t requested_features)
+uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
+                                          uint64_t requested_features,
+                                          unsigned int revision)
 {
     VirtIODevice *vdev = virtio_bus_get_device(bus);
     VirtioDeviceClass *k;
 
     assert(vdev != NULL);
     k = VIRTIO_DEVICE_GET_CLASS(vdev);
+    if (revision > 0 && k->get_features_rev) {
+        return k->get_features_rev(vdev, requested_features, revision);
+    }
     assert(k->get_features != NULL);
     return k->get_features(vdev, requested_features);
 }
 
+uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
+                                      uint64_t requested_features)
+{
+    return virtio_bus_get_vdev_features_rev(bus, requested_features, 0);
+}
+
 /* Get bad features of the plugged device. */
 uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
 {
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 0a4dde1..f0916ef 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -84,6 +84,9 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
 /* Get the features of the plugged device. */
 uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
                                       uint64_t requested_features);
+uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
+                                          uint64_t requested_features,
+                                          unsigned int revision);
 /* Get bad features of the plugged device. */
 uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
 /* Get config of the plugged device. */
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 068211e..1338540 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -147,6 +147,9 @@ typedef struct VirtioDeviceClass {
     DeviceRealize realize;
     DeviceUnrealize unrealize;
     uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
+    uint64_t (*get_features_rev)(VirtIODevice *vdev,
+                                 uint64_t requested_features,
+                                 unsigned int revision);
     uint64_t (*bad_features)(VirtIODevice *vdev);
     void (*set_features)(VirtIODevice *vdev, uint64_t val);
     int (*validate_features)(VirtIODevice *vdev);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 18/20] virtio: support revision-specific features
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Devices may support different sets of feature bits depending on which
revision they're operating at. Let's give the transport a way to
re-query the device about its features when the revision has been
changed.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/virtio-ccw.c          |   12 ++++++++++--
 hw/virtio/virtio-bus.c         |   14 ++++++++++++--
 include/hw/virtio/virtio-bus.h |    3 +++
 include/hw/virtio/virtio.h     |    3 +++
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index a55e851..8b6b2ab 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -699,6 +699,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
         }
         ret = 0;
         dev->revision = revinfo.revision;
+        /* Re-evaluate which features the device wants to offer. */
+        dev->host_features =
+            virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features,
+                                             dev->revision >= 1 ? 1 : 0);
         break;
     default:
         ret = -ENOSYS;
@@ -712,6 +716,9 @@ static void virtio_sch_disable_cb(SubchDev *sch)
     VirtioCcwDevice *dev = sch->driver_data;
 
     dev->revision = -1;
+    /* Reset the device's features to legacy. */
+    dev->host_features =
+        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
 }
 
 static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
@@ -853,8 +860,9 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
     virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
     virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
 
-    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
-                                                      dev->host_features);
+    /* All devices start in legacy mode. */
+    dev->host_features =
+        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
 
     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                           parent->hotplugged, 1);
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index 32e3fab..a30826c 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -97,18 +97,28 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
 }
 
 /* Get the features of the plugged device. */
-uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
-                                      uint64_t requested_features)
+uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
+                                          uint64_t requested_features,
+                                          unsigned int revision)
 {
     VirtIODevice *vdev = virtio_bus_get_device(bus);
     VirtioDeviceClass *k;
 
     assert(vdev != NULL);
     k = VIRTIO_DEVICE_GET_CLASS(vdev);
+    if (revision > 0 && k->get_features_rev) {
+        return k->get_features_rev(vdev, requested_features, revision);
+    }
     assert(k->get_features != NULL);
     return k->get_features(vdev, requested_features);
 }
 
+uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
+                                      uint64_t requested_features)
+{
+    return virtio_bus_get_vdev_features_rev(bus, requested_features, 0);
+}
+
 /* Get bad features of the plugged device. */
 uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
 {
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 0a4dde1..f0916ef 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -84,6 +84,9 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
 /* Get the features of the plugged device. */
 uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
                                       uint64_t requested_features);
+uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
+                                          uint64_t requested_features,
+                                          unsigned int revision);
 /* Get bad features of the plugged device. */
 uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
 /* Get config of the plugged device. */
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 068211e..1338540 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -147,6 +147,9 @@ typedef struct VirtioDeviceClass {
     DeviceRealize realize;
     DeviceUnrealize unrealize;
     uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
+    uint64_t (*get_features_rev)(VirtIODevice *vdev,
+                                 uint64_t requested_features,
+                                 unsigned int revision);
     uint64_t (*bad_features)(VirtIODevice *vdev);
     void (*set_features)(VirtIODevice *vdev, uint64_t val);
     int (*validate_features)(VirtIODevice *vdev);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Wire up virtio-blk to provide different feature bit sets depending
on whether legacy or v1.0 has been requested.

Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/block/virtio-blk.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 9cfae66..fdc236a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -587,6 +587,24 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
     return features;
 }
 
+static uint64_t virtio_blk_get_features_rev(VirtIODevice *vdev,
+                                            uint64_t features,
+                                            unsigned int revision)
+{
+    if (revision == 0) {
+        /* legacy */
+        virtio_clear_feature(&features, VIRTIO_F_VERSION_1);
+        return virtio_blk_get_features(vdev, features);
+    }
+    /* virtio 1.0 or later */
+    virtio_clear_feature(&features, VIRTIO_BLK_F_SCSI);
+    virtio_clear_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
+    virtio_clear_feature(&features, VIRTIO_BLK_F_WCE);
+    /* we're still missing ANY_LAYOUT */
+    /* virtio_add_feature(&features, VIRTIO_F_VERSION_1); */
+    return features;
+}
+
 static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
@@ -821,6 +839,7 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
     vdc->get_config = virtio_blk_update_config;
     vdc->set_config = virtio_blk_set_config;
     vdc->get_features = virtio_blk_get_features;
+    vdc->get_features_rev = virtio_blk_get_features_rev;
     vdc->set_status = virtio_blk_set_status;
     vdc->reset = virtio_blk_reset;
     vdc->save = virtio_blk_save_device;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Wire up virtio-blk to provide different feature bit sets depending
on whether legacy or v1.0 has been requested.

Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/block/virtio-blk.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 9cfae66..fdc236a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -587,6 +587,24 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
     return features;
 }
 
+static uint64_t virtio_blk_get_features_rev(VirtIODevice *vdev,
+                                            uint64_t features,
+                                            unsigned int revision)
+{
+    if (revision == 0) {
+        /* legacy */
+        virtio_clear_feature(&features, VIRTIO_F_VERSION_1);
+        return virtio_blk_get_features(vdev, features);
+    }
+    /* virtio 1.0 or later */
+    virtio_clear_feature(&features, VIRTIO_BLK_F_SCSI);
+    virtio_clear_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
+    virtio_clear_feature(&features, VIRTIO_BLK_F_WCE);
+    /* we're still missing ANY_LAYOUT */
+    /* virtio_add_feature(&features, VIRTIO_F_VERSION_1); */
+    return features;
+}
+
 static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
@@ -821,6 +839,7 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
     vdc->get_config = virtio_blk_update_config;
     vdc->set_config = virtio_blk_set_config;
     vdc->get_features = virtio_blk_get_features;
+    vdc->get_features_rev = virtio_blk_get_features_rev;
     vdc->set_status = virtio_blk_set_status;
     vdc->reset = virtio_blk_reset;
     vdc->save = virtio_blk_save_device;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [Qemu-devel] [PATCH RFC v6 20/20] vhost: 64 bit features
  2014-12-11 13:25 ` Cornelia Huck
@ 2014-12-11 13:25   ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: Cornelia Huck, rusty, thuth, mst

Make sure that all vhost interfaces use 64 bit features, as the virtio
core does, and make sure to use ULL everywhere possible to be on the
safe side.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/vhost_net.c        |   12 ++++++------
 hw/virtio/vhost.c         |   14 +++++++-------
 include/hw/virtio/vhost.h |    6 +++---
 include/net/vhost_net.h   |    4 ++--
 4 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 4e3a061..a6d4ef2 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -107,13 +107,13 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
     return feature_bits;
 }
 
-unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
+uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
 {
     return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net),
             features);
 }
 
-void vhost_net_ack_features(struct vhost_net *net, unsigned features)
+void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
 {
     net->dev.acked_features = net->dev.backend_features;
     vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features);
@@ -147,7 +147,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
             goto fail;
         }
         net->dev.backend_features = qemu_has_vnet_hdr(options->net_backend)
-            ? 0 : (1 << VHOST_NET_F_VIRTIO_NET_HDR);
+            ? 0 : (1ULL << VHOST_NET_F_VIRTIO_NET_HDR);
         net->backend = r;
     } else {
         net->dev.backend_features = 0;
@@ -166,7 +166,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     if (backend_kernel) {
         if (!qemu_has_vnet_hdr_len(options->net_backend,
                                sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
-            net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
+            net->dev.features &= ~(1ULL << VIRTIO_NET_F_MRG_RXBUF);
         }
         if (~net->dev.features & net->dev.backend_features) {
             fprintf(stderr, "vhost lacks feature mask %" PRIu64
@@ -423,11 +423,11 @@ void vhost_net_cleanup(struct vhost_net *net)
 {
 }
 
-unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
+uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
 {
     return features;
 }
-void vhost_net_ack_features(struct vhost_net *net, unsigned features)
+void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
 {
 }
 
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 5a12861..9e6e9cc 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -551,7 +551,7 @@ static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
     uint64_t features = dev->acked_features;
     int r;
     if (enable_log) {
-        features |= 0x1 << VHOST_F_LOG_ALL;
+        features |= 0x1ULL << VHOST_F_LOG_ALL;
     }
     r = dev->vhost_ops->vhost_call(dev, VHOST_SET_FEATURES, &features);
     return r < 0 ? -errno : 0;
@@ -860,7 +860,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
         .priority = 10
     };
     hdev->migration_blocker = NULL;
-    if (!(hdev->features & (0x1 << VHOST_F_LOG_ALL))) {
+    if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
         error_setg(&hdev->migration_blocker,
                    "Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
         migrate_add_blocker(hdev->migration_blocker);
@@ -1003,12 +1003,12 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
     assert(r >= 0);
 }
 
-unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features)
+uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
+                            uint64_t features)
 {
     const int *bit = feature_bits;
     while (*bit != VHOST_INVALID_FEATURE_BIT) {
-        unsigned bit_mask = (1 << *bit);
+        uint64_t bit_mask = (1ULL << *bit);
         if (!(hdev->features & bit_mask)) {
             features &= ~bit_mask;
         }
@@ -1018,11 +1018,11 @@ unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
 }
 
 void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features)
+                        uint64_t features)
 {
     const int *bit = feature_bits;
     while (*bit != VHOST_INVALID_FEATURE_BIT) {
-        unsigned bit_mask = (1 << *bit);
+        uint64_t bit_mask = (1ULL << *bit);
         if (features & bit_mask) {
             hdev->acked_features |= bit_mask;
         }
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index d5593d1..71ef18f 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -72,8 +72,8 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n);
  */
 void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
                           bool mask);
-unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features);
+uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
+                            uint64_t features);
 void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features);
+                        uint64_t features);
 #endif
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index b1c18a3..9eb493e 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -22,8 +22,8 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs, int total_queues);
 
 void vhost_net_cleanup(VHostNetState *net);
 
-unsigned vhost_net_get_features(VHostNetState *net, unsigned features);
-void vhost_net_ack_features(VHostNetState *net, unsigned features);
+uint64_t vhost_net_get_features(VHostNetState *net, uint64_t features);
+void vhost_net_ack_features(VHostNetState *net, uint64_t features);
 
 bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* [PATCH RFC v6 20/20] vhost: 64 bit features
@ 2014-12-11 13:25   ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-11 13:25 UTC (permalink / raw)
  To: virtualization, qemu-devel; +Cc: thuth, mst

Make sure that all vhost interfaces use 64 bit features, as the virtio
core does, and make sure to use ULL everywhere possible to be on the
safe side.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/net/vhost_net.c        |   12 ++++++------
 hw/virtio/vhost.c         |   14 +++++++-------
 include/hw/virtio/vhost.h |    6 +++---
 include/net/vhost_net.h   |    4 ++--
 4 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 4e3a061..a6d4ef2 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -107,13 +107,13 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
     return feature_bits;
 }
 
-unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
+uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
 {
     return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net),
             features);
 }
 
-void vhost_net_ack_features(struct vhost_net *net, unsigned features)
+void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
 {
     net->dev.acked_features = net->dev.backend_features;
     vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features);
@@ -147,7 +147,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
             goto fail;
         }
         net->dev.backend_features = qemu_has_vnet_hdr(options->net_backend)
-            ? 0 : (1 << VHOST_NET_F_VIRTIO_NET_HDR);
+            ? 0 : (1ULL << VHOST_NET_F_VIRTIO_NET_HDR);
         net->backend = r;
     } else {
         net->dev.backend_features = 0;
@@ -166,7 +166,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     if (backend_kernel) {
         if (!qemu_has_vnet_hdr_len(options->net_backend,
                                sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
-            net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
+            net->dev.features &= ~(1ULL << VIRTIO_NET_F_MRG_RXBUF);
         }
         if (~net->dev.features & net->dev.backend_features) {
             fprintf(stderr, "vhost lacks feature mask %" PRIu64
@@ -423,11 +423,11 @@ void vhost_net_cleanup(struct vhost_net *net)
 {
 }
 
-unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
+uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
 {
     return features;
 }
-void vhost_net_ack_features(struct vhost_net *net, unsigned features)
+void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
 {
 }
 
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 5a12861..9e6e9cc 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -551,7 +551,7 @@ static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
     uint64_t features = dev->acked_features;
     int r;
     if (enable_log) {
-        features |= 0x1 << VHOST_F_LOG_ALL;
+        features |= 0x1ULL << VHOST_F_LOG_ALL;
     }
     r = dev->vhost_ops->vhost_call(dev, VHOST_SET_FEATURES, &features);
     return r < 0 ? -errno : 0;
@@ -860,7 +860,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
         .priority = 10
     };
     hdev->migration_blocker = NULL;
-    if (!(hdev->features & (0x1 << VHOST_F_LOG_ALL))) {
+    if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
         error_setg(&hdev->migration_blocker,
                    "Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
         migrate_add_blocker(hdev->migration_blocker);
@@ -1003,12 +1003,12 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
     assert(r >= 0);
 }
 
-unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features)
+uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
+                            uint64_t features)
 {
     const int *bit = feature_bits;
     while (*bit != VHOST_INVALID_FEATURE_BIT) {
-        unsigned bit_mask = (1 << *bit);
+        uint64_t bit_mask = (1ULL << *bit);
         if (!(hdev->features & bit_mask)) {
             features &= ~bit_mask;
         }
@@ -1018,11 +1018,11 @@ unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
 }
 
 void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features)
+                        uint64_t features)
 {
     const int *bit = feature_bits;
     while (*bit != VHOST_INVALID_FEATURE_BIT) {
-        unsigned bit_mask = (1 << *bit);
+        uint64_t bit_mask = (1ULL << *bit);
         if (features & bit_mask) {
             hdev->acked_features |= bit_mask;
         }
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index d5593d1..71ef18f 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -72,8 +72,8 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n);
  */
 void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
                           bool mask);
-unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features);
+uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
+                            uint64_t features);
 void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
-        unsigned features);
+                        uint64_t features);
 #endif
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index b1c18a3..9eb493e 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -22,8 +22,8 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs, int total_queues);
 
 void vhost_net_cleanup(VHostNetState *net);
 
-unsigned vhost_net_get_features(VHostNetState *net, unsigned features);
-void vhost_net_ack_features(VHostNetState *net, unsigned features);
+uint64_t vhost_net_get_features(VHostNetState *net, uint64_t features);
+void vhost_net_ack_features(VHostNetState *net, uint64_t features);
 
 bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 03/20] virtio: feature bit manipulation helpers
  2014-12-11 13:25   ` Cornelia Huck
  (?)
  (?)
@ 2014-12-11 14:29   ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-11 14:29 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: rusty, mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:05 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> Add virtio_{add,clear}_feature helper functions for manipulating a
> feature bits variable. This has some benefits over open coding:
> - add check that the bit is in a sane range
> - make it obvious at a glance what is going on
> - have a central point to change when we want to extend feature bits
> 
> Convert existing code manipulating features to use the new helpers.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/9pfs/virtio-9p-device.c  |    2 +-
>  hw/block/virtio-blk.c       |   16 ++++++++--------
>  hw/char/virtio-serial-bus.c |    2 +-
>  hw/net/virtio-net.c         |   34 +++++++++++++++++-----------------
>  hw/s390x/virtio-ccw.c       |    4 ++--
>  hw/virtio/virtio-mmio.c     |    2 +-
>  hw/virtio/virtio-pci.c      |    4 ++--
>  include/hw/virtio/virtio.h  |   12 ++++++++++++
>  8 files changed, 44 insertions(+), 32 deletions(-)

Patch looks fine to me.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 03/20] virtio: feature bit manipulation helpers
  2014-12-11 13:25   ` Cornelia Huck
  (?)
@ 2014-12-11 14:29   ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-11 14:29 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:05 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> Add virtio_{add,clear}_feature helper functions for manipulating a
> feature bits variable. This has some benefits over open coding:
> - add check that the bit is in a sane range
> - make it obvious at a glance what is going on
> - have a central point to change when we want to extend feature bits
> 
> Convert existing code manipulating features to use the new helpers.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/9pfs/virtio-9p-device.c  |    2 +-
>  hw/block/virtio-blk.c       |   16 ++++++++--------
>  hw/char/virtio-serial-bus.c |    2 +-
>  hw/net/virtio-net.c         |   34 +++++++++++++++++-----------------
>  hw/s390x/virtio-ccw.c       |    4 ++--
>  hw/virtio/virtio-mmio.c     |    2 +-
>  hw/virtio/virtio-pci.c      |    4 ++--
>  include/hw/virtio/virtio.h  |   12 ++++++++++++
>  8 files changed, 44 insertions(+), 32 deletions(-)

Patch looks fine to me.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 13:25   ` Cornelia Huck
  (?)
@ 2014-12-11 14:46   ` Thomas Huth
  2014-12-11 17:05       ` Michael S. Tsirkin
  2014-12-12 10:07       ` Cornelia Huck
  -1 siblings, 2 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-11 14:46 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: rusty, mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:06 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> Add a helper function for checking whether a bit is set in the guest
> features for a vdev as well as one that works on a feature bit set.
> 
> Convert code that open-coded this: It cleans up the code and makes it
> easier to extend the guest feature bits.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
...
> diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> index ef48550..56c92fb 100644
> --- a/hw/scsi/virtio-scsi.c
> +++ b/hw/scsi/virtio-scsi.c
> @@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
>       *
>       * TODO: always disable this workaround for virtio 1.0 devices.
>       */
> -    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
> +    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {

Wait ... this does not only look like a clean-up, but also like a
bug-fix to me, since it should have been "(1 << VIRTIO_F_ANY_LAYOUT)"
instead of "VIRTIO_F_ANY_LAYOUT" in the original code instead?

So in case this patch queue takes a little bit longer 'til it gets
upstream, do we might want to submit a separate patch for fixing this
issue first?

>          req_size = req->elem.out_sg[0].iov_len;
>          resp_size = req->elem.in_sg[0].iov_len;
>      }
> @@ -748,7 +748,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
>      VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
>      VirtIODevice *vdev = VIRTIO_DEVICE(s);
> 
> -    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
> +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
>          dev->type != TYPE_ROM) {
>          virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
>                                 sense.asc | (sense.ascq << 8));
> @@ -769,7 +769,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
>          blk_op_block_all(sd->conf.blk, s->blocker);
>      }
> 
> -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
>          virtio_scsi_push_event(s, sd,
>                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
>                                 VIRTIO_SCSI_EVT_RESET_RESCAN);
> @@ -783,7 +783,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
>      VirtIOSCSI *s = VIRTIO_SCSI(vdev);
>      SCSIDevice *sd = SCSI_DEVICE(dev);
> 
> -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
>          virtio_scsi_push_event(s, sd,
>                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
>                                 VIRTIO_SCSI_EVT_RESET_REMOVED);
...
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 2fede2e..f6c0379 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -278,6 +278,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
>      *features &= ~(1 << fbit);
>  }
> 
> +static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
> +{
> +    assert(fbit < 32);
> +    return !!(features & (1 << fbit));
> +}
> +
> +static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> +{
> +    return __virtio_has_feature(vdev->guest_features, fbit);
> +}
> +

I've got to say that I'm a little bit unhappy with the naming of the
functions - and in contrast to the Linux kernel code, I think it is
also quite uncommon in the QEMU sources to use function names with
double underscores at the beginning.

Could you maybe rename the second function to "virtio_vdev_has_feature"
instead? And then remove the double underscores from the first function?

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 13:25   ` Cornelia Huck
  (?)
  (?)
@ 2014-12-11 14:46   ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-11 14:46 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:06 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> Add a helper function for checking whether a bit is set in the guest
> features for a vdev as well as one that works on a feature bit set.
> 
> Convert code that open-coded this: It cleans up the code and makes it
> easier to extend the guest feature bits.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
...
> diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> index ef48550..56c92fb 100644
> --- a/hw/scsi/virtio-scsi.c
> +++ b/hw/scsi/virtio-scsi.c
> @@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
>       *
>       * TODO: always disable this workaround for virtio 1.0 devices.
>       */
> -    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
> +    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {

Wait ... this does not only look like a clean-up, but also like a
bug-fix to me, since it should have been "(1 << VIRTIO_F_ANY_LAYOUT)"
instead of "VIRTIO_F_ANY_LAYOUT" in the original code instead?

So in case this patch queue takes a little bit longer 'til it gets
upstream, do we might want to submit a separate patch for fixing this
issue first?

>          req_size = req->elem.out_sg[0].iov_len;
>          resp_size = req->elem.in_sg[0].iov_len;
>      }
> @@ -748,7 +748,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
>      VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
>      VirtIODevice *vdev = VIRTIO_DEVICE(s);
> 
> -    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
> +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
>          dev->type != TYPE_ROM) {
>          virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
>                                 sense.asc | (sense.ascq << 8));
> @@ -769,7 +769,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
>          blk_op_block_all(sd->conf.blk, s->blocker);
>      }
> 
> -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
>          virtio_scsi_push_event(s, sd,
>                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
>                                 VIRTIO_SCSI_EVT_RESET_RESCAN);
> @@ -783,7 +783,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
>      VirtIOSCSI *s = VIRTIO_SCSI(vdev);
>      SCSIDevice *sd = SCSI_DEVICE(dev);
> 
> -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
>          virtio_scsi_push_event(s, sd,
>                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
>                                 VIRTIO_SCSI_EVT_RESET_REMOVED);
...
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 2fede2e..f6c0379 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -278,6 +278,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
>      *features &= ~(1 << fbit);
>  }
> 
> +static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
> +{
> +    assert(fbit < 32);
> +    return !!(features & (1 << fbit));
> +}
> +
> +static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> +{
> +    return __virtio_has_feature(vdev->guest_features, fbit);
> +}
> +

I've got to say that I'm a little bit unhappy with the naming of the
functions - and in contrast to the Linux kernel code, I think it is
also quite uncommon in the QEMU sources to use function names with
double underscores at the beginning.

Could you maybe rename the second function to "virtio_vdev_has_feature"
instead? And then remove the double underscores from the first function?

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 14:46   ` [Qemu-devel] " Thomas Huth
@ 2014-12-11 17:05       ` Michael S. Tsirkin
  2014-12-12 10:07       ` Cornelia Huck
  1 sibling, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-11 17:05 UTC (permalink / raw)
  To: Thomas Huth; +Cc: Cornelia Huck, rusty, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 03:46:23PM +0100, Thomas Huth wrote:
> On Thu, 11 Dec 2014 14:25:06 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > Add a helper function for checking whether a bit is set in the guest
> > features for a vdev as well as one that works on a feature bit set.
> > 
> > Convert code that open-coded this: It cleans up the code and makes it
> > easier to extend the guest feature bits.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ...
> > diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> > index ef48550..56c92fb 100644
> > --- a/hw/scsi/virtio-scsi.c
> > +++ b/hw/scsi/virtio-scsi.c
> > @@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
> >       *
> >       * TODO: always disable this workaround for virtio 1.0 devices.
> >       */
> > -    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
> > +    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
> 
> Wait ... this does not only look like a clean-up, but also like a
> bug-fix to me, since it should have been "(1 << VIRTIO_F_ANY_LAYOUT)"
> instead of "VIRTIO_F_ANY_LAYOUT" in the original code instead?
> 
> So in case this patch queue takes a little bit longer 'til it gets
> upstream, do we might want to submit a separate patch for fixing this
> issue first?

Yes, please do.


> >          req_size = req->elem.out_sg[0].iov_len;
> >          resp_size = req->elem.in_sg[0].iov_len;
> >      }
> > @@ -748,7 +748,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
> >      VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
> >      VirtIODevice *vdev = VIRTIO_DEVICE(s);
> > 
> > -    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
> > +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
> >          dev->type != TYPE_ROM) {
> >          virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
> >                                 sense.asc | (sense.ascq << 8));
> > @@ -769,7 +769,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
> >          blk_op_block_all(sd->conf.blk, s->blocker);
> >      }
> > 
> > -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> > +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
> >          virtio_scsi_push_event(s, sd,
> >                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
> >                                 VIRTIO_SCSI_EVT_RESET_RESCAN);
> > @@ -783,7 +783,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
> >      VirtIOSCSI *s = VIRTIO_SCSI(vdev);
> >      SCSIDevice *sd = SCSI_DEVICE(dev);
> > 
> > -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> > +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
> >          virtio_scsi_push_event(s, sd,
> >                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
> >                                 VIRTIO_SCSI_EVT_RESET_REMOVED);
> ...
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index 2fede2e..f6c0379 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -278,6 +278,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
> >      *features &= ~(1 << fbit);
> >  }
> > 
> > +static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
> > +{
> > +    assert(fbit < 32);
> > +    return !!(features & (1 << fbit));
> > +}
> > +
> > +static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> > +{
> > +    return __virtio_has_feature(vdev->guest_features, fbit);
> > +}
> > +
> 
> I've got to say that I'm a little bit unhappy with the naming of the
> functions - and in contrast to the Linux kernel code, I think it is
> also quite uncommon in the QEMU sources to use function names with
> double underscores at the beginning.
> 
> Could you maybe rename the second function to "virtio_vdev_has_feature"
> instead? And then remove the double underscores from the first function?
> 
>  Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 04/20] virtio: add feature checking helpers
@ 2014-12-11 17:05       ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-11 17:05 UTC (permalink / raw)
  To: Thomas Huth; +Cc: qemu-devel, virtualization

On Thu, Dec 11, 2014 at 03:46:23PM +0100, Thomas Huth wrote:
> On Thu, 11 Dec 2014 14:25:06 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > Add a helper function for checking whether a bit is set in the guest
> > features for a vdev as well as one that works on a feature bit set.
> > 
> > Convert code that open-coded this: It cleans up the code and makes it
> > easier to extend the guest feature bits.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ...
> > diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> > index ef48550..56c92fb 100644
> > --- a/hw/scsi/virtio-scsi.c
> > +++ b/hw/scsi/virtio-scsi.c
> > @@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
> >       *
> >       * TODO: always disable this workaround for virtio 1.0 devices.
> >       */
> > -    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
> > +    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
> 
> Wait ... this does not only look like a clean-up, but also like a
> bug-fix to me, since it should have been "(1 << VIRTIO_F_ANY_LAYOUT)"
> instead of "VIRTIO_F_ANY_LAYOUT" in the original code instead?
> 
> So in case this patch queue takes a little bit longer 'til it gets
> upstream, do we might want to submit a separate patch for fixing this
> issue first?

Yes, please do.


> >          req_size = req->elem.out_sg[0].iov_len;
> >          resp_size = req->elem.in_sg[0].iov_len;
> >      }
> > @@ -748,7 +748,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
> >      VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
> >      VirtIODevice *vdev = VIRTIO_DEVICE(s);
> > 
> > -    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
> > +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
> >          dev->type != TYPE_ROM) {
> >          virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
> >                                 sense.asc | (sense.ascq << 8));
> > @@ -769,7 +769,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
> >          blk_op_block_all(sd->conf.blk, s->blocker);
> >      }
> > 
> > -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> > +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
> >          virtio_scsi_push_event(s, sd,
> >                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
> >                                 VIRTIO_SCSI_EVT_RESET_RESCAN);
> > @@ -783,7 +783,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
> >      VirtIOSCSI *s = VIRTIO_SCSI(vdev);
> >      SCSIDevice *sd = SCSI_DEVICE(dev);
> > 
> > -    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
> > +    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
> >          virtio_scsi_push_event(s, sd,
> >                                 VIRTIO_SCSI_T_TRANSPORT_RESET,
> >                                 VIRTIO_SCSI_EVT_RESET_REMOVED);
> ...
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index 2fede2e..f6c0379 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -278,6 +278,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
> >      *features &= ~(1 << fbit);
> >  }
> > 
> > +static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
> > +{
> > +    assert(fbit < 32);
> > +    return !!(features & (1 << fbit));
> > +}
> > +
> > +static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> > +{
> > +    return __virtio_has_feature(vdev->guest_features, fbit);
> > +}
> > +
> 
> I've got to say that I'm a little bit unhappy with the naming of the
> functions - and in contrast to the Linux kernel code, I think it is
> also quite uncommon in the QEMU sources to use function names with
> double underscores at the beginning.
> 
> Could you maybe rename the second function to "virtio_vdev_has_feature"
> instead? And then remove the double underscores from the first function?
> 
>  Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 17:05       ` Michael S. Tsirkin
@ 2014-12-12  8:37         ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12  8:37 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel, rusty, Thomas Huth, virtualization

On Thu, 11 Dec 2014 19:05:26 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 03:46:23PM +0100, Thomas Huth wrote:
> > On Thu, 11 Dec 2014 14:25:06 +0100
> > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> > 
> > > Add a helper function for checking whether a bit is set in the guest
> > > features for a vdev as well as one that works on a feature bit set.
> > > 
> > > Convert code that open-coded this: It cleans up the code and makes it
> > > easier to extend the guest feature bits.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ...
> > > diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> > > index ef48550..56c92fb 100644
> > > --- a/hw/scsi/virtio-scsi.c
> > > +++ b/hw/scsi/virtio-scsi.c
> > > @@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
> > >       *
> > >       * TODO: always disable this workaround for virtio 1.0 devices.
> > >       */
> > > -    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
> > > +    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
> > 
> > Wait ... this does not only look like a clean-up, but also like a
> > bug-fix to me, since it should have been "(1 << VIRTIO_F_ANY_LAYOUT)"
> > instead of "VIRTIO_F_ANY_LAYOUT" in the original code instead?

I've clearly been looking at this stuff for too long, as I didn't even
notice this bug :)

> > 
> > So in case this patch queue takes a little bit longer 'til it gets
> > upstream, do we might want to submit a separate patch for fixing this
> > issue first?
> 
> Yes, please do.

OK, will send.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 04/20] virtio: add feature checking helpers
@ 2014-12-12  8:37         ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12  8:37 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel, Thomas Huth, virtualization

On Thu, 11 Dec 2014 19:05:26 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 03:46:23PM +0100, Thomas Huth wrote:
> > On Thu, 11 Dec 2014 14:25:06 +0100
> > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> > 
> > > Add a helper function for checking whether a bit is set in the guest
> > > features for a vdev as well as one that works on a feature bit set.
> > > 
> > > Convert code that open-coded this: It cleans up the code and makes it
> > > easier to extend the guest feature bits.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ...
> > > diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> > > index ef48550..56c92fb 100644
> > > --- a/hw/scsi/virtio-scsi.c
> > > +++ b/hw/scsi/virtio-scsi.c
> > > @@ -144,7 +144,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
> > >       *
> > >       * TODO: always disable this workaround for virtio 1.0 devices.
> > >       */
> > > -    if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
> > > +    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
> > 
> > Wait ... this does not only look like a clean-up, but also like a
> > bug-fix to me, since it should have been "(1 << VIRTIO_F_ANY_LAYOUT)"
> > instead of "VIRTIO_F_ANY_LAYOUT" in the original code instead?

I've clearly been looking at this stuff for too long, as I didn't even
notice this bug :)

> > 
> > So in case this patch queue takes a little bit longer 'til it gets
> > upstream, do we might want to submit a separate patch for fixing this
> > issue first?
> 
> Yes, please do.

OK, will send.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2014-12-11 13:25   ` Cornelia Huck
@ 2014-12-12 10:06     ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-12 10:06 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: rusty, mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:07 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> With virtio-1, we support more than 32 feature bits. Let's extend both
> host and guest features to 64, which should suffice for a while.
> 
> vhost and migration have been ignored for now.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/9pfs/virtio-9p-device.c      |    2 +-
>  hw/block/virtio-blk.c           |    2 +-
>  hw/char/virtio-serial-bus.c     |    2 +-
>  hw/core/qdev-properties.c       |   58 +++++++++++++++++++++++++++++++++++++++
>  hw/net/virtio-net.c             |   22 +++++++--------
>  hw/s390x/s390-virtio-bus.c      |    3 +-
>  hw/s390x/s390-virtio-bus.h      |    2 +-
>  hw/s390x/virtio-ccw.c           |   39 +++++++++++++++-----------
>  hw/s390x/virtio-ccw.h           |    5 +---
>  hw/scsi/vhost-scsi.c            |    3 +-
>  hw/scsi/virtio-scsi.c           |    4 +--
>  hw/virtio/virtio-balloon.c      |    2 +-
>  hw/virtio/virtio-bus.c          |    6 ++--
>  hw/virtio/virtio-mmio.c         |    4 +--
>  hw/virtio/virtio-pci.c          |    3 +-
>  hw/virtio/virtio-pci.h          |    2 +-
>  hw/virtio/virtio-rng.c          |    2 +-
>  hw/virtio/virtio.c              |   13 +++++----
>  include/hw/qdev-properties.h    |   12 ++++++++
>  include/hw/virtio/virtio-bus.h  |    8 +++---
>  include/hw/virtio/virtio-net.h  |   46 +++++++++++++++----------------
>  include/hw/virtio/virtio-scsi.h |    6 ++--
>  include/hw/virtio/virtio.h      |   38 ++++++++++++++-----------
>  23 files changed, 184 insertions(+), 100 deletions(-)
...
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 9f3c58a..d6d1b98 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
...
> @@ -514,7 +514,7 @@ static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
>      return virtio_net_guest_offloads_by_features(vdev->guest_features);
>  }
> 
> -static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
> +static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features)
>  {
>      VirtIONet *n = VIRTIO_NET(vdev);
>      int i;
> @@ -1036,7 +1036,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
>                  return -1;
>              error_report("virtio-net unexpected empty queue: "
>                      "i %zd mergeable %d offset %zd, size %zd, "
> -                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
> +                    "guest hdr len %zd, host hdr len %zd guest features 0x%lx",

I think you need a different format string like PRIx64 here so that the
code also works right on a 32-bit system (where long is only 32-bit).

>                      i, n->mergeable_rx_bufs, offset, size,
>                      n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
>              exit(1);
...
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index 3fee4aa..fbd909d 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -371,8 +371,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>          } else {
>              features.index = ldub_phys(&address_space_memory,
>                                         ccw.cda + sizeof(features.features));
> -            if (features.index < ARRAY_SIZE(dev->host_features)) {
> -                features.features = dev->host_features[features.index];
> +            if (features.index == 0) {
> +                features.features = (uint32_t)dev->host_features;
> +            } else if (features.index == 1) {
> +                features.features = (uint32_t)(dev->host_features >> 32);
>              } else {
>                  /* Return zeroes if the guest supports more feature bits. */
>                  features.features = 0;
> @@ -399,8 +401,14 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>              features.index = ldub_phys(&address_space_memory,
>                                         ccw.cda + sizeof(features.features));
>              features.features = ldl_le_phys(&address_space_memory, ccw.cda);
> -            if (features.index < ARRAY_SIZE(dev->host_features)) {
> -                virtio_set_features(vdev, features.features);
> +            if (features.index == 0) {
> +                virtio_set_features(vdev,
> +                                    (vdev->guest_features & 0xffffffff00000000) |
> +                                    features.features);
> +            } else if (features.index == 1) {
> +                virtio_set_features(vdev,
> +                                    (vdev->guest_features & 0x00000000ffffffff) |
> +                                    ((uint64_t)features.features << 32));

The long constants 0xffffffff00000000 and 0x00000000ffffffff should
probably get an ULL suffix.

...
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 5814433..7f74ae5 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -593,6 +593,7 @@ void virtio_reset(void *opaque)
>      }
> 
>      vdev->guest_features = 0;
> +

Unnecessary white space change?

>      vdev->queue_sel = 0;
>      vdev->status = 0;
>      vdev->isr = 0;
> @@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>      qemu_put_8s(f, &vdev->status);
>      qemu_put_8s(f, &vdev->isr);
>      qemu_put_be16s(f, &vdev->queue_sel);
> -    qemu_put_be32s(f, &vdev->guest_features);
> +    /* XXX features >= 32 */
> +    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);

Casting a uint64_t* to a uint32_t* here sounds very wrong - this likely
only works on little endian sytems, but certainly not on big-endian
systems.
If you do not want to extend this for 64-bit right from the beginning,
I think you've got to use a temporary 32-bit variable to get this right.

...
> @@ -1005,9 +1007,10 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>      }
>      qemu_get_be32s(f, &features);
> 
> +    /* XXX features >= 32 */
>      if (virtio_set_features(vdev, features) < 0) {
>          supported_features = k->get_features(qbus->parent);
> -        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
> +        error_report("Features 0x%x unsupported. Allowed features: 0x%lx",
>                       features, supported_features);

You'll likely need the PRIx64 format here, too.

>          return -1;
>      }
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 070006c..81e5d0b 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -6,6 +6,7 @@
>  /*** qdev-properties.c ***/
> 
>  extern PropertyInfo qdev_prop_bit;
> +extern PropertyInfo qdev_prop_bit64;
>  extern PropertyInfo qdev_prop_bool;
>  extern PropertyInfo qdev_prop_uint8;
>  extern PropertyInfo qdev_prop_uint16;
> @@ -51,6 +52,17 @@ extern PropertyInfo qdev_prop_arraylen;
>          .defval    = (bool)_defval,                              \
>          }
> 
> +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {  \
> +        .name      = (_name),                                    \
> +        .info      = &(qdev_prop_bit64),                           \

No need for the paranthesis around qdev_prop_bit64 here?

> +        .bitnr    = (_bit),                                      \
> +        .offset    = offsetof(_state, _field)                    \
> +            + type_check(uint64_t,typeof_field(_state, _field)), \
> +        .qtype     = QTYPE_QBOOL,                                \
> +        .defval    = (bool)_defval,                              \
> +        }

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2014-12-12 10:06     ` Thomas Huth
  0 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-12 10:06 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:07 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> With virtio-1, we support more than 32 feature bits. Let's extend both
> host and guest features to 64, which should suffice for a while.
> 
> vhost and migration have been ignored for now.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/9pfs/virtio-9p-device.c      |    2 +-
>  hw/block/virtio-blk.c           |    2 +-
>  hw/char/virtio-serial-bus.c     |    2 +-
>  hw/core/qdev-properties.c       |   58 +++++++++++++++++++++++++++++++++++++++
>  hw/net/virtio-net.c             |   22 +++++++--------
>  hw/s390x/s390-virtio-bus.c      |    3 +-
>  hw/s390x/s390-virtio-bus.h      |    2 +-
>  hw/s390x/virtio-ccw.c           |   39 +++++++++++++++-----------
>  hw/s390x/virtio-ccw.h           |    5 +---
>  hw/scsi/vhost-scsi.c            |    3 +-
>  hw/scsi/virtio-scsi.c           |    4 +--
>  hw/virtio/virtio-balloon.c      |    2 +-
>  hw/virtio/virtio-bus.c          |    6 ++--
>  hw/virtio/virtio-mmio.c         |    4 +--
>  hw/virtio/virtio-pci.c          |    3 +-
>  hw/virtio/virtio-pci.h          |    2 +-
>  hw/virtio/virtio-rng.c          |    2 +-
>  hw/virtio/virtio.c              |   13 +++++----
>  include/hw/qdev-properties.h    |   12 ++++++++
>  include/hw/virtio/virtio-bus.h  |    8 +++---
>  include/hw/virtio/virtio-net.h  |   46 +++++++++++++++----------------
>  include/hw/virtio/virtio-scsi.h |    6 ++--
>  include/hw/virtio/virtio.h      |   38 ++++++++++++++-----------
>  23 files changed, 184 insertions(+), 100 deletions(-)
...
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 9f3c58a..d6d1b98 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
...
> @@ -514,7 +514,7 @@ static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
>      return virtio_net_guest_offloads_by_features(vdev->guest_features);
>  }
> 
> -static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
> +static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features)
>  {
>      VirtIONet *n = VIRTIO_NET(vdev);
>      int i;
> @@ -1036,7 +1036,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
>                  return -1;
>              error_report("virtio-net unexpected empty queue: "
>                      "i %zd mergeable %d offset %zd, size %zd, "
> -                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
> +                    "guest hdr len %zd, host hdr len %zd guest features 0x%lx",

I think you need a different format string like PRIx64 here so that the
code also works right on a 32-bit system (where long is only 32-bit).

>                      i, n->mergeable_rx_bufs, offset, size,
>                      n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
>              exit(1);
...
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index 3fee4aa..fbd909d 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -371,8 +371,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>          } else {
>              features.index = ldub_phys(&address_space_memory,
>                                         ccw.cda + sizeof(features.features));
> -            if (features.index < ARRAY_SIZE(dev->host_features)) {
> -                features.features = dev->host_features[features.index];
> +            if (features.index == 0) {
> +                features.features = (uint32_t)dev->host_features;
> +            } else if (features.index == 1) {
> +                features.features = (uint32_t)(dev->host_features >> 32);
>              } else {
>                  /* Return zeroes if the guest supports more feature bits. */
>                  features.features = 0;
> @@ -399,8 +401,14 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>              features.index = ldub_phys(&address_space_memory,
>                                         ccw.cda + sizeof(features.features));
>              features.features = ldl_le_phys(&address_space_memory, ccw.cda);
> -            if (features.index < ARRAY_SIZE(dev->host_features)) {
> -                virtio_set_features(vdev, features.features);
> +            if (features.index == 0) {
> +                virtio_set_features(vdev,
> +                                    (vdev->guest_features & 0xffffffff00000000) |
> +                                    features.features);
> +            } else if (features.index == 1) {
> +                virtio_set_features(vdev,
> +                                    (vdev->guest_features & 0x00000000ffffffff) |
> +                                    ((uint64_t)features.features << 32));

The long constants 0xffffffff00000000 and 0x00000000ffffffff should
probably get an ULL suffix.

...
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 5814433..7f74ae5 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -593,6 +593,7 @@ void virtio_reset(void *opaque)
>      }
> 
>      vdev->guest_features = 0;
> +

Unnecessary white space change?

>      vdev->queue_sel = 0;
>      vdev->status = 0;
>      vdev->isr = 0;
> @@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>      qemu_put_8s(f, &vdev->status);
>      qemu_put_8s(f, &vdev->isr);
>      qemu_put_be16s(f, &vdev->queue_sel);
> -    qemu_put_be32s(f, &vdev->guest_features);
> +    /* XXX features >= 32 */
> +    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);

Casting a uint64_t* to a uint32_t* here sounds very wrong - this likely
only works on little endian sytems, but certainly not on big-endian
systems.
If you do not want to extend this for 64-bit right from the beginning,
I think you've got to use a temporary 32-bit variable to get this right.

...
> @@ -1005,9 +1007,10 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>      }
>      qemu_get_be32s(f, &features);
> 
> +    /* XXX features >= 32 */
>      if (virtio_set_features(vdev, features) < 0) {
>          supported_features = k->get_features(qbus->parent);
> -        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
> +        error_report("Features 0x%x unsupported. Allowed features: 0x%lx",
>                       features, supported_features);

You'll likely need the PRIx64 format here, too.

>          return -1;
>      }
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 070006c..81e5d0b 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -6,6 +6,7 @@
>  /*** qdev-properties.c ***/
> 
>  extern PropertyInfo qdev_prop_bit;
> +extern PropertyInfo qdev_prop_bit64;
>  extern PropertyInfo qdev_prop_bool;
>  extern PropertyInfo qdev_prop_uint8;
>  extern PropertyInfo qdev_prop_uint16;
> @@ -51,6 +52,17 @@ extern PropertyInfo qdev_prop_arraylen;
>          .defval    = (bool)_defval,                              \
>          }
> 
> +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {  \
> +        .name      = (_name),                                    \
> +        .info      = &(qdev_prop_bit64),                           \

No need for the paranthesis around qdev_prop_bit64 here?

> +        .bitnr    = (_bit),                                      \
> +        .offset    = offsetof(_state, _field)                    \
> +            + type_check(uint64_t,typeof_field(_state, _field)), \
> +        .qtype     = QTYPE_QBOOL,                                \
> +        .defval    = (bool)_defval,                              \
> +        }

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 14:46   ` [Qemu-devel] " Thomas Huth
@ 2014-12-12 10:07       ` Cornelia Huck
  2014-12-12 10:07       ` Cornelia Huck
  1 sibling, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12 10:07 UTC (permalink / raw)
  To: Thomas Huth; +Cc: rusty, mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 15:46:23 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:


> > +static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
> > +{
> > +    assert(fbit < 32);
> > +    return !!(features & (1 << fbit));
> > +}
> > +
> > +static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> > +{
> > +    return __virtio_has_feature(vdev->guest_features, fbit);
> > +}
> > +
> 
> I've got to say that I'm a little bit unhappy with the naming of the
> functions - and in contrast to the Linux kernel code, I think it is
> also quite uncommon in the QEMU sources to use function names with
> double underscores at the beginning.
> 
> Could you maybe rename the second function to "virtio_vdev_has_feature"
> instead? And then remove the double underscores from the first function?

Renamed the functions just like this.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 04/20] virtio: add feature checking helpers
@ 2014-12-12 10:07       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12 10:07 UTC (permalink / raw)
  To: Thomas Huth; +Cc: mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 15:46:23 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:


> > +static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
> > +{
> > +    assert(fbit < 32);
> > +    return !!(features & (1 << fbit));
> > +}
> > +
> > +static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> > +{
> > +    return __virtio_has_feature(vdev->guest_features, fbit);
> > +}
> > +
> 
> I've got to say that I'm a little bit unhappy with the naming of the
> functions - and in contrast to the Linux kernel code, I think it is
> also quite uncommon in the QEMU sources to use function names with
> double underscores at the beginning.
> 
> Could you maybe rename the second function to "virtio_vdev_has_feature"
> instead? And then remove the double underscores from the first function?

Renamed the functions just like this.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2014-12-12 10:06     ` Thomas Huth
@ 2014-12-12 10:17       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12 10:17 UTC (permalink / raw)
  To: Thomas Huth; +Cc: rusty, mst, qemu-devel, virtualization

On Fri, 12 Dec 2014 11:06:40 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:

> On Thu, 11 Dec 2014 14:25:07 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > With virtio-1, we support more than 32 feature bits. Let's extend both
> > host and guest features to 64, which should suffice for a while.
> > 
> > vhost and migration have been ignored for now.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

> > @@ -1036,7 +1036,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
> >                  return -1;
> >              error_report("virtio-net unexpected empty queue: "
> >                      "i %zd mergeable %d offset %zd, size %zd, "
> > -                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
> > +                    "guest hdr len %zd, host hdr len %zd guest features 0x%lx",
> 
> I think you need a different format string like PRIx64 here so that the
> code also works right on a 32-bit system (where long is only 32-bit).

Reminder to self: set up cross-compile again.

> 
> >                      i, n->mergeable_rx_bufs, offset, size,
> >                      n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
> >              exit(1);

> > @@ -399,8 +401,14 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> >              features.index = ldub_phys(&address_space_memory,
> >                                         ccw.cda + sizeof(features.features));
> >              features.features = ldl_le_phys(&address_space_memory, ccw.cda);
> > -            if (features.index < ARRAY_SIZE(dev->host_features)) {
> > -                virtio_set_features(vdev, features.features);
> > +            if (features.index == 0) {
> > +                virtio_set_features(vdev,
> > +                                    (vdev->guest_features & 0xffffffff00000000) |
> > +                                    features.features);
> > +            } else if (features.index == 1) {
> > +                virtio_set_features(vdev,
> > +                                    (vdev->guest_features & 0x00000000ffffffff) |
> > +                                    ((uint64_t)features.features << 32));
> 
> The long constants 0xffffffff00000000 and 0x00000000ffffffff should
> probably get an ULL suffix.

Probably.

> > @@ -593,6 +593,7 @@ void virtio_reset(void *opaque)
> >      }
> > 
> >      vdev->guest_features = 0;
> > +
> 
> Unnecessary white space change?

Crept in during various rebase sessions :)

> 
> >      vdev->queue_sel = 0;
> >      vdev->status = 0;
> >      vdev->isr = 0;
> > @@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> >      qemu_put_8s(f, &vdev->status);
> >      qemu_put_8s(f, &vdev->isr);
> >      qemu_put_be16s(f, &vdev->queue_sel);
> > -    qemu_put_be32s(f, &vdev->guest_features);
> > +    /* XXX features >= 32 */
> > +    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);
> 
> Casting a uint64_t* to a uint32_t* here sounds very wrong - this likely
> only works on little endian sytems, but certainly not on big-endian
> systems.
> If you do not want to extend this for 64-bit right from the beginning,
> I think you've got to use a temporary 32-bit variable to get this right.

Hm... always store the old 32 bits here, then store the new 32 bits
later? Should be able to get that compatible.


> > +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {  \
> > +        .name      = (_name),                                    \
> > +        .info      = &(qdev_prop_bit64),                           \
> 
> No need for the paranthesis around qdev_prop_bit64 here?

Straight copy&paste :) I'd prefer to keep the same style for all
#defines here.

> 
> > +        .bitnr    = (_bit),                                      \
> > +        .offset    = offsetof(_state, _field)                    \
> > +            + type_check(uint64_t,typeof_field(_state, _field)), \
> > +        .qtype     = QTYPE_QBOOL,                                \
> > +        .defval    = (bool)_defval,                              \
> > +        }

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2014-12-12 10:17       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12 10:17 UTC (permalink / raw)
  To: Thomas Huth; +Cc: mst, qemu-devel, virtualization

On Fri, 12 Dec 2014 11:06:40 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:

> On Thu, 11 Dec 2014 14:25:07 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > With virtio-1, we support more than 32 feature bits. Let's extend both
> > host and guest features to 64, which should suffice for a while.
> > 
> > vhost and migration have been ignored for now.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

> > @@ -1036,7 +1036,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
> >                  return -1;
> >              error_report("virtio-net unexpected empty queue: "
> >                      "i %zd mergeable %d offset %zd, size %zd, "
> > -                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
> > +                    "guest hdr len %zd, host hdr len %zd guest features 0x%lx",
> 
> I think you need a different format string like PRIx64 here so that the
> code also works right on a 32-bit system (where long is only 32-bit).

Reminder to self: set up cross-compile again.

> 
> >                      i, n->mergeable_rx_bufs, offset, size,
> >                      n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
> >              exit(1);

> > @@ -399,8 +401,14 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> >              features.index = ldub_phys(&address_space_memory,
> >                                         ccw.cda + sizeof(features.features));
> >              features.features = ldl_le_phys(&address_space_memory, ccw.cda);
> > -            if (features.index < ARRAY_SIZE(dev->host_features)) {
> > -                virtio_set_features(vdev, features.features);
> > +            if (features.index == 0) {
> > +                virtio_set_features(vdev,
> > +                                    (vdev->guest_features & 0xffffffff00000000) |
> > +                                    features.features);
> > +            } else if (features.index == 1) {
> > +                virtio_set_features(vdev,
> > +                                    (vdev->guest_features & 0x00000000ffffffff) |
> > +                                    ((uint64_t)features.features << 32));
> 
> The long constants 0xffffffff00000000 and 0x00000000ffffffff should
> probably get an ULL suffix.

Probably.

> > @@ -593,6 +593,7 @@ void virtio_reset(void *opaque)
> >      }
> > 
> >      vdev->guest_features = 0;
> > +
> 
> Unnecessary white space change?

Crept in during various rebase sessions :)

> 
> >      vdev->queue_sel = 0;
> >      vdev->status = 0;
> >      vdev->isr = 0;
> > @@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> >      qemu_put_8s(f, &vdev->status);
> >      qemu_put_8s(f, &vdev->isr);
> >      qemu_put_be16s(f, &vdev->queue_sel);
> > -    qemu_put_be32s(f, &vdev->guest_features);
> > +    /* XXX features >= 32 */
> > +    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);
> 
> Casting a uint64_t* to a uint32_t* here sounds very wrong - this likely
> only works on little endian sytems, but certainly not on big-endian
> systems.
> If you do not want to extend this for 64-bit right from the beginning,
> I think you've got to use a temporary 32-bit variable to get this right.

Hm... always store the old 32 bits here, then store the new 32 bits
later? Should be able to get that compatible.


> > +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {  \
> > +        .name      = (_name),                                    \
> > +        .info      = &(qdev_prop_bit64),                           \
> 
> No need for the paranthesis around qdev_prop_bit64 here?

Straight copy&paste :) I'd prefer to keep the same style for all
#defines here.

> 
> > +        .bitnr    = (_bit),                                      \
> > +        .offset    = offsetof(_state, _field)                    \
> > +            + type_check(uint64_t,typeof_field(_state, _field)), \
> > +        .qtype     = QTYPE_QBOOL,                                \
> > +        .defval    = (bool)_defval,                              \
> > +        }

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
  2014-12-11 13:25   ` Cornelia Huck
@ 2014-12-12 10:55     ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-12 10:55 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: rusty, mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:14 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> For virtio-1 devices, the driver must not attempt to set feature bits
> after it set FEATURES_OK in the device status. Simply reject it in
> that case.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio.c         |   16 ++++++++++++++--
>  include/hw/virtio/virtio.h |    2 ++
>  2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 57190ba..a3dd67b 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>      vmstate_save_state(f, &vmstate_virtio, vdev);
>  }
> 
> -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)

Maybe avoid the double underscores here? But unfortunately, I also fail
to come up with a better suggestion for a name here ...

>  {
>      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
>      VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
> @@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
>      return bad ? -1 : 0;
>  }
> 
> +int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> +{
> +   /*
> +     * The driver must not attempt to set features after feature negotiation
> +     * has finished.
> +     */
> +    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
> +        return -EINVAL;
> +    }

Hmm, according to your patch description, the FEATURES_OK check only
applies to virtio-1.0 devices ... so shouldn't there be a check for
virtio-1 here? Or did I miss something?

> +    return __virtio_set_features(vdev, val);
> +}

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
@ 2014-12-12 10:55     ` Thomas Huth
  0 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-12 10:55 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: mst, qemu-devel, virtualization

On Thu, 11 Dec 2014 14:25:14 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> For virtio-1 devices, the driver must not attempt to set feature bits
> after it set FEATURES_OK in the device status. Simply reject it in
> that case.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio.c         |   16 ++++++++++++++--
>  include/hw/virtio/virtio.h |    2 ++
>  2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 57190ba..a3dd67b 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>      vmstate_save_state(f, &vmstate_virtio, vdev);
>  }
> 
> -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)

Maybe avoid the double underscores here? But unfortunately, I also fail
to come up with a better suggestion for a name here ...

>  {
>      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
>      VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
> @@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
>      return bad ? -1 : 0;
>  }
> 
> +int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> +{
> +   /*
> +     * The driver must not attempt to set features after feature negotiation
> +     * has finished.
> +     */
> +    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
> +        return -EINVAL;
> +    }

Hmm, according to your patch description, the FEATURES_OK check only
applies to virtio-1.0 devices ... so shouldn't there be a check for
virtio-1 here? Or did I miss something?

> +    return __virtio_set_features(vdev, val);
> +}

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
  2014-12-12 10:55     ` Thomas Huth
@ 2014-12-12 11:18       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12 11:18 UTC (permalink / raw)
  To: Thomas Huth; +Cc: rusty, mst, qemu-devel, virtualization

On Fri, 12 Dec 2014 11:55:38 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:

> On Thu, 11 Dec 2014 14:25:14 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > For virtio-1 devices, the driver must not attempt to set feature bits
> > after it set FEATURES_OK in the device status. Simply reject it in
> > that case.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/virtio/virtio.c         |   16 ++++++++++++++--
> >  include/hw/virtio/virtio.h |    2 ++
> >  2 files changed, 16 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > index 57190ba..a3dd67b 100644
> > --- a/hw/virtio/virtio.c
> > +++ b/hw/virtio/virtio.c
> > @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> >      vmstate_save_state(f, &vmstate_virtio, vdev);
> >  }
> > 
> > -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
> 
> Maybe avoid the double underscores here? But unfortunately, I also fail
> to come up with a better suggestion for a name here ...

virtio_set_features_nocheck()?

This function is only called within virtio.c anyway...

> 
> >  {
> >      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> >      VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
> > @@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> >      return bad ? -1 : 0;
> >  }
> > 
> > +int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > +{
> > +   /*
> > +     * The driver must not attempt to set features after feature negotiation
> > +     * has finished.
> > +     */
> > +    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
> > +        return -EINVAL;
> > +    }
> 
> Hmm, according to your patch description, the FEATURES_OK check only
> applies to virtio-1.0 devices ... so shouldn't there be a check for
> virtio-1 here? Or did I miss something?

A device in legacy mode will never have FEATURES_OK set. But it is a
bit non-obvious - maybe adding a check for VERSION_1 does not hurt.

> 
> > +    return __virtio_set_features(vdev, val);
> > +}
> 
>  Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
@ 2014-12-12 11:18       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-12 11:18 UTC (permalink / raw)
  To: Thomas Huth; +Cc: mst, qemu-devel, virtualization

On Fri, 12 Dec 2014 11:55:38 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:

> On Thu, 11 Dec 2014 14:25:14 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > For virtio-1 devices, the driver must not attempt to set feature bits
> > after it set FEATURES_OK in the device status. Simply reject it in
> > that case.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/virtio/virtio.c         |   16 ++++++++++++++--
> >  include/hw/virtio/virtio.h |    2 ++
> >  2 files changed, 16 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > index 57190ba..a3dd67b 100644
> > --- a/hw/virtio/virtio.c
> > +++ b/hw/virtio/virtio.c
> > @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> >      vmstate_save_state(f, &vmstate_virtio, vdev);
> >  }
> > 
> > -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
> 
> Maybe avoid the double underscores here? But unfortunately, I also fail
> to come up with a better suggestion for a name here ...

virtio_set_features_nocheck()?

This function is only called within virtio.c anyway...

> 
> >  {
> >      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> >      VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
> > @@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> >      return bad ? -1 : 0;
> >  }
> > 
> > +int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > +{
> > +   /*
> > +     * The driver must not attempt to set features after feature negotiation
> > +     * has finished.
> > +     */
> > +    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
> > +        return -EINVAL;
> > +    }
> 
> Hmm, according to your patch description, the FEATURES_OK check only
> applies to virtio-1.0 devices ... so shouldn't there be a check for
> virtio-1 here? Or did I miss something?

A device in legacy mode will never have FEATURES_OK set. But it is a
bit non-obvious - maybe adding a check for VERSION_1 does not hurt.

> 
> > +    return __virtio_set_features(vdev, val);
> > +}
> 
>  Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
  2014-12-12 11:18       ` Cornelia Huck
@ 2014-12-12 11:25         ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-12 11:25 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: rusty, mst, qemu-devel, virtualization

On Fri, 12 Dec 2014 12:18:25 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> On Fri, 12 Dec 2014 11:55:38 +0100
> Thomas Huth <thuth@linux.vnet.ibm.com> wrote:
> 
> > On Thu, 11 Dec 2014 14:25:14 +0100
> > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> > 
> > > For virtio-1 devices, the driver must not attempt to set feature bits
> > > after it set FEATURES_OK in the device status. Simply reject it in
> > > that case.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > ---
> > >  hw/virtio/virtio.c         |   16 ++++++++++++++--
> > >  include/hw/virtio/virtio.h |    2 ++
> > >  2 files changed, 16 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > > index 57190ba..a3dd67b 100644
> > > --- a/hw/virtio/virtio.c
> > > +++ b/hw/virtio/virtio.c
> > > @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> > >      vmstate_save_state(f, &vmstate_virtio, vdev);
> > >  }
> > > 
> > > -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > 
> > Maybe avoid the double underscores here? But unfortunately, I also fail
> > to come up with a better suggestion for a name here ...
> 
> virtio_set_features_nocheck()?

Sounds ok to me.

> This function is only called within virtio.c anyway...

Right, so the double underscores should be ok here, too. (I still do
not like them very much, but that's just my personal taste in this case)

> > >  {
> > >      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> > >      VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
> > > @@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > >      return bad ? -1 : 0;
> > >  }
> > > 
> > > +int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > +{
> > > +   /*
> > > +     * The driver must not attempt to set features after feature negotiation
> > > +     * has finished.
> > > +     */
> > > +    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
> > > +        return -EINVAL;
> > > +    }
> > 
> > Hmm, according to your patch description, the FEATURES_OK check only
> > applies to virtio-1.0 devices ... so shouldn't there be a check for
> > virtio-1 here? Or did I miss something?
> 
> A device in legacy mode will never have FEATURES_OK set. But it is a
> bit non-obvious - maybe adding a check for VERSION_1 does not hurt.

Ah, ok, right, and if it is a legacy device and has FEATURES_OK set, it
is certainly a misbehavior wrt the legacy protocol. So it really should
be ok or even good to _not_ check for virtio-1.0 here. So sorry for the
confusion, I think now the patch is good as it is:

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
@ 2014-12-12 11:25         ` Thomas Huth
  0 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2014-12-12 11:25 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: mst, qemu-devel, virtualization

On Fri, 12 Dec 2014 12:18:25 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> On Fri, 12 Dec 2014 11:55:38 +0100
> Thomas Huth <thuth@linux.vnet.ibm.com> wrote:
> 
> > On Thu, 11 Dec 2014 14:25:14 +0100
> > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> > 
> > > For virtio-1 devices, the driver must not attempt to set feature bits
> > > after it set FEATURES_OK in the device status. Simply reject it in
> > > that case.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > ---
> > >  hw/virtio/virtio.c         |   16 ++++++++++++++--
> > >  include/hw/virtio/virtio.h |    2 ++
> > >  2 files changed, 16 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > > index 57190ba..a3dd67b 100644
> > > --- a/hw/virtio/virtio.c
> > > +++ b/hw/virtio/virtio.c
> > > @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> > >      vmstate_save_state(f, &vmstate_virtio, vdev);
> > >  }
> > > 
> > > -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > 
> > Maybe avoid the double underscores here? But unfortunately, I also fail
> > to come up with a better suggestion for a name here ...
> 
> virtio_set_features_nocheck()?

Sounds ok to me.

> This function is only called within virtio.c anyway...

Right, so the double underscores should be ok here, too. (I still do
not like them very much, but that's just my personal taste in this case)

> > >  {
> > >      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> > >      VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus);
> > > @@ -994,6 +994,18 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > >      return bad ? -1 : 0;
> > >  }
> > > 
> > > +int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > +{
> > > +   /*
> > > +     * The driver must not attempt to set features after feature negotiation
> > > +     * has finished.
> > > +     */
> > > +    if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) {
> > > +        return -EINVAL;
> > > +    }
> > 
> > Hmm, according to your patch description, the FEATURES_OK check only
> > applies to virtio-1.0 devices ... so shouldn't there be a check for
> > virtio-1 here? Or did I miss something?
> 
> A device in legacy mode will never have FEATURES_OK set. But it is a
> bit non-obvious - maybe adding a check for VERSION_1 does not hurt.

Ah, ok, right, and if it is a legacy device and has FEATURES_OK set, it
is certainly a misbehavior wrt the legacy protocol. So it really should
be ok or even good to _not_ check for virtio-1.0 here. So sorry for the
confusion, I think now the patch is good as it is:

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 17/20] virtio-net: enable virtio 1.0
  2014-12-11 13:25   ` Cornelia Huck
@ 2014-12-16 13:10     ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-16 13:10 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:19PM +0100, Cornelia Huck wrote:
> virtio-net (non-vhost) now should have everything in place to support
> virtio 1.0: let's enable the feature bit for it.
> 
> Note that VIRTIO_F_VERSION_1 is technically a transport feature; once
> every device is ready for virtio 1.0, we can move setting this
> feature bit out of the individual devices.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

So to use this with e.g. tun, you need to make tun device LE.
I posted a kernel patch 1418732988-3535-1-git-send-email-mst@redhat.com
with TUNSETVNETLE/TUNGETVNETLE ioctls to support it.

But you still need to call them in qemu, and disable virtio-1.0
if not there.


> ---
>  hw/net/virtio-net.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 7ee2bd6..b5dd356 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -473,6 +473,7 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
>      }
>  
>      if (!get_vhost_net(nc->peer)) {
> +        virtio_add_feature(&features, VIRTIO_F_VERSION_1);
>          return features;
>      }
>      return vhost_net_get_features(get_vhost_net(nc->peer), features);
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 17/20] virtio-net: enable virtio 1.0
@ 2014-12-16 13:10     ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-16 13:10 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:19PM +0100, Cornelia Huck wrote:
> virtio-net (non-vhost) now should have everything in place to support
> virtio 1.0: let's enable the feature bit for it.
> 
> Note that VIRTIO_F_VERSION_1 is technically a transport feature; once
> every device is ready for virtio 1.0, we can move setting this
> feature bit out of the individual devices.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

So to use this with e.g. tun, you need to make tun device LE.
I posted a kernel patch 1418732988-3535-1-git-send-email-mst@redhat.com
with TUNSETVNETLE/TUNGETVNETLE ioctls to support it.

But you still need to call them in qemu, and disable virtio-1.0
if not there.


> ---
>  hw/net/virtio-net.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 7ee2bd6..b5dd356 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -473,6 +473,7 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
>      }
>  
>      if (!get_vhost_net(nc->peer)) {
> +        virtio_add_feature(&features, VIRTIO_F_VERSION_1);
>          return features;
>      }
>      return vhost_net_get_features(get_vhost_net(nc->peer), features);
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 17/20] virtio-net: enable virtio 1.0
  2014-12-16 13:10     ` Michael S. Tsirkin
@ 2014-12-18 16:57       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-18 16:57 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Tue, 16 Dec 2014 15:10:04 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:19PM +0100, Cornelia Huck wrote:
> > virtio-net (non-vhost) now should have everything in place to support
> > virtio 1.0: let's enable the feature bit for it.
> > 
> > Note that VIRTIO_F_VERSION_1 is technically a transport feature; once
> > every device is ready for virtio 1.0, we can move setting this
> > feature bit out of the individual devices.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> So to use this with e.g. tun, you need to make tun device LE.
> I posted a kernel patch 1418732988-3535-1-git-send-email-mst@redhat.com
> with TUNSETVNETLE/TUNGETVNETLE ioctls to support it.
> 
> But you still need to call them in qemu, and disable virtio-1.0
> if not there.

I had planned on playing with this a bit, but didn't come around to
doing it. I'm afraid it will have to wait until next year.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 17/20] virtio-net: enable virtio 1.0
@ 2014-12-18 16:57       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2014-12-18 16:57 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Tue, 16 Dec 2014 15:10:04 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:19PM +0100, Cornelia Huck wrote:
> > virtio-net (non-vhost) now should have everything in place to support
> > virtio 1.0: let's enable the feature bit for it.
> > 
> > Note that VIRTIO_F_VERSION_1 is technically a transport feature; once
> > every device is ready for virtio 1.0, we can move setting this
> > feature bit out of the individual devices.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> So to use this with e.g. tun, you need to make tun device LE.
> I posted a kernel patch 1418732988-3535-1-git-send-email-mst@redhat.com
> with TUNSETVNETLE/TUNGETVNETLE ioctls to support it.
> 
> But you still need to call them in qemu, and disable virtio-1.0
> if not there.

I had planned on playing with this a bit, but didn't come around to
doing it. I'm afraid it will have to wait until next year.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features
  2014-12-11 13:25   ` Cornelia Huck
@ 2014-12-28  8:32     ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-28  8:32 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> Devices may support different sets of feature bits depending on which
> revision they're operating at. Let's give the transport a way to
> re-query the device about its features when the revision has been
> changed.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

So now we have both get_features and get_features_rev, and
it's never clear which revision does host_features refer to.
IMHO that's just too messy.
Let's add get_legacy_features and host_legacy_features instead?


> ---
>  hw/s390x/virtio-ccw.c          |   12 ++++++++++--
>  hw/virtio/virtio-bus.c         |   14 ++++++++++++--
>  include/hw/virtio/virtio-bus.h |    3 +++
>  include/hw/virtio/virtio.h     |    3 +++
>  4 files changed, 28 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index a55e851..8b6b2ab 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -699,6 +699,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>          }
>          ret = 0;
>          dev->revision = revinfo.revision;
> +        /* Re-evaluate which features the device wants to offer. */
> +        dev->host_features =
> +            virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features,
> +                                             dev->revision >= 1 ? 1 : 0);
>          break;
>      default:
>          ret = -ENOSYS;
> @@ -712,6 +716,9 @@ static void virtio_sch_disable_cb(SubchDev *sch)
>      VirtioCcwDevice *dev = sch->driver_data;
>  
>      dev->revision = -1;
> +    /* Reset the device's features to legacy. */
> +    dev->host_features =
> +        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
>  }
>  
>  static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
> @@ -853,8 +860,9 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
>      virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
>      virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
>  
> -    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
> -                                                      dev->host_features);
> +    /* All devices start in legacy mode. */
> +    dev->host_features =
> +        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
>  
>      css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
>                            parent->hotplugged, 1);
> diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
> index 32e3fab..a30826c 100644
> --- a/hw/virtio/virtio-bus.c
> +++ b/hw/virtio/virtio-bus.c
> @@ -97,18 +97,28 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
>  }
>  
>  /* Get the features of the plugged device. */
> -uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
> -                                      uint64_t requested_features)
> +uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
> +                                          uint64_t requested_features,
> +                                          unsigned int revision)
>  {
>      VirtIODevice *vdev = virtio_bus_get_device(bus);
>      VirtioDeviceClass *k;
>  
>      assert(vdev != NULL);
>      k = VIRTIO_DEVICE_GET_CLASS(vdev);
> +    if (revision > 0 && k->get_features_rev) {
> +        return k->get_features_rev(vdev, requested_features, revision);
> +    }
>      assert(k->get_features != NULL);
>      return k->get_features(vdev, requested_features);
>  }
>  
> +uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
> +                                      uint64_t requested_features)
> +{
> +    return virtio_bus_get_vdev_features_rev(bus, requested_features, 0);
> +}
> +
>  /* Get bad features of the plugged device. */
>  uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
>  {
> diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
> index 0a4dde1..f0916ef 100644
> --- a/include/hw/virtio/virtio-bus.h
> +++ b/include/hw/virtio/virtio-bus.h
> @@ -84,6 +84,9 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
>  /* Get the features of the plugged device. */
>  uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
>                                        uint64_t requested_features);
> +uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
> +                                          uint64_t requested_features,
> +                                          unsigned int revision);
>  /* Get bad features of the plugged device. */
>  uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
>  /* Get config of the plugged device. */
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 068211e..1338540 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -147,6 +147,9 @@ typedef struct VirtioDeviceClass {
>      DeviceRealize realize;
>      DeviceUnrealize unrealize;
>      uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
> +    uint64_t (*get_features_rev)(VirtIODevice *vdev,
> +                                 uint64_t requested_features,
> +                                 unsigned int revision);
>      uint64_t (*bad_features)(VirtIODevice *vdev);
>      void (*set_features)(VirtIODevice *vdev, uint64_t val);
>      int (*validate_features)(VirtIODevice *vdev);
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 18/20] virtio: support revision-specific features
@ 2014-12-28  8:32     ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-28  8:32 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> Devices may support different sets of feature bits depending on which
> revision they're operating at. Let's give the transport a way to
> re-query the device about its features when the revision has been
> changed.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

So now we have both get_features and get_features_rev, and
it's never clear which revision does host_features refer to.
IMHO that's just too messy.
Let's add get_legacy_features and host_legacy_features instead?


> ---
>  hw/s390x/virtio-ccw.c          |   12 ++++++++++--
>  hw/virtio/virtio-bus.c         |   14 ++++++++++++--
>  include/hw/virtio/virtio-bus.h |    3 +++
>  include/hw/virtio/virtio.h     |    3 +++
>  4 files changed, 28 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index a55e851..8b6b2ab 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -699,6 +699,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>          }
>          ret = 0;
>          dev->revision = revinfo.revision;
> +        /* Re-evaluate which features the device wants to offer. */
> +        dev->host_features =
> +            virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features,
> +                                             dev->revision >= 1 ? 1 : 0);
>          break;
>      default:
>          ret = -ENOSYS;
> @@ -712,6 +716,9 @@ static void virtio_sch_disable_cb(SubchDev *sch)
>      VirtioCcwDevice *dev = sch->driver_data;
>  
>      dev->revision = -1;
> +    /* Reset the device's features to legacy. */
> +    dev->host_features =
> +        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
>  }
>  
>  static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
> @@ -853,8 +860,9 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
>      virtio_add_feature(&dev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
>      virtio_add_feature(&dev->host_features, VIRTIO_F_BAD_FEATURE);
>  
> -    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
> -                                                      dev->host_features);
> +    /* All devices start in legacy mode. */
> +    dev->host_features =
> +        virtio_bus_get_vdev_features_rev(&dev->bus, dev->host_features, 0);
>  
>      css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
>                            parent->hotplugged, 1);
> diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
> index 32e3fab..a30826c 100644
> --- a/hw/virtio/virtio-bus.c
> +++ b/hw/virtio/virtio-bus.c
> @@ -97,18 +97,28 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
>  }
>  
>  /* Get the features of the plugged device. */
> -uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
> -                                      uint64_t requested_features)
> +uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
> +                                          uint64_t requested_features,
> +                                          unsigned int revision)
>  {
>      VirtIODevice *vdev = virtio_bus_get_device(bus);
>      VirtioDeviceClass *k;
>  
>      assert(vdev != NULL);
>      k = VIRTIO_DEVICE_GET_CLASS(vdev);
> +    if (revision > 0 && k->get_features_rev) {
> +        return k->get_features_rev(vdev, requested_features, revision);
> +    }
>      assert(k->get_features != NULL);
>      return k->get_features(vdev, requested_features);
>  }
>  
> +uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
> +                                      uint64_t requested_features)
> +{
> +    return virtio_bus_get_vdev_features_rev(bus, requested_features, 0);
> +}
> +
>  /* Get bad features of the plugged device. */
>  uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
>  {
> diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
> index 0a4dde1..f0916ef 100644
> --- a/include/hw/virtio/virtio-bus.h
> +++ b/include/hw/virtio/virtio-bus.h
> @@ -84,6 +84,9 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus);
>  /* Get the features of the plugged device. */
>  uint64_t virtio_bus_get_vdev_features(VirtioBusState *bus,
>                                        uint64_t requested_features);
> +uint64_t virtio_bus_get_vdev_features_rev(VirtioBusState *bus,
> +                                          uint64_t requested_features,
> +                                          unsigned int revision);
>  /* Get bad features of the plugged device. */
>  uint64_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus);
>  /* Get config of the plugged device. */
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 068211e..1338540 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -147,6 +147,9 @@ typedef struct VirtioDeviceClass {
>      DeviceRealize realize;
>      DeviceUnrealize unrealize;
>      uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
> +    uint64_t (*get_features_rev)(VirtIODevice *vdev,
> +                                 uint64_t requested_features,
> +                                 unsigned int revision);
>      uint64_t (*bad_features)(VirtIODevice *vdev);
>      void (*set_features)(VirtIODevice *vdev, uint64_t val);
>      int (*validate_features)(VirtIODevice *vdev);
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
  2014-12-11 13:25   ` Cornelia Huck
@ 2014-12-28 10:24     ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-28 10:24 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> Wire up virtio-blk to provide different feature bit sets depending
> on whether legacy or v1.0 has been requested.
> 
> Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

So we need some way for devices to tell transports
not to negotiate rev 1.
Does clearing VERSION_1 have this effect?


> ---
>  hw/block/virtio-blk.c |   19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index 9cfae66..fdc236a 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -587,6 +587,24 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
>      return features;
>  }
>  
> +static uint64_t virtio_blk_get_features_rev(VirtIODevice *vdev,
> +                                            uint64_t features,
> +                                            unsigned int revision)
> +{
> +    if (revision == 0) {
> +        /* legacy */
> +        virtio_clear_feature(&features, VIRTIO_F_VERSION_1);
> +        return virtio_blk_get_features(vdev, features);
> +    }
> +    /* virtio 1.0 or later */
> +    virtio_clear_feature(&features, VIRTIO_BLK_F_SCSI);
> +    virtio_clear_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
> +    virtio_clear_feature(&features, VIRTIO_BLK_F_WCE);
> +    /* we're still missing ANY_LAYOUT */
> +    /* virtio_add_feature(&features, VIRTIO_F_VERSION_1); */
> +    return features;
> +}
> +
>  static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
>  {
>      VirtIOBlock *s = VIRTIO_BLK(vdev);
> @@ -821,6 +839,7 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
>      vdc->get_config = virtio_blk_update_config;
>      vdc->set_config = virtio_blk_set_config;
>      vdc->get_features = virtio_blk_get_features;
> +    vdc->get_features_rev = virtio_blk_get_features_rev;
>      vdc->set_status = virtio_blk_set_status;
>      vdc->reset = virtio_blk_reset;
>      vdc->save = virtio_blk_save_device;
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
@ 2014-12-28 10:24     ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-28 10:24 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> Wire up virtio-blk to provide different feature bit sets depending
> on whether legacy or v1.0 has been requested.
> 
> Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

So we need some way for devices to tell transports
not to negotiate rev 1.
Does clearing VERSION_1 have this effect?


> ---
>  hw/block/virtio-blk.c |   19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index 9cfae66..fdc236a 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -587,6 +587,24 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
>      return features;
>  }
>  
> +static uint64_t virtio_blk_get_features_rev(VirtIODevice *vdev,
> +                                            uint64_t features,
> +                                            unsigned int revision)
> +{
> +    if (revision == 0) {
> +        /* legacy */
> +        virtio_clear_feature(&features, VIRTIO_F_VERSION_1);
> +        return virtio_blk_get_features(vdev, features);
> +    }
> +    /* virtio 1.0 or later */
> +    virtio_clear_feature(&features, VIRTIO_BLK_F_SCSI);
> +    virtio_clear_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
> +    virtio_clear_feature(&features, VIRTIO_BLK_F_WCE);
> +    /* we're still missing ANY_LAYOUT */
> +    /* virtio_add_feature(&features, VIRTIO_F_VERSION_1); */
> +    return features;
> +}
> +
>  static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
>  {
>      VirtIOBlock *s = VIRTIO_BLK(vdev);
> @@ -821,6 +839,7 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
>      vdc->get_config = virtio_blk_update_config;
>      vdc->set_config = virtio_blk_set_config;
>      vdc->get_features = virtio_blk_get_features;
> +    vdc->get_features_rev = virtio_blk_get_features_rev;
>      vdc->set_status = virtio_blk_set_status;
>      vdc->reset = virtio_blk_reset;
>      vdc->save = virtio_blk_save_device;
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 13/20] virtio: allow to fail setting status
  2014-12-11 13:25   ` Cornelia Huck
@ 2014-12-30 12:25     ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-30 12:25 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> virtio-1 allow setting of the FEATURES_OK status bit to fail if
> the negotiated feature bits are inconsistent: let's fail
> virtio_set_status() in that case and update virtio-ccw to post an
> error to the guest.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Right but a separate validate_features call is awkward.
How about we defer virtio_set_features until FEATURES_OK,
and teach virtio_set_features that it can fail?


> ---
>  hw/s390x/virtio-ccw.c      |   20 ++++++++++++--------
>  hw/virtio/virtio.c         |   24 +++++++++++++++++++++++-
>  include/hw/virtio/virtio.h |    3 ++-
>  3 files changed, 37 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index e09e0da..a55e851 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -555,15 +555,19 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>              if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
>                  virtio_ccw_stop_ioeventfd(dev);
>              }
> -            virtio_set_status(vdev, status);
> -            if (vdev->status == 0) {
> -                virtio_reset(vdev);
> -            }
> -            if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
> -                virtio_ccw_start_ioeventfd(dev);
> +            if (virtio_set_status(vdev, status) == 0) {
> +                if (vdev->status == 0) {
> +                    virtio_reset(vdev);
> +                }
> +                if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
> +                    virtio_ccw_start_ioeventfd(dev);
> +                }
> +                sch->curr_status.scsw.count = ccw.count - sizeof(status);
> +                ret = 0;
> +            } else {
> +                /* Trigger a command reject. */
> +                ret = -ENOSYS;
>              }
> -            sch->curr_status.scsw.count = ccw.count - sizeof(status);
> -            ret = 0;
>          }
>          break;
>      case CCW_CMD_SET_IND:
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index a3dd67b..90eedd3 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -543,15 +543,37 @@ void virtio_update_irq(VirtIODevice *vdev)
>      virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
>  }
>  
> -void virtio_set_status(VirtIODevice *vdev, uint8_t val)
> +static int virtio_validate_features(VirtIODevice *vdev)
> +{
> +    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> +
> +    if (k->validate_features) {
> +        return k->validate_features(vdev);
> +    } else {
> +        return 0;
> +    }
> +}
> +
> +int virtio_set_status(VirtIODevice *vdev, uint8_t val)
>  {
>      VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
>      trace_virtio_set_status(vdev, val);
>  
> +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        if (!(vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) &&
> +            val & VIRTIO_CONFIG_S_FEATURES_OK) {
> +            int ret = virtio_validate_features(vdev);
> +
> +            if (ret) {
> +                return ret;
> +            }
> +        }
> +    }
>      if (k->set_status) {
>          k->set_status(vdev, val);
>      }
>      vdev->status = val;
> +    return 0;
>  }
>  
>  bool target_words_bigendian(void);
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index a24e403..068211e 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -149,6 +149,7 @@ typedef struct VirtioDeviceClass {
>      uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
>      uint64_t (*bad_features)(VirtIODevice *vdev);
>      void (*set_features)(VirtIODevice *vdev, uint64_t val);
> +    int (*validate_features)(VirtIODevice *vdev);
>      void (*get_config)(VirtIODevice *vdev, uint8_t *config);
>      void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
>      void (*reset)(VirtIODevice *vdev);
> @@ -233,7 +234,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>  void virtio_queue_notify(VirtIODevice *vdev, int n);
>  uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
>  void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
> -void virtio_set_status(VirtIODevice *vdev, uint8_t val);
> +int virtio_set_status(VirtIODevice *vdev, uint8_t val);
>  void virtio_reset(void *opaque);
>  void virtio_update_irq(VirtIODevice *vdev);
>  int virtio_set_features(VirtIODevice *vdev, uint64_t val);
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 13/20] virtio: allow to fail setting status
@ 2014-12-30 12:25     ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2014-12-30 12:25 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> virtio-1 allow setting of the FEATURES_OK status bit to fail if
> the negotiated feature bits are inconsistent: let's fail
> virtio_set_status() in that case and update virtio-ccw to post an
> error to the guest.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Right but a separate validate_features call is awkward.
How about we defer virtio_set_features until FEATURES_OK,
and teach virtio_set_features that it can fail?


> ---
>  hw/s390x/virtio-ccw.c      |   20 ++++++++++++--------
>  hw/virtio/virtio.c         |   24 +++++++++++++++++++++++-
>  include/hw/virtio/virtio.h |    3 ++-
>  3 files changed, 37 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index e09e0da..a55e851 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -555,15 +555,19 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>              if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
>                  virtio_ccw_stop_ioeventfd(dev);
>              }
> -            virtio_set_status(vdev, status);
> -            if (vdev->status == 0) {
> -                virtio_reset(vdev);
> -            }
> -            if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
> -                virtio_ccw_start_ioeventfd(dev);
> +            if (virtio_set_status(vdev, status) == 0) {
> +                if (vdev->status == 0) {
> +                    virtio_reset(vdev);
> +                }
> +                if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
> +                    virtio_ccw_start_ioeventfd(dev);
> +                }
> +                sch->curr_status.scsw.count = ccw.count - sizeof(status);
> +                ret = 0;
> +            } else {
> +                /* Trigger a command reject. */
> +                ret = -ENOSYS;
>              }
> -            sch->curr_status.scsw.count = ccw.count - sizeof(status);
> -            ret = 0;
>          }
>          break;
>      case CCW_CMD_SET_IND:
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index a3dd67b..90eedd3 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -543,15 +543,37 @@ void virtio_update_irq(VirtIODevice *vdev)
>      virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
>  }
>  
> -void virtio_set_status(VirtIODevice *vdev, uint8_t val)
> +static int virtio_validate_features(VirtIODevice *vdev)
> +{
> +    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> +
> +    if (k->validate_features) {
> +        return k->validate_features(vdev);
> +    } else {
> +        return 0;
> +    }
> +}
> +
> +int virtio_set_status(VirtIODevice *vdev, uint8_t val)
>  {
>      VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
>      trace_virtio_set_status(vdev, val);
>  
> +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        if (!(vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) &&
> +            val & VIRTIO_CONFIG_S_FEATURES_OK) {
> +            int ret = virtio_validate_features(vdev);
> +
> +            if (ret) {
> +                return ret;
> +            }
> +        }
> +    }
>      if (k->set_status) {
>          k->set_status(vdev, val);
>      }
>      vdev->status = val;
> +    return 0;
>  }
>  
>  bool target_words_bigendian(void);
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index a24e403..068211e 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -149,6 +149,7 @@ typedef struct VirtioDeviceClass {
>      uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
>      uint64_t (*bad_features)(VirtIODevice *vdev);
>      void (*set_features)(VirtIODevice *vdev, uint64_t val);
> +    int (*validate_features)(VirtIODevice *vdev);
>      void (*get_config)(VirtIODevice *vdev, uint8_t *config);
>      void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
>      void (*reset)(VirtIODevice *vdev);
> @@ -233,7 +234,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>  void virtio_queue_notify(VirtIODevice *vdev, int n);
>  uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
>  void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
> -void virtio_set_status(VirtIODevice *vdev, uint8_t val);
> +int virtio_set_status(VirtIODevice *vdev, uint8_t val);
>  void virtio_reset(void *opaque);
>  void virtio_update_irq(VirtIODevice *vdev);
>  int virtio_set_features(VirtIODevice *vdev, uint64_t val);
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 13/20] virtio: allow to fail setting status
  2014-12-30 12:25     ` Michael S. Tsirkin
@ 2015-01-07 16:13       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-07 16:13 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Tue, 30 Dec 2014 14:25:37 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > the negotiated feature bits are inconsistent: let's fail
> > virtio_set_status() in that case and update virtio-ccw to post an
> > error to the guest.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> Right but a separate validate_features call is awkward.
> How about we defer virtio_set_features until FEATURES_OK,
> and teach virtio_set_features that it can fail?

Hm. But we would need to keep virtio_set_features() where it is called
now for legacy devices, as they will never see FEATURES_OK, right? So
we need to make this depending on revisions (or whatever the equivalent
is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
this makes the code easier to follow.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 13/20] virtio: allow to fail setting status
@ 2015-01-07 16:13       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-07 16:13 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Tue, 30 Dec 2014 14:25:37 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > the negotiated feature bits are inconsistent: let's fail
> > virtio_set_status() in that case and update virtio-ccw to post an
> > error to the guest.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> Right but a separate validate_features call is awkward.
> How about we defer virtio_set_features until FEATURES_OK,
> and teach virtio_set_features that it can fail?

Hm. But we would need to keep virtio_set_features() where it is called
now for legacy devices, as they will never see FEATURES_OK, right? So
we need to make this depending on revisions (or whatever the equivalent
is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
this makes the code easier to follow.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features
  2014-12-28  8:32     ` Michael S. Tsirkin
@ 2015-01-07 16:22       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-07 16:22 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Sun, 28 Dec 2014 10:32:06 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > Devices may support different sets of feature bits depending on which
> > revision they're operating at. Let's give the transport a way to
> > re-query the device about its features when the revision has been
> > changed.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> So now we have both get_features and get_features_rev, and
> it's never clear which revision does host_features refer to.
> IMHO that's just too messy.
> Let's add get_legacy_features and host_legacy_features instead?

I wanted to avoid touching anything that does not support version 1.
And this interface might still work for later revisions, no?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 18/20] virtio: support revision-specific features
@ 2015-01-07 16:22       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-07 16:22 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Sun, 28 Dec 2014 10:32:06 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > Devices may support different sets of feature bits depending on which
> > revision they're operating at. Let's give the transport a way to
> > re-query the device about its features when the revision has been
> > changed.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> So now we have both get_features and get_features_rev, and
> it's never clear which revision does host_features refer to.
> IMHO that's just too messy.
> Let's add get_legacy_features and host_legacy_features instead?

I wanted to avoid touching anything that does not support version 1.
And this interface might still work for later revisions, no?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
  2014-12-28 10:24     ` Michael S. Tsirkin
  (?)
  (?)
@ 2015-01-07 16:29     ` Cornelia Huck
  2015-01-07 19:11         ` Michael S. Tsirkin
  -1 siblings, 1 reply; 164+ messages in thread
From: Cornelia Huck @ 2015-01-07 16:29 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Sun, 28 Dec 2014 12:24:46 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> > Wire up virtio-blk to provide different feature bit sets depending
> > on whether legacy or v1.0 has been requested.
> > 
> > Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> So we need some way for devices to tell transports
> not to negotiate rev 1.
> Does clearing VERSION_1 have this effect?
> 
I just noticed that my patch is running in circles here.

What we need is probably the transport-dependent maximum revision
checker (which at least for ccw is acting on a device) pass in the
requested revision and check if the feature bits for the revision
include VERSION_1. Does that make sense?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
  2014-12-28 10:24     ` Michael S. Tsirkin
  (?)
@ 2015-01-07 16:29     ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-07 16:29 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Sun, 28 Dec 2014 12:24:46 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> > Wire up virtio-blk to provide different feature bit sets depending
> > on whether legacy or v1.0 has been requested.
> > 
> > Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> 
> So we need some way for devices to tell transports
> not to negotiate rev 1.
> Does clearing VERSION_1 have this effect?
> 
I just noticed that my patch is running in circles here.

What we need is probably the transport-dependent maximum revision
checker (which at least for ccw is acting on a device) pass in the
requested revision and check if the feature bits for the revision
include VERSION_1. Does that make sense?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 13/20] virtio: allow to fail setting status
  2015-01-07 16:13       ` Cornelia Huck
@ 2015-01-07 19:08         ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-07 19:08 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Wed, Jan 07, 2015 at 05:13:32PM +0100, Cornelia Huck wrote:
> On Tue, 30 Dec 2014 14:25:37 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > > the negotiated feature bits are inconsistent: let's fail
> > > virtio_set_status() in that case and update virtio-ccw to post an
> > > error to the guest.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > 
> > Right but a separate validate_features call is awkward.
> > How about we defer virtio_set_features until FEATURES_OK,
> > and teach virtio_set_features that it can fail?
> 
> Hm. But we would need to keep virtio_set_features() where it is called
> now for legacy devices, as they will never see FEATURES_OK, right?
> So
> we need to make this depending on revisions (or whatever the equivalent
> is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
> this makes the code easier to follow.

So let's make this a separate callback then.
virtio_legacy_set_features?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 13/20] virtio: allow to fail setting status
@ 2015-01-07 19:08         ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-07 19:08 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Wed, Jan 07, 2015 at 05:13:32PM +0100, Cornelia Huck wrote:
> On Tue, 30 Dec 2014 14:25:37 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > > the negotiated feature bits are inconsistent: let's fail
> > > virtio_set_status() in that case and update virtio-ccw to post an
> > > error to the guest.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > 
> > Right but a separate validate_features call is awkward.
> > How about we defer virtio_set_features until FEATURES_OK,
> > and teach virtio_set_features that it can fail?
> 
> Hm. But we would need to keep virtio_set_features() where it is called
> now for legacy devices, as they will never see FEATURES_OK, right?
> So
> we need to make this depending on revisions (or whatever the equivalent
> is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
> this makes the code easier to follow.

So let's make this a separate callback then.
virtio_legacy_set_features?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features
  2015-01-07 16:22       ` Cornelia Huck
@ 2015-01-07 19:10         ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-07 19:10 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> On Sun, 28 Dec 2014 10:32:06 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > Devices may support different sets of feature bits depending on which
> > > revision they're operating at. Let's give the transport a way to
> > > re-query the device about its features when the revision has been
> > > changed.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > 
> > So now we have both get_features and get_features_rev, and
> > it's never clear which revision does host_features refer to.
> > IMHO that's just too messy.
> > Let's add get_legacy_features and host_legacy_features instead?
> 
> I wanted to avoid touching anything that does not support version 1.
> And this interface might still work for later revisions, no?

We can add _modern_ then, or rename host_features to host_legacy_features
everywhere as preparation.

-- 
MST

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 18/20] virtio: support revision-specific features
@ 2015-01-07 19:10         ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-07 19:10 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> On Sun, 28 Dec 2014 10:32:06 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > Devices may support different sets of feature bits depending on which
> > > revision they're operating at. Let's give the transport a way to
> > > re-query the device about its features when the revision has been
> > > changed.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > 
> > So now we have both get_features and get_features_rev, and
> > it's never clear which revision does host_features refer to.
> > IMHO that's just too messy.
> > Let's add get_legacy_features and host_legacy_features instead?
> 
> I wanted to avoid touching anything that does not support version 1.
> And this interface might still work for later revisions, no?

We can add _modern_ then, or rename host_features to host_legacy_features
everywhere as preparation.

-- 
MST

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
  2015-01-07 16:29     ` [Qemu-devel] " Cornelia Huck
@ 2015-01-07 19:11         ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-07 19:11 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Wed, Jan 07, 2015 at 05:29:49PM +0100, Cornelia Huck wrote:
> On Sun, 28 Dec 2014 12:24:46 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> > > Wire up virtio-blk to provide different feature bit sets depending
> > > on whether legacy or v1.0 has been requested.
> > > 
> > > Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > 
> > So we need some way for devices to tell transports
> > not to negotiate rev 1.
> > Does clearing VERSION_1 have this effect?
> > 
> I just noticed that my patch is running in circles here.
> 
> What we need is probably the transport-dependent maximum revision
> checker (which at least for ccw is acting on a device) pass in the
> requested revision and check if the feature bits for the revision
> include VERSION_1. Does that make sense?

Just make devices set 'rev 1 supported' flag?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
@ 2015-01-07 19:11         ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-07 19:11 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Wed, Jan 07, 2015 at 05:29:49PM +0100, Cornelia Huck wrote:
> On Sun, 28 Dec 2014 12:24:46 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> > > Wire up virtio-blk to provide different feature bit sets depending
> > > on whether legacy or v1.0 has been requested.
> > > 
> > > Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > 
> > So we need some way for devices to tell transports
> > not to negotiate rev 1.
> > Does clearing VERSION_1 have this effect?
> > 
> I just noticed that my patch is running in circles here.
> 
> What we need is probably the transport-dependent maximum revision
> checker (which at least for ccw is acting on a device) pass in the
> requested revision and check if the feature bits for the revision
> include VERSION_1. Does that make sense?

Just make devices set 'rev 1 supported' flag?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 13/20] virtio: allow to fail setting status
  2015-01-07 19:08         ` Michael S. Tsirkin
@ 2015-01-08  7:20           ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-08  7:20 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Wed, 7 Jan 2015 21:08:21 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 07, 2015 at 05:13:32PM +0100, Cornelia Huck wrote:
> > On Tue, 30 Dec 2014 14:25:37 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > > > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > > > the negotiated feature bits are inconsistent: let's fail
> > > > virtio_set_status() in that case and update virtio-ccw to post an
> > > > error to the guest.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > 
> > > Right but a separate validate_features call is awkward.
> > > How about we defer virtio_set_features until FEATURES_OK,
> > > and teach virtio_set_features that it can fail?
> > 
> > Hm. But we would need to keep virtio_set_features() where it is called
> > now for legacy devices, as they will never see FEATURES_OK, right?
> > So
> > we need to make this depending on revisions (or whatever the equivalent
> > is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
> > this makes the code easier to follow.
> 
> So let's make this a separate callback then.
> virtio_legacy_set_features?

I'm not sure I like that. We'd need to touch every transport, right?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 13/20] virtio: allow to fail setting status
@ 2015-01-08  7:20           ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-08  7:20 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Wed, 7 Jan 2015 21:08:21 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 07, 2015 at 05:13:32PM +0100, Cornelia Huck wrote:
> > On Tue, 30 Dec 2014 14:25:37 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > > > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > > > the negotiated feature bits are inconsistent: let's fail
> > > > virtio_set_status() in that case and update virtio-ccw to post an
> > > > error to the guest.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > 
> > > Right but a separate validate_features call is awkward.
> > > How about we defer virtio_set_features until FEATURES_OK,
> > > and teach virtio_set_features that it can fail?
> > 
> > Hm. But we would need to keep virtio_set_features() where it is called
> > now for legacy devices, as they will never see FEATURES_OK, right?
> > So
> > we need to make this depending on revisions (or whatever the equivalent
> > is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
> > this makes the code easier to follow.
> 
> So let's make this a separate callback then.
> virtio_legacy_set_features?

I'm not sure I like that. We'd need to touch every transport, right?

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 13/20] virtio: allow to fail setting status
  2015-01-08  7:20           ` Cornelia Huck
@ 2015-01-08  8:09             ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-08  8:09 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Thu, Jan 08, 2015 at 08:20:37AM +0100, Cornelia Huck wrote:
> On Wed, 7 Jan 2015 21:08:21 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Jan 07, 2015 at 05:13:32PM +0100, Cornelia Huck wrote:
> > > On Tue, 30 Dec 2014 14:25:37 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > > > > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > > > > the negotiated feature bits are inconsistent: let's fail
> > > > > virtio_set_status() in that case and update virtio-ccw to post an
> > > > > error to the guest.
> > > > > 
> > > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > 
> > > > Right but a separate validate_features call is awkward.
> > > > How about we defer virtio_set_features until FEATURES_OK,
> > > > and teach virtio_set_features that it can fail?
> > > 
> > > Hm. But we would need to keep virtio_set_features() where it is called
> > > now for legacy devices, as they will never see FEATURES_OK, right?
> > > So
> > > we need to make this depending on revisions (or whatever the equivalent
> > > is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
> > > this makes the code easier to follow.
> > 
> > So let's make this a separate callback then.
> > virtio_legacy_set_features?
> 
> I'm not sure I like that. We'd need to touch every transport, right?

Yes but there aren't so many.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 13/20] virtio: allow to fail setting status
@ 2015-01-08  8:09             ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-08  8:09 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Thu, Jan 08, 2015 at 08:20:37AM +0100, Cornelia Huck wrote:
> On Wed, 7 Jan 2015 21:08:21 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Jan 07, 2015 at 05:13:32PM +0100, Cornelia Huck wrote:
> > > On Tue, 30 Dec 2014 14:25:37 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Thu, Dec 11, 2014 at 02:25:15PM +0100, Cornelia Huck wrote:
> > > > > virtio-1 allow setting of the FEATURES_OK status bit to fail if
> > > > > the negotiated feature bits are inconsistent: let's fail
> > > > > virtio_set_status() in that case and update virtio-ccw to post an
> > > > > error to the guest.
> > > > > 
> > > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > 
> > > > Right but a separate validate_features call is awkward.
> > > > How about we defer virtio_set_features until FEATURES_OK,
> > > > and teach virtio_set_features that it can fail?
> > > 
> > > Hm. But we would need to keep virtio_set_features() where it is called
> > > now for legacy devices, as they will never see FEATURES_OK, right?
> > > So
> > > we need to make this depending on revisions (or whatever the equivalent
> > > is for pci/mmio), as we cannot check for VERSION_1. Not sure whether
> > > this makes the code easier to follow.
> > 
> > So let's make this a separate callback then.
> > virtio_legacy_set_features?
> 
> I'm not sure I like that. We'd need to touch every transport, right?

Yes but there aren't so many.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 10:29     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 10:29 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 564 bytes --]

On Thu, Dec 11, 2014 at 02:25:08PM +0100, Cornelia Huck wrote:
> Add code that checks for the VERSION_1 feature bit in order to make
> decisions about the device's endianness. This allows us to support
> transitional devices.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio.c                |    6 +++++-
>  include/hw/virtio/virtio-access.h |    4 ++++
>  include/hw/virtio/virtio.h        |    8 ++++++--
>  3 files changed, 15 insertions(+), 3 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
@ 2015-01-20 10:29     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 10:29 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 564 bytes --]

On Thu, Dec 11, 2014 at 02:25:08PM +0100, Cornelia Huck wrote:
> Add code that checks for the VERSION_1 feature bit in order to make
> decisions about the device's endianness. This allows us to support
> transitional devices.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio.c                |    6 +++++-
>  include/hw/virtio/virtio-access.h |    4 ++++
>  include/hw/virtio/virtio.h        |    8 ++++++--
>  3 files changed, 15 insertions(+), 3 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 10:43     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 10:43 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 2013 bytes --]

On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
> Handle endianness conversion for virtio-1 virtqueues correctly.
> 
> Note that dataplane now needs to be built per-target.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/block/dataplane/virtio-blk.c               |    4 +-
>  hw/scsi/virtio-scsi-dataplane.c               |    2 +-
>  hw/virtio/Makefile.objs                       |    2 +-
>  hw/virtio/dataplane/Makefile.objs             |    2 +-
>  hw/virtio/dataplane/vring.c                   |   86 ++++++++++++++-----------
>  include/hw/virtio/dataplane/vring-accessors.h |   75 +++++++++++++++++++++
>  include/hw/virtio/dataplane/vring.h           |   14 +---
>  7 files changed, 131 insertions(+), 54 deletions(-)
>  create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

This patch is independent of VIRTIO 1.0 and can be merged separately
(faster).

> diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
> index 1222a37..2d8cc15 100644
> --- a/hw/block/dataplane/virtio-blk.c
> +++ b/hw/block/dataplane/virtio-blk.c
> @@ -16,7 +16,9 @@
>  #include "qemu/iov.h"
>  #include "qemu/thread.h"
>  #include "qemu/error-report.h"
> +#include "hw/virtio/virtio-access.h"
>  #include "hw/virtio/dataplane/vring.h"
> +#include "hw/virtio/dataplane/vring-accessors.h"

I like your vring-accessors.h approach better than the inline
virtio_ld/st_p() in my patch.  Nice.

> @@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
>  }
>  
>  
> -static int get_desc(Vring *vring, VirtQueueElement *elem,
> +static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
>                      struct vring_desc *desc)

Since we copy in struct vring_desc anyway, it's cleaner to byteswap the
fields once instead of remembering to do it each time we need to access
a field.  The copy_in_vring_desc() function is one thing I prefer I
about my patch.

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
@ 2015-01-20 10:43     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 10:43 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 2013 bytes --]

On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
> Handle endianness conversion for virtio-1 virtqueues correctly.
> 
> Note that dataplane now needs to be built per-target.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/block/dataplane/virtio-blk.c               |    4 +-
>  hw/scsi/virtio-scsi-dataplane.c               |    2 +-
>  hw/virtio/Makefile.objs                       |    2 +-
>  hw/virtio/dataplane/Makefile.objs             |    2 +-
>  hw/virtio/dataplane/vring.c                   |   86 ++++++++++++++-----------
>  include/hw/virtio/dataplane/vring-accessors.h |   75 +++++++++++++++++++++
>  include/hw/virtio/dataplane/vring.h           |   14 +---
>  7 files changed, 131 insertions(+), 54 deletions(-)
>  create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

This patch is independent of VIRTIO 1.0 and can be merged separately
(faster).

> diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
> index 1222a37..2d8cc15 100644
> --- a/hw/block/dataplane/virtio-blk.c
> +++ b/hw/block/dataplane/virtio-blk.c
> @@ -16,7 +16,9 @@
>  #include "qemu/iov.h"
>  #include "qemu/thread.h"
>  #include "qemu/error-report.h"
> +#include "hw/virtio/virtio-access.h"
>  #include "hw/virtio/dataplane/vring.h"
> +#include "hw/virtio/dataplane/vring-accessors.h"

I like your vring-accessors.h approach better than the inline
virtio_ld/st_p() in my patch.  Nice.

> @@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
>  }
>  
>  
> -static int get_desc(Vring *vring, VirtQueueElement *elem,
> +static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
>                      struct vring_desc *desc)

Since we copy in struct vring_desc anyway, it's cleaner to byteswap the
fields once instead of remembering to do it each time we need to access
a field.  The copy_in_vring_desc() function is one thing I prefer I
about my patch.

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 09/20] s390x/css: Add a callback for when subchannel gets disabled
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 10:50     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 10:50 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 521 bytes --]

On Thu, Dec 11, 2014 at 02:25:11PM +0100, Cornelia Huck wrote:
> From: Thomas Huth <thuth@linux.vnet.ibm.com>
> 
> We need a possibility to run code when a subchannel gets disabled.
> This patch adds the necessary infrastructure.
> 
> Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/css.c |   12 ++++++++++++
>  hw/s390x/css.h |    1 +
>  2 files changed, 13 insertions(+)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 09/20] s390x/css: Add a callback for when subchannel gets disabled
@ 2015-01-20 10:50     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 10:50 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 521 bytes --]

On Thu, Dec 11, 2014 at 02:25:11PM +0100, Cornelia Huck wrote:
> From: Thomas Huth <thuth@linux.vnet.ibm.com>
> 
> We need a possibility to run code when a subchannel gets disabled.
> This patch adds the necessary infrastructure.
> 
> Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/css.c |   12 ++++++++++++
>  hw/s390x/css.h |    1 +
>  2 files changed, 13 insertions(+)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 11:00     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:00 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 948 bytes --]

On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> From: Thomas Huth <thuth@linux.vnet.ibm.com>
> 
> Handle the virtio-ccw revision according to what the guest sets.
> When revision 1 is selected, we have a virtio-1 standard device
> with byteswapping for the virtio rings.
> 
> When a channel gets disabled, we have to revert to the legacy behavior
> in case the next user of the device does not negotiate the revision 1
> anymore (e.g. the boot firmware uses revision 1, but the operating
> system only uses the legacy mode).
> 
> Note that revisions > 0 are still disabled.
> 
> Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/virtio-ccw.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/s390x/virtio-ccw.h |    8 ++++++++
>  2 files changed, 60 insertions(+)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
@ 2015-01-20 11:00     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:00 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 948 bytes --]

On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> From: Thomas Huth <thuth@linux.vnet.ibm.com>
> 
> Handle the virtio-ccw revision according to what the guest sets.
> When revision 1 is selected, we have a virtio-1 standard device
> with byteswapping for the virtio rings.
> 
> When a channel gets disabled, we have to revert to the legacy behavior
> in case the next user of the device does not negotiate the revision 1
> anymore (e.g. the boot firmware uses revision 1, but the operating
> system only uses the legacy mode).
> 
> Note that revisions > 0 are still disabled.
> 
> Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/virtio-ccw.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/s390x/virtio-ccw.h |    8 ++++++++
>  2 files changed, 60 insertions(+)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 11/20] s390x/virtio-ccw: support virtio-1 set_vq format
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 11:06     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:06 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 577 bytes --]

On Thu, Dec 11, 2014 at 02:25:13PM +0100, Cornelia Huck wrote:
> Support the new CCW_CMD_SET_VQ format for virtio-1 devices.
> 
> While we're at it, refactor the code a bit and enforce big endian
> fields (which had always been required, even for legacy).
> 
> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/virtio-ccw.c |  114 ++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 80 insertions(+), 34 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 11/20] s390x/virtio-ccw: support virtio-1 set_vq format
@ 2015-01-20 11:06     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:06 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 577 bytes --]

On Thu, Dec 11, 2014 at 02:25:13PM +0100, Cornelia Huck wrote:
> Support the new CCW_CMD_SET_VQ format for virtio-1 devices.
> 
> While we're at it, refactor the code a bit and enforce big endian
> fields (which had always been required, even for legacy).
> 
> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/virtio-ccw.c |  114 ++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 80 insertions(+), 34 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 11:08     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:08 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 945 bytes --]

On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>              }
>          }
>          break;
> +    case CCW_CMD_SET_VIRTIO_REV:
> +        len = sizeof(revinfo);
> +        if (ccw.count < len || (check_len && ccw.count > len)) {
> +            ret = -EINVAL;
> +            break;
> +        }
> +        if (!ccw.cda) {
> +            ret = -EFAULT;
> +            break;
> +        }
> +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> +        if (dev->revision >= 0 ||
> +            revinfo.revision > virtio_ccw_rev_max(dev)) {

In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
access functions to load a struct from guest memory.

Here you just copy the struct in without byteswaps.

Are the byteswaps missing here?  (I guess this normally runs big-endian
guests on big-endian hosts so it's not noticable.)

Stefan

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
@ 2015-01-20 11:08     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:08 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 945 bytes --]

On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
>              }
>          }
>          break;
> +    case CCW_CMD_SET_VIRTIO_REV:
> +        len = sizeof(revinfo);
> +        if (ccw.count < len || (check_len && ccw.count > len)) {
> +            ret = -EINVAL;
> +            break;
> +        }
> +        if (!ccw.cda) {
> +            ret = -EFAULT;
> +            break;
> +        }
> +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> +        if (dev->revision >= 0 ||
> +            revinfo.revision > virtio_ccw_rev_max(dev)) {

In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
access functions to load a struct from guest memory.

Here you just copy the struct in without byteswaps.

Are the byteswaps missing here?  (I guess this normally runs big-endian
guests on big-endian hosts so it's not noticable.)

Stefan

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
  2014-12-12 11:25         ` Thomas Huth
@ 2015-01-20 11:14           ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:14 UTC (permalink / raw)
  To: Thomas Huth; +Cc: Cornelia Huck, virtualization, qemu-devel, mst

[-- Attachment #1: Type: text/plain, Size: 2035 bytes --]

On Fri, Dec 12, 2014 at 12:25:47PM +0100, Thomas Huth wrote:
> On Fri, 12 Dec 2014 12:18:25 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > On Fri, 12 Dec 2014 11:55:38 +0100
> > Thomas Huth <thuth@linux.vnet.ibm.com> wrote:
> > 
> > > On Thu, 11 Dec 2014 14:25:14 +0100
> > > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> > > 
> > > > For virtio-1 devices, the driver must not attempt to set feature bits
> > > > after it set FEATURES_OK in the device status. Simply reject it in
> > > > that case.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > ---
> > > >  hw/virtio/virtio.c         |   16 ++++++++++++++--
> > > >  include/hw/virtio/virtio.h |    2 ++
> > > >  2 files changed, 16 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > > > index 57190ba..a3dd67b 100644
> > > > --- a/hw/virtio/virtio.c
> > > > +++ b/hw/virtio/virtio.c
> > > > @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> > > >      vmstate_save_state(f, &vmstate_virtio, vdev);
> > > >  }
> > > > 
> > > > -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > > +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > 
> > > Maybe avoid the double underscores here? But unfortunately, I also fail
> > > to come up with a better suggestion for a name here ...
> > 
> > virtio_set_features_nocheck()?
> 
> Sounds ok to me.
> 
> > This function is only called within virtio.c anyway...
> 
> Right, so the double underscores should be ok here, too. (I still do
> not like them very much, but that's just my personal taste in this case)

C99 "7.1.3 Reserved identifiers" says:

  All identifiers that begin with an underscore and either an uppercase
  letter or another underscore are always reserved for any use

[by the standard library]

You can use a trailing underscore or useless word like "do", e.g.
virtio_do_set_features(), for internal functions.

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
@ 2015-01-20 11:14           ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:14 UTC (permalink / raw)
  To: Thomas Huth; +Cc: virtualization, qemu-devel, mst


[-- Attachment #1.1: Type: text/plain, Size: 2035 bytes --]

On Fri, Dec 12, 2014 at 12:25:47PM +0100, Thomas Huth wrote:
> On Fri, 12 Dec 2014 12:18:25 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > On Fri, 12 Dec 2014 11:55:38 +0100
> > Thomas Huth <thuth@linux.vnet.ibm.com> wrote:
> > 
> > > On Thu, 11 Dec 2014 14:25:14 +0100
> > > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> > > 
> > > > For virtio-1 devices, the driver must not attempt to set feature bits
> > > > after it set FEATURES_OK in the device status. Simply reject it in
> > > > that case.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > ---
> > > >  hw/virtio/virtio.c         |   16 ++++++++++++++--
> > > >  include/hw/virtio/virtio.h |    2 ++
> > > >  2 files changed, 16 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > > > index 57190ba..a3dd67b 100644
> > > > --- a/hw/virtio/virtio.c
> > > > +++ b/hw/virtio/virtio.c
> > > > @@ -978,7 +978,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> > > >      vmstate_save_state(f, &vmstate_virtio, vdev);
> > > >  }
> > > > 
> > > > -int virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > > +static int __virtio_set_features(VirtIODevice *vdev, uint64_t val)
> > > 
> > > Maybe avoid the double underscores here? But unfortunately, I also fail
> > > to come up with a better suggestion for a name here ...
> > 
> > virtio_set_features_nocheck()?
> 
> Sounds ok to me.
> 
> > This function is only called within virtio.c anyway...
> 
> Right, so the double underscores should be ok here, too. (I still do
> not like them very much, but that's just my personal taste in this case)

C99 "7.1.3 Reserved identifiers" says:

  All identifiers that begin with an underscore and either an uppercase
  letter or another underscore are always reserved for any use

[by the standard library]

You can use a trailing underscore or useless word like "do", e.g.
virtio_do_set_features(), for internal functions.

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 14/20] s390x/virtio-ccw: enable virtio 1.0
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 11:15     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:15 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 386 bytes --]

On Thu, Dec 11, 2014 at 02:25:16PM +0100, Cornelia Huck wrote:
> virtio-ccw should now have everything in place to operate virtio 1.0
> devices, so let's enable revision 1.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/virtio-ccw.h |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 14/20] s390x/virtio-ccw: enable virtio 1.0
@ 2015-01-20 11:15     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:15 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 386 bytes --]

On Thu, Dec 11, 2014 at 02:25:16PM +0100, Cornelia Huck wrote:
> virtio-ccw should now have everything in place to operate virtio 1.0
> devices, so let's enable revision 1.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/s390x/virtio-ccw.h |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 15/20] virtio-net: no writeable mac for virtio-1
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 11:19     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:19 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 937 bytes --]

On Thu, Dec 11, 2014 at 02:25:17PM +0100, Cornelia Huck wrote:
> Devices operating as virtio 1.0 may not allow writes to the mac
> address in config space.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/net/virtio-net.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index d6d1b98..ebbea60 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -87,6 +87,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
>      memcpy(&netcfg, config, n->config_size);
>  
>      if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&

I don't see VIRTIO_NET_F_CTRL_MAC_ADDR (23) in the VIRTIO 1.0 "5.1.3.1
Legacy Interface: Feature bits" section.  Should it be there just so
people don't try to reuse bit 23 in the future?

The patch itself:
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 15/20] virtio-net: no writeable mac for virtio-1
@ 2015-01-20 11:19     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 11:19 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 937 bytes --]

On Thu, Dec 11, 2014 at 02:25:17PM +0100, Cornelia Huck wrote:
> Devices operating as virtio 1.0 may not allow writes to the mac
> address in config space.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/net/virtio-net.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index d6d1b98..ebbea60 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -87,6 +87,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
>      memcpy(&netcfg, config, n->config_size);
>  
>      if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&

I don't see VIRTIO_NET_F_CTRL_MAC_ADDR (23) in the VIRTIO 1.0 "5.1.3.1
Legacy Interface: Feature bits" section.  Should it be there just so
people don't try to reuse bit 23 in the future?

The patch itself:
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
  2015-01-20 10:43     ` Stefan Hajnoczi
@ 2015-01-20 12:56       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-20 12:56 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 10:43:31 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
> > Handle endianness conversion for virtio-1 virtqueues correctly.
> > 
> > Note that dataplane now needs to be built per-target.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/block/dataplane/virtio-blk.c               |    4 +-
> >  hw/scsi/virtio-scsi-dataplane.c               |    2 +-
> >  hw/virtio/Makefile.objs                       |    2 +-
> >  hw/virtio/dataplane/Makefile.objs             |    2 +-
> >  hw/virtio/dataplane/vring.c                   |   86 ++++++++++++++-----------
> >  include/hw/virtio/dataplane/vring-accessors.h |   75 +++++++++++++++++++++
> >  include/hw/virtio/dataplane/vring.h           |   14 +---
> >  7 files changed, 131 insertions(+), 54 deletions(-)
> >  create mode 100644 include/hw/virtio/dataplane/vring-accessors.h
> 
> This patch is independent of VIRTIO 1.0 and can be merged separately
> (faster).

Yep, I've pulled it in front of my queue.

> 
> > diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
> > index 1222a37..2d8cc15 100644
> > --- a/hw/block/dataplane/virtio-blk.c
> > +++ b/hw/block/dataplane/virtio-blk.c
> > @@ -16,7 +16,9 @@
> >  #include "qemu/iov.h"
> >  #include "qemu/thread.h"
> >  #include "qemu/error-report.h"
> > +#include "hw/virtio/virtio-access.h"
> >  #include "hw/virtio/dataplane/vring.h"
> > +#include "hw/virtio/dataplane/vring-accessors.h"
> 
> I like your vring-accessors.h approach better than the inline
> virtio_ld/st_p() in my patch.  Nice.
> 
> > @@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
> >  }
> >  
> >  
> > -static int get_desc(Vring *vring, VirtQueueElement *elem,
> > +static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
> >                      struct vring_desc *desc)
> 
> Since we copy in struct vring_desc anyway, it's cleaner to byteswap the
> fields once instead of remembering to do it each time we need to access
> a field.  The copy_in_vring_desc() function is one thing I prefer I
> about my patch.

Agreed, that makes the code cleaner.

I've prepared a version of this patch using copy_in_vring_desc() and
I'll post it when it survives some light testing on my side.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
@ 2015-01-20 12:56       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-20 12:56 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 10:43:31 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
> > Handle endianness conversion for virtio-1 virtqueues correctly.
> > 
> > Note that dataplane now needs to be built per-target.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/block/dataplane/virtio-blk.c               |    4 +-
> >  hw/scsi/virtio-scsi-dataplane.c               |    2 +-
> >  hw/virtio/Makefile.objs                       |    2 +-
> >  hw/virtio/dataplane/Makefile.objs             |    2 +-
> >  hw/virtio/dataplane/vring.c                   |   86 ++++++++++++++-----------
> >  include/hw/virtio/dataplane/vring-accessors.h |   75 +++++++++++++++++++++
> >  include/hw/virtio/dataplane/vring.h           |   14 +---
> >  7 files changed, 131 insertions(+), 54 deletions(-)
> >  create mode 100644 include/hw/virtio/dataplane/vring-accessors.h
> 
> This patch is independent of VIRTIO 1.0 and can be merged separately
> (faster).

Yep, I've pulled it in front of my queue.

> 
> > diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
> > index 1222a37..2d8cc15 100644
> > --- a/hw/block/dataplane/virtio-blk.c
> > +++ b/hw/block/dataplane/virtio-blk.c
> > @@ -16,7 +16,9 @@
> >  #include "qemu/iov.h"
> >  #include "qemu/thread.h"
> >  #include "qemu/error-report.h"
> > +#include "hw/virtio/virtio-access.h"
> >  #include "hw/virtio/dataplane/vring.h"
> > +#include "hw/virtio/dataplane/vring-accessors.h"
> 
> I like your vring-accessors.h approach better than the inline
> virtio_ld/st_p() in my patch.  Nice.
> 
> > @@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
> >  }
> >  
> >  
> > -static int get_desc(Vring *vring, VirtQueueElement *elem,
> > +static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
> >                      struct vring_desc *desc)
> 
> Since we copy in struct vring_desc anyway, it's cleaner to byteswap the
> fields once instead of remembering to do it each time we need to access
> a field.  The copy_in_vring_desc() function is one thing I prefer I
> about my patch.

Agreed, that makes the code cleaner.

I've prepared a version of this patch using copy_in_vring_desc() and
I'll post it when it survives some light testing on my side.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 16/20] virtio-net: support longer header
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-20 13:18     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 13:18 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 627 bytes --]

On Thu, Dec 11, 2014 at 02:25:18PM +0100, Cornelia Huck wrote:
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index ebbea60..7ee2bd6 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -373,15 +373,21 @@ static int peer_has_ufo(VirtIONet *n)
>      return n->has_ufo;
>  }
>  
> -static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
> +static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
> +                                       int version_1)

Please use bool, it makes it 100% clear what the meaning of "version_1"
is.

s/int/bool/

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 16/20] virtio-net: support longer header
@ 2015-01-20 13:18     ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 13:18 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 627 bytes --]

On Thu, Dec 11, 2014 at 02:25:18PM +0100, Cornelia Huck wrote:
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index ebbea60..7ee2bd6 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -373,15 +373,21 @@ static int peer_has_ufo(VirtIONet *n)
>      return n->has_ufo;
>  }
>  
> -static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
> +static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
> +                                       int version_1)

Please use bool, it makes it 100% clear what the meaning of "version_1"
is.

s/int/bool/

[-- Attachment #1.2: Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
  2015-01-20 12:56       ` Cornelia Huck
@ 2015-01-20 14:47         ` Stefan Hajnoczi
  -1 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 14:47 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Thomas Huth, Michael S. Tsirkin, qemu-devel, Linux Virtualization

On Tue, Jan 20, 2015 at 12:56 PM, Cornelia Huck
<cornelia.huck@de.ibm.com> wrote:
> On Tue, 20 Jan 2015 10:43:31 +0000
> Stefan Hajnoczi <stefanha@gmail.com> wrote:
>> On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
>> > @@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
>> >  }
>> >
>> >
>> > -static int get_desc(Vring *vring, VirtQueueElement *elem,
>> > +static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
>> >                      struct vring_desc *desc)
>>
>> Since we copy in struct vring_desc anyway, it's cleaner to byteswap the
>> fields once instead of remembering to do it each time we need to access
>> a field.  The copy_in_vring_desc() function is one thing I prefer I
>> about my patch.
>
> Agreed, that makes the code cleaner.
>
> I've prepared a version of this patch using copy_in_vring_desc() and
> I'll post it when it survives some light testing on my side.

Cool, thanks for doing this!

Stefan

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
@ 2015-01-20 14:47         ` Stefan Hajnoczi
  0 siblings, 0 replies; 164+ messages in thread
From: Stefan Hajnoczi @ 2015-01-20 14:47 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Thomas Huth, Michael S. Tsirkin, qemu-devel, Linux Virtualization

On Tue, Jan 20, 2015 at 12:56 PM, Cornelia Huck
<cornelia.huck@de.ibm.com> wrote:
> On Tue, 20 Jan 2015 10:43:31 +0000
> Stefan Hajnoczi <stefanha@gmail.com> wrote:
>> On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
>> > @@ -154,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
>> >  }
>> >
>> >
>> > -static int get_desc(Vring *vring, VirtQueueElement *elem,
>> > +static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
>> >                      struct vring_desc *desc)
>>
>> Since we copy in struct vring_desc anyway, it's cleaner to byteswap the
>> fields once instead of remembering to do it each time we need to access
>> a field.  The copy_in_vring_desc() function is one thing I prefer I
>> about my patch.
>
> Agreed, that makes the code cleaner.
>
> I've prepared a version of this patch using copy_in_vring_desc() and
> I'll post it when it survives some light testing on my side.

Cool, thanks for doing this!

Stefan

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
  2015-01-20 11:08     ` Stefan Hajnoczi
@ 2015-01-21 11:23       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-21 11:23 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 11:08:24 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> > @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> >              }
> >          }
> >          break;
> > +    case CCW_CMD_SET_VIRTIO_REV:
> > +        len = sizeof(revinfo);
> > +        if (ccw.count < len || (check_len && ccw.count > len)) {
> > +            ret = -EINVAL;
> > +            break;
> > +        }
> > +        if (!ccw.cda) {
> > +            ret = -EFAULT;
> > +            break;
> > +        }
> > +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> > +        if (dev->revision >= 0 ||
> > +            revinfo.revision > virtio_ccw_rev_max(dev)) {
> 
> In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
> access functions to load a struct from guest memory.
> 
> Here you just copy the struct in without byteswaps.
> 
> Are the byteswaps missing here?  (I guess this normally runs big-endian
> guests on big-endian hosts so it's not noticable.)

Indeed, these are supposed to be big-endian. I'll double check the
other payloads.

Thanks for spotting this!

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
@ 2015-01-21 11:23       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-21 11:23 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 11:08:24 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> > @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> >              }
> >          }
> >          break;
> > +    case CCW_CMD_SET_VIRTIO_REV:
> > +        len = sizeof(revinfo);
> > +        if (ccw.count < len || (check_len && ccw.count > len)) {
> > +            ret = -EINVAL;
> > +            break;
> > +        }
> > +        if (!ccw.cda) {
> > +            ret = -EFAULT;
> > +            break;
> > +        }
> > +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> > +        if (dev->revision >= 0 ||
> > +            revinfo.revision > virtio_ccw_rev_max(dev)) {
> 
> In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
> access functions to load a struct from guest memory.
> 
> Here you just copy the struct in without byteswaps.
> 
> Are the byteswaps missing here?  (I guess this normally runs big-endian
> guests on big-endian hosts so it's not noticable.)

Indeed, these are supposed to be big-endian. I'll double check the
other payloads.

Thanks for spotting this!

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
  2015-01-21 11:23       ` Cornelia Huck
@ 2015-01-21 11:51         ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2015-01-21 11:51 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: Stefan Hajnoczi, virtualization, qemu-devel, mst

On Wed, 21 Jan 2015 12:23:18 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> On Tue, 20 Jan 2015 11:08:24 +0000
> Stefan Hajnoczi <stefanha@gmail.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> > > @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> > >              }
> > >          }
> > >          break;
> > > +    case CCW_CMD_SET_VIRTIO_REV:
> > > +        len = sizeof(revinfo);
> > > +        if (ccw.count < len || (check_len && ccw.count > len)) {
> > > +            ret = -EINVAL;
> > > +            break;
> > > +        }
> > > +        if (!ccw.cda) {
> > > +            ret = -EFAULT;
> > > +            break;
> > > +        }
> > > +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> > > +        if (dev->revision >= 0 ||
> > > +            revinfo.revision > virtio_ccw_rev_max(dev)) {
> > 
> > In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
> > access functions to load a struct from guest memory.
> > 
> > Here you just copy the struct in without byteswaps.
> > 
> > Are the byteswaps missing here?  (I guess this normally runs big-endian
> > guests on big-endian hosts so it's not noticable.)
> 
> Indeed, these are supposed to be big-endian. I'll double check the
> other payloads.

Right. Cornelia, can you take care of this or shall I rework the patch?

NB: Actually, there are a couple of "XXX config space endianness"
comments in that virtio_ccw_cb() function, so there are likely a bunch
of problems when this code should be run on little endian hosts one day.
So far, this code only runs with big-endian guests on big-endian hosts
since the virtio-ccw machine is currently KVM-only as far as I know,
that's likely why nobody complained about this yet.

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
@ 2015-01-21 11:51         ` Thomas Huth
  0 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2015-01-21 11:51 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: virtualization, qemu-devel, mst

On Wed, 21 Jan 2015 12:23:18 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> On Tue, 20 Jan 2015 11:08:24 +0000
> Stefan Hajnoczi <stefanha@gmail.com> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> > > @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> > >              }
> > >          }
> > >          break;
> > > +    case CCW_CMD_SET_VIRTIO_REV:
> > > +        len = sizeof(revinfo);
> > > +        if (ccw.count < len || (check_len && ccw.count > len)) {
> > > +            ret = -EINVAL;
> > > +            break;
> > > +        }
> > > +        if (!ccw.cda) {
> > > +            ret = -EFAULT;
> > > +            break;
> > > +        }
> > > +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> > > +        if (dev->revision >= 0 ||
> > > +            revinfo.revision > virtio_ccw_rev_max(dev)) {
> > 
> > In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
> > access functions to load a struct from guest memory.
> > 
> > Here you just copy the struct in without byteswaps.
> > 
> > Are the byteswaps missing here?  (I guess this normally runs big-endian
> > guests on big-endian hosts so it's not noticable.)
> 
> Indeed, these are supposed to be big-endian. I'll double check the
> other payloads.

Right. Cornelia, can you take care of this or shall I rework the patch?

NB: Actually, there are a couple of "XXX config space endianness"
comments in that virtio_ccw_cb() function, so there are likely a bunch
of problems when this code should be run on little endian hosts one day.
So far, this code only runs with big-endian guests on big-endian hosts
since the virtio-ccw machine is currently KVM-only as far as I know,
that's likely why nobody complained about this yet.

 Thomas

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
  2015-01-21 11:51         ` Thomas Huth
@ 2015-01-21 12:39           ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-21 12:39 UTC (permalink / raw)
  To: Thomas Huth; +Cc: Stefan Hajnoczi, virtualization, qemu-devel, mst

On Wed, 21 Jan 2015 12:51:41 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:

> On Wed, 21 Jan 2015 12:23:18 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > On Tue, 20 Jan 2015 11:08:24 +0000
> > Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> > > > @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> > > >              }
> > > >          }
> > > >          break;
> > > > +    case CCW_CMD_SET_VIRTIO_REV:
> > > > +        len = sizeof(revinfo);
> > > > +        if (ccw.count < len || (check_len && ccw.count > len)) {
> > > > +            ret = -EINVAL;
> > > > +            break;
> > > > +        }
> > > > +        if (!ccw.cda) {
> > > > +            ret = -EFAULT;
> > > > +            break;
> > > > +        }
> > > > +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> > > > +        if (dev->revision >= 0 ||
> > > > +            revinfo.revision > virtio_ccw_rev_max(dev)) {
> > > 
> > > In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
> > > access functions to load a struct from guest memory.
> > > 
> > > Here you just copy the struct in without byteswaps.
> > > 
> > > Are the byteswaps missing here?  (I guess this normally runs big-endian
> > > guests on big-endian hosts so it's not noticable.)
> > 
> > Indeed, these are supposed to be big-endian. I'll double check the
> > other payloads.
> 
> Right. Cornelia, can you take care of this or shall I rework the patch?

Currently already working on a patch :)

> NB: Actually, there are a couple of "XXX config space endianness"
> comments in that virtio_ccw_cb() function, so there are likely a bunch
> of problems when this code should be run on little endian hosts one day.
> So far, this code only runs with big-endian guests on big-endian hosts
> since the virtio-ccw machine is currently KVM-only as far as I know,
> that's likely why nobody complained about this yet.

The transport can't take care of the config space endianness, this
needs to be done by the individual devices. Probably best to simply
ditch the comments.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call
@ 2015-01-21 12:39           ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-21 12:39 UTC (permalink / raw)
  To: Thomas Huth; +Cc: virtualization, qemu-devel, mst

On Wed, 21 Jan 2015 12:51:41 +0100
Thomas Huth <thuth@linux.vnet.ibm.com> wrote:

> On Wed, 21 Jan 2015 12:23:18 +0100
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> 
> > On Tue, 20 Jan 2015 11:08:24 +0000
> > Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:12PM +0100, Cornelia Huck wrote:
> > > > @@ -608,6 +631,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
> > > >              }
> > > >          }
> > > >          break;
> > > > +    case CCW_CMD_SET_VIRTIO_REV:
> > > > +        len = sizeof(revinfo);
> > > > +        if (ccw.count < len || (check_len && ccw.count > len)) {
> > > > +            ret = -EINVAL;
> > > > +            break;
> > > > +        }
> > > > +        if (!ccw.cda) {
> > > > +            ret = -EFAULT;
> > > > +            break;
> > > > +        }
> > > > +        cpu_physical_memory_read(ccw.cda, &revinfo, len);
> > > > +        if (dev->revision >= 0 ||
> > > > +            revinfo.revision > virtio_ccw_rev_max(dev)) {
> > > 
> > > In the next patch virtio_ccw_handle_set_vq() uses big-endian memory
> > > access functions to load a struct from guest memory.
> > > 
> > > Here you just copy the struct in without byteswaps.
> > > 
> > > Are the byteswaps missing here?  (I guess this normally runs big-endian
> > > guests on big-endian hosts so it's not noticable.)
> > 
> > Indeed, these are supposed to be big-endian. I'll double check the
> > other payloads.
> 
> Right. Cornelia, can you take care of this or shall I rework the patch?

Currently already working on a patch :)

> NB: Actually, there are a couple of "XXX config space endianness"
> comments in that virtio_ccw_cb() function, so there are likely a bunch
> of problems when this code should be run on little endian hosts one day.
> So far, this code only runs with big-endian guests on big-endian hosts
> since the virtio-ccw machine is currently KVM-only as far as I know,
> that's likely why nobody complained about this yet.

The transport can't take care of the config space endianness, this
needs to be done by the individual devices. Probably best to simply
ditch the comments.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 16/20] virtio-net: support longer header
  2015-01-20 13:18     ` Stefan Hajnoczi
@ 2015-01-21 16:06       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-21 16:06 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 13:18:14 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:18PM +0100, Cornelia Huck wrote:
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index ebbea60..7ee2bd6 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -373,15 +373,21 @@ static int peer_has_ufo(VirtIONet *n)
> >      return n->has_ufo;
> >  }
> >  
> > -static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
> > +static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
> > +                                       int version_1)
> 
> Please use bool, it makes it 100% clear what the meaning of "version_1"
> is.
> 
> s/int/bool/

OK, will change.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 16/20] virtio-net: support longer header
@ 2015-01-21 16:06       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-21 16:06 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 13:18:14 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:18PM +0100, Cornelia Huck wrote:
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index ebbea60..7ee2bd6 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -373,15 +373,21 @@ static int peer_has_ufo(VirtIONet *n)
> >      return n->has_ufo;
> >  }
> >  
> > -static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
> > +static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
> > +                                       int version_1)
> 
> Please use bool, it makes it 100% clear what the meaning of "version_1"
> is.
> 
> s/int/bool/

OK, will change.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 02/20] virtio: cull virtio_bus_set_vdev_features
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-22  1:24     ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:24 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 653 bytes --]

On Thu, Dec 11, 2014 at 02:25:04PM +0100, Cornelia Huck wrote:
> The only user of this function was virtio-ccw, and it should use
> virtio_set_features() like everybody else: We need to make sure
> that bad features are masked out properly, which this function did
> not do.
> 
> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 02/20] virtio: cull virtio_bus_set_vdev_features
@ 2015-01-22  1:24     ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:24 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 653 bytes --]

On Thu, Dec 11, 2014 at 02:25:04PM +0100, Cornelia Huck wrote:
> The only user of this function was virtio-ccw, and it should use
> virtio_set_features() like everybody else: We need to make sure
> that bad features are masked out properly, which this function did
> not do.
> 
> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 03/20] virtio: feature bit manipulation helpers
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-22  1:25     ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:25 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 763 bytes --]

On Thu, Dec 11, 2014 at 02:25:05PM +0100, Cornelia Huck wrote:
> Add virtio_{add,clear}_feature helper functions for manipulating a
> feature bits variable. This has some benefits over open coding:
> - add check that the bit is in a sane range
> - make it obvious at a glance what is going on
> - have a central point to change when we want to extend feature bits
> 
> Convert existing code manipulating features to use the new helpers.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 03/20] virtio: feature bit manipulation helpers
@ 2015-01-22  1:25     ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:25 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 763 bytes --]

On Thu, Dec 11, 2014 at 02:25:05PM +0100, Cornelia Huck wrote:
> Add virtio_{add,clear}_feature helper functions for manipulating a
> feature bits variable. This has some benefits over open coding:
> - add check that the bit is in a sane range
> - make it obvious at a glance what is going on
> - have a central point to change when we want to extend feature bits
> 
> Convert existing code manipulating features to use the new helpers.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 13:25   ` Cornelia Huck
                     ` (3 preceding siblings ...)
  (?)
@ 2015-01-22  1:28   ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:28 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 646 bytes --]

On Thu, Dec 11, 2014 at 02:25:06PM +0100, Cornelia Huck wrote:
> Add a helper function for checking whether a bit is set in the guest
> features for a vdev as well as one that works on a feature bit set.
> 
> Convert code that open-coded this: It cleans up the code and makes it
> easier to extend the guest feature bits.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers
  2014-12-11 13:25   ` Cornelia Huck
                     ` (2 preceding siblings ...)
  (?)
@ 2015-01-22  1:28   ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:28 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 646 bytes --]

On Thu, Dec 11, 2014 at 02:25:06PM +0100, Cornelia Huck wrote:
> Add a helper function for checking whether a bit is set in the guest
> features for a vdev as well as one that works on a feature bit set.
> 
> Convert code that open-coded this: It cleans up the code and makes it
> easier to extend the guest feature bits.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2014-12-12 10:17       ` Cornelia Huck
  (?)
@ 2015-01-22  1:40       ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:40 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, rusty, virtualization, Thomas Huth, mst

[-- Attachment #1: Type: text/plain, Size: 1555 bytes --]

On Fri, Dec 12, 2014 at 11:17:47AM +0100, Cornelia Huck wrote:
> On Fri, 12 Dec 2014 11:06:40 +0100
> Thomas Huth <thuth@linux.vnet.ibm.com> wrote:
> 
> > On Thu, 11 Dec 2014 14:25:07 +0100
> > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
[snip]
> > >      vdev->queue_sel = 0;
> > >      vdev->status = 0;
> > >      vdev->isr = 0;
> > > @@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> > >      qemu_put_8s(f, &vdev->status);
> > >      qemu_put_8s(f, &vdev->isr);
> > >      qemu_put_be16s(f, &vdev->queue_sel);
> > > -    qemu_put_be32s(f, &vdev->guest_features);
> > > +    /* XXX features >= 32 */
> > > +    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);
> > 
> > Casting a uint64_t* to a uint32_t* here sounds very wrong - this likely
> > only works on little endian sytems, but certainly not on big-endian
> > systems.
> > If you do not want to extend this for 64-bit right from the beginning,
> > I think you've got to use a temporary 32-bit variable to get this right.
> 
> Hm... always store the old 32 bits here, then store the new 32 bits
> later? Should be able to get that compatible.

I think Thomas' point is that since vdev->guest_features has changed
to a uint64_t, the "old" bits are now in the second 32-bit half on a
BE system.

Or maybe I'm misunderstanding your reply.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2014-12-12 10:17       ` Cornelia Huck
  (?)
  (?)
@ 2015-01-22  1:40       ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:40 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, virtualization, Thomas Huth, mst


[-- Attachment #1.1: Type: text/plain, Size: 1555 bytes --]

On Fri, Dec 12, 2014 at 11:17:47AM +0100, Cornelia Huck wrote:
> On Fri, 12 Dec 2014 11:06:40 +0100
> Thomas Huth <thuth@linux.vnet.ibm.com> wrote:
> 
> > On Thu, 11 Dec 2014 14:25:07 +0100
> > Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
[snip]
> > >      vdev->queue_sel = 0;
> > >      vdev->status = 0;
> > >      vdev->isr = 0;
> > > @@ -924,7 +925,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> > >      qemu_put_8s(f, &vdev->status);
> > >      qemu_put_8s(f, &vdev->isr);
> > >      qemu_put_be16s(f, &vdev->queue_sel);
> > > -    qemu_put_be32s(f, &vdev->guest_features);
> > > +    /* XXX features >= 32 */
> > > +    qemu_put_be32s(f, (uint32_t *)&vdev->guest_features);
> > 
> > Casting a uint64_t* to a uint32_t* here sounds very wrong - this likely
> > only works on little endian sytems, but certainly not on big-endian
> > systems.
> > If you do not want to extend this for 64-bit right from the beginning,
> > I think you've got to use a temporary 32-bit variable to get this right.
> 
> Hm... always store the old 32 bits here, then store the new 32 bits
> later? Should be able to get that compatible.

I think Thomas' point is that since vdev->guest_features has changed
to a uint64_t, the "old" bits are now in the second 32-bit half on a
BE system.

Or maybe I'm misunderstanding your reply.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-22  1:43     ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:43 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 912 bytes --]

On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> With virtio-1, we support more than 32 feature bits. Let's extend both
> host and guest features to 64, which should suffice for a while.
> 
> vhost and migration have been ignored for now.

[snip]

> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index f6c0379..08141c7 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -55,6 +55,12 @@
>  /* A guest should never accept this.  It implies negotiation is broken. */
>  #define VIRTIO_F_BAD_FEATURE		30
>  
> +/* v1.0 compliant. */
> +#define VIRTIO_F_VERSION_1              32

This is already in the kernel header, isn't it?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2015-01-22  1:43     ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:43 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 912 bytes --]

On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> With virtio-1, we support more than 32 feature bits. Let's extend both
> host and guest features to 64, which should suffice for a while.
> 
> vhost and migration have been ignored for now.

[snip]

> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index f6c0379..08141c7 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -55,6 +55,12 @@
>  /* A guest should never accept this.  It implies negotiation is broken. */
>  #define VIRTIO_F_BAD_FEATURE		30
>  
> +/* v1.0 compliant. */
> +#define VIRTIO_F_VERSION_1              32

This is already in the kernel header, isn't it?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
  2014-12-11 13:25   ` Cornelia Huck
  (?)
  (?)
@ 2015-01-22  1:54   ` David Gibson
  2015-01-23 16:09       ` Greg Kurz
  -1 siblings, 1 reply; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:54 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 3312 bytes --]

On Thu, Dec 11, 2014 at 02:25:08PM +0100, Cornelia Huck wrote:
> Add code that checks for the VERSION_1 feature bit in order to make
> decisions about the device's endianness. This allows us to support
> transitional devices.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio.c                |    6 +++++-
>  include/hw/virtio/virtio-access.h |    4 ++++
>  include/hw/virtio/virtio.h        |    8 ++++++--
>  3 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 7f74ae5..8f69ffa 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -881,7 +881,11 @@ static bool virtio_device_endian_needed(void *opaque)
>      VirtIODevice *vdev = opaque;
>  
>      assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> -    return vdev->device_endian != virtio_default_endian();
> +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        return vdev->device_endian != virtio_default_endian();
> +    }
> +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> +    return vdev->device_endian != VIRTIO_DEVICE_ENDIAN_LITTLE;

This doesn't seem quite right.  Since virtio 1.0 is always LE, this
should just assert that device_endian == LE and return false,
right?

>  }
>  
>  static const VMStateDescription vmstate_virtio_device_endian = {
> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> index 46456fd..ee28c21 100644
> --- a/include/hw/virtio/virtio-access.h
> +++ b/include/hw/virtio/virtio-access.h
> @@ -19,6 +19,10 @@
>  
>  static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
>  {
> +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> +        return false;
> +    }
>  #if defined(TARGET_IS_BIENDIAN)
>      return virtio_is_big_endian(vdev);
>  #elif defined(TARGET_WORDS_BIGENDIAN)
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 08141c7..68c40db 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -297,7 +297,11 @@ static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
>  
>  static inline bool virtio_is_big_endian(VirtIODevice *vdev)
>  {
> -    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> -    return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> +        return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> +    }
> +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> +    return false;
>  }
>  #endif

AFAICT, the only real difference between virtio_is_big_endian() and
virtio_access_is_big_endian() is that the latter will become
compile-time constant on targets that don't do bi-endian.

With virtio 1.0 support, that's no longer true, so those two macros
should just be merged, I think.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
  2014-12-11 13:25   ` Cornelia Huck
                     ` (2 preceding siblings ...)
  (?)
@ 2015-01-22  1:54   ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  1:54 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 3312 bytes --]

On Thu, Dec 11, 2014 at 02:25:08PM +0100, Cornelia Huck wrote:
> Add code that checks for the VERSION_1 feature bit in order to make
> decisions about the device's endianness. This allows us to support
> transitional devices.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio.c                |    6 +++++-
>  include/hw/virtio/virtio-access.h |    4 ++++
>  include/hw/virtio/virtio.h        |    8 ++++++--
>  3 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 7f74ae5..8f69ffa 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -881,7 +881,11 @@ static bool virtio_device_endian_needed(void *opaque)
>      VirtIODevice *vdev = opaque;
>  
>      assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> -    return vdev->device_endian != virtio_default_endian();
> +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        return vdev->device_endian != virtio_default_endian();
> +    }
> +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> +    return vdev->device_endian != VIRTIO_DEVICE_ENDIAN_LITTLE;

This doesn't seem quite right.  Since virtio 1.0 is always LE, this
should just assert that device_endian == LE and return false,
right?

>  }
>  
>  static const VMStateDescription vmstate_virtio_device_endian = {
> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> index 46456fd..ee28c21 100644
> --- a/include/hw/virtio/virtio-access.h
> +++ b/include/hw/virtio/virtio-access.h
> @@ -19,6 +19,10 @@
>  
>  static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
>  {
> +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> +        return false;
> +    }
>  #if defined(TARGET_IS_BIENDIAN)
>      return virtio_is_big_endian(vdev);
>  #elif defined(TARGET_WORDS_BIGENDIAN)
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 08141c7..68c40db 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -297,7 +297,11 @@ static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
>  
>  static inline bool virtio_is_big_endian(VirtIODevice *vdev)
>  {
> -    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> -    return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> +        return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> +    }
> +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> +    return false;
>  }
>  #endif

AFAICT, the only real difference between virtio_is_big_endian() and
virtio_access_is_big_endian() is that the latter will become
compile-time constant on targets that don't do bi-endian.

With virtio 1.0 support, that's no longer true, so those two macros
should just be merged, I think.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
  2014-12-11 13:25   ` Cornelia Huck
  (?)
@ 2015-01-22  2:06   ` David Gibson
  2015-01-28 16:07       ` Cornelia Huck
  -1 siblings, 1 reply; 164+ messages in thread
From: David Gibson @ 2015-01-22  2:06 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 8325 bytes --]

On Thu, Dec 11, 2014 at 02:25:09PM +0100, Cornelia Huck wrote:
> For virtio-1 devices, we allow a more complex queue layout that doesn't
> require descriptor table and rings on a physically-contigous memory area:
> add virtio_queue_set_rings() to allow transports to set this up.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio-mmio.c    |    3 +++
>  hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
>  include/hw/virtio/virtio.h |    3 +++
>  3 files changed, 40 insertions(+), 19 deletions(-)
> 
> diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> index 43b7e02..0c9b63b 100644
> --- a/hw/virtio/virtio-mmio.c
> +++ b/hw/virtio/virtio-mmio.c
> @@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
>      case VIRTIO_MMIO_QUEUENUM:
>          DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
>          virtio_queue_set_num(vdev, vdev->queue_sel, value);
> +        /* Note: only call this function for legacy devices */

It's not clear to me if this is an assertion that this *does* only
call the function for legacy devices or a fixme, that it *should* only
call the function for legacy devices.

> +        virtio_queue_update_rings(vdev, vdev->queue_sel);
>          break;
>      case VIRTIO_MMIO_QUEUEALIGN:
> +        /* Note: this is only valid for legacy devices */
>          virtio_queue_set_align(vdev, vdev->queue_sel, value);
>          break;
>      case VIRTIO_MMIO_QUEUEPFN:
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 8f69ffa..57190ba 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -69,7 +69,6 @@ typedef struct VRing
>  struct VirtQueue
>  {
>      VRing vring;
> -    hwaddr pa;
>      uint16_t last_avail_idx;
>      /* Last used index value we have signalled on */
>      uint16_t signalled_used;
> @@ -92,15 +91,18 @@ struct VirtQueue
>  };
>  
>  /* virt queue functions */
> -static void virtqueue_init(VirtQueue *vq)
> +void virtio_queue_update_rings(VirtIODevice *vdev, int n)

Perhaps something in the name to emphasise that this is only for <v1.0
devices?

>  {
> -    hwaddr pa = vq->pa;
> +    VRing *vring = &vdev->vq[n].vring;
>  
> -    vq->vring.desc = pa;
> -    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
> -    vq->vring.used = vring_align(vq->vring.avail +
> -                                 offsetof(VRingAvail, ring[vq->vring.num]),
> -                                 vq->vring.align);
> +    if (!vring->desc) {
> +        /* not yet setup -> nothing to do */
> +        return;
> +    }
> +    vring->avail = vring->desc + vring->num * sizeof(VRingDesc);
> +    vring->used = vring_align(vring->avail +
> +                              offsetof(VRingAvail, ring[vring->num]),
> +                              vring->align);

Would it make sense to implement this in terms of
virtio_queue_set_rings()?

>  }
>  
>  static inline uint64_t vring_desc_addr(VirtIODevice *vdev, hwaddr desc_pa,
> @@ -605,7 +607,6 @@ void virtio_reset(void *opaque)
>          vdev->vq[i].vring.avail = 0;
>          vdev->vq[i].vring.used = 0;
>          vdev->vq[i].last_avail_idx = 0;
> -        vdev->vq[i].pa = 0;
>          vdev->vq[i].vector = VIRTIO_NO_VECTOR;
>          vdev->vq[i].signalled_used = 0;
>          vdev->vq[i].signalled_used_valid = false;
> @@ -708,13 +709,21 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
>  
>  void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr)
>  {
> -    vdev->vq[n].pa = addr;
> -    virtqueue_init(&vdev->vq[n]);
> +    vdev->vq[n].vring.desc = addr;
> +    virtio_queue_update_rings(vdev, n);
>  }
>  
>  hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n)
>  {
> -    return vdev->vq[n].pa;
> +    return vdev->vq[n].vring.desc;
> +}
> +
> +void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
> +                            hwaddr avail, hwaddr used)
> +{
> +    vdev->vq[n].vring.desc = desc;
> +    vdev->vq[n].vring.avail = avail;
> +    vdev->vq[n].vring.used = used;
>  }
>  
>  void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
> @@ -728,7 +737,6 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
>          return;
>      }
>      vdev->vq[n].vring.num = num;
> -    virtqueue_init(&vdev->vq[n]);
>  }
>  
>  int virtio_queue_get_num(VirtIODevice *vdev, int n)
> @@ -748,6 +756,11 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
>      VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
>  
> +    /* virtio-1 compliant devices cannot change the aligment */
> +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        error_report("tried to modify queue alignment for virtio-1 device");
> +        return;
> +    }
>      /* Check that the transport told us it was going to do this
>       * (so a buggy transport will immediately assert rather than
>       * silently failing to migrate this state)
> @@ -755,7 +768,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>      assert(k->has_variable_vring_alignment);
>  
>      vdev->vq[n].vring.align = align;
> -    virtqueue_init(&vdev->vq[n]);
> +    virtio_queue_update_rings(vdev, n);
>  }
>  
>  void virtio_queue_notify_vq(VirtQueue *vq)
> @@ -949,7 +962,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>          if (k->has_variable_vring_alignment) {
>              qemu_put_be32(f, vdev->vq[i].vring.align);
>          }
> -        qemu_put_be64(f, vdev->vq[i].pa);
> +        /* XXX virtio-1 devices */
> +        qemu_put_be64(f, vdev->vq[i].vring.desc);
>          qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
>          if (k->save_queue) {
>              k->save_queue(qbus->parent, i, f);
> @@ -1044,13 +1058,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>          if (k->has_variable_vring_alignment) {
>              vdev->vq[i].vring.align = qemu_get_be32(f);
>          }
> -        vdev->vq[i].pa = qemu_get_be64(f);
> +        vdev->vq[i].vring.desc = qemu_get_be64(f);
>          qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
>          vdev->vq[i].signalled_used_valid = false;
>          vdev->vq[i].notification = true;
>  
> -        if (vdev->vq[i].pa) {
> -            virtqueue_init(&vdev->vq[i]);
> +        if (vdev->vq[i].vring.desc) {
> +            /* XXX virtio-1 devices */
> +            virtio_queue_update_rings(vdev, i);
>          } else if (vdev->vq[i].last_avail_idx) {
>              error_report("VQ %d address 0x0 "
>                           "inconsistent with Host index 0x%x",
> @@ -1084,7 +1099,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>      }
>  
>      for (i = 0; i < num; i++) {
> -        if (vdev->vq[i].pa) {
> +        if (vdev->vq[i].vring.desc) {
>              uint16_t nheads;
>              nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
>              /* Check it isn't doing strange things with descriptor numbers. */
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 68c40db..b63ced3 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -224,6 +224,9 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr);
>  hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n);
>  void virtio_queue_set_num(VirtIODevice *vdev, int n, int num);
>  int virtio_queue_get_num(VirtIODevice *vdev, int n);
> +void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
> +                            hwaddr avail, hwaddr used);
> +void virtio_queue_update_rings(VirtIODevice *vdev, int n);
>  void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>  void virtio_queue_notify(VirtIODevice *vdev, int n);
>  uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
  2014-12-11 13:25   ` Cornelia Huck
  (?)
  (?)
@ 2015-01-22  2:06   ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  2:06 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 8325 bytes --]

On Thu, Dec 11, 2014 at 02:25:09PM +0100, Cornelia Huck wrote:
> For virtio-1 devices, we allow a more complex queue layout that doesn't
> require descriptor table and rings on a physically-contigous memory area:
> add virtio_queue_set_rings() to allow transports to set this up.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/virtio/virtio-mmio.c    |    3 +++
>  hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
>  include/hw/virtio/virtio.h |    3 +++
>  3 files changed, 40 insertions(+), 19 deletions(-)
> 
> diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> index 43b7e02..0c9b63b 100644
> --- a/hw/virtio/virtio-mmio.c
> +++ b/hw/virtio/virtio-mmio.c
> @@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
>      case VIRTIO_MMIO_QUEUENUM:
>          DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
>          virtio_queue_set_num(vdev, vdev->queue_sel, value);
> +        /* Note: only call this function for legacy devices */

It's not clear to me if this is an assertion that this *does* only
call the function for legacy devices or a fixme, that it *should* only
call the function for legacy devices.

> +        virtio_queue_update_rings(vdev, vdev->queue_sel);
>          break;
>      case VIRTIO_MMIO_QUEUEALIGN:
> +        /* Note: this is only valid for legacy devices */
>          virtio_queue_set_align(vdev, vdev->queue_sel, value);
>          break;
>      case VIRTIO_MMIO_QUEUEPFN:
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 8f69ffa..57190ba 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -69,7 +69,6 @@ typedef struct VRing
>  struct VirtQueue
>  {
>      VRing vring;
> -    hwaddr pa;
>      uint16_t last_avail_idx;
>      /* Last used index value we have signalled on */
>      uint16_t signalled_used;
> @@ -92,15 +91,18 @@ struct VirtQueue
>  };
>  
>  /* virt queue functions */
> -static void virtqueue_init(VirtQueue *vq)
> +void virtio_queue_update_rings(VirtIODevice *vdev, int n)

Perhaps something in the name to emphasise that this is only for <v1.0
devices?

>  {
> -    hwaddr pa = vq->pa;
> +    VRing *vring = &vdev->vq[n].vring;
>  
> -    vq->vring.desc = pa;
> -    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
> -    vq->vring.used = vring_align(vq->vring.avail +
> -                                 offsetof(VRingAvail, ring[vq->vring.num]),
> -                                 vq->vring.align);
> +    if (!vring->desc) {
> +        /* not yet setup -> nothing to do */
> +        return;
> +    }
> +    vring->avail = vring->desc + vring->num * sizeof(VRingDesc);
> +    vring->used = vring_align(vring->avail +
> +                              offsetof(VRingAvail, ring[vring->num]),
> +                              vring->align);

Would it make sense to implement this in terms of
virtio_queue_set_rings()?

>  }
>  
>  static inline uint64_t vring_desc_addr(VirtIODevice *vdev, hwaddr desc_pa,
> @@ -605,7 +607,6 @@ void virtio_reset(void *opaque)
>          vdev->vq[i].vring.avail = 0;
>          vdev->vq[i].vring.used = 0;
>          vdev->vq[i].last_avail_idx = 0;
> -        vdev->vq[i].pa = 0;
>          vdev->vq[i].vector = VIRTIO_NO_VECTOR;
>          vdev->vq[i].signalled_used = 0;
>          vdev->vq[i].signalled_used_valid = false;
> @@ -708,13 +709,21 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
>  
>  void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr)
>  {
> -    vdev->vq[n].pa = addr;
> -    virtqueue_init(&vdev->vq[n]);
> +    vdev->vq[n].vring.desc = addr;
> +    virtio_queue_update_rings(vdev, n);
>  }
>  
>  hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n)
>  {
> -    return vdev->vq[n].pa;
> +    return vdev->vq[n].vring.desc;
> +}
> +
> +void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
> +                            hwaddr avail, hwaddr used)
> +{
> +    vdev->vq[n].vring.desc = desc;
> +    vdev->vq[n].vring.avail = avail;
> +    vdev->vq[n].vring.used = used;
>  }
>  
>  void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
> @@ -728,7 +737,6 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
>          return;
>      }
>      vdev->vq[n].vring.num = num;
> -    virtqueue_init(&vdev->vq[n]);
>  }
>  
>  int virtio_queue_get_num(VirtIODevice *vdev, int n)
> @@ -748,6 +756,11 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>      BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
>      VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
>  
> +    /* virtio-1 compliant devices cannot change the aligment */
> +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> +        error_report("tried to modify queue alignment for virtio-1 device");
> +        return;
> +    }
>      /* Check that the transport told us it was going to do this
>       * (so a buggy transport will immediately assert rather than
>       * silently failing to migrate this state)
> @@ -755,7 +768,7 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>      assert(k->has_variable_vring_alignment);
>  
>      vdev->vq[n].vring.align = align;
> -    virtqueue_init(&vdev->vq[n]);
> +    virtio_queue_update_rings(vdev, n);
>  }
>  
>  void virtio_queue_notify_vq(VirtQueue *vq)
> @@ -949,7 +962,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>          if (k->has_variable_vring_alignment) {
>              qemu_put_be32(f, vdev->vq[i].vring.align);
>          }
> -        qemu_put_be64(f, vdev->vq[i].pa);
> +        /* XXX virtio-1 devices */
> +        qemu_put_be64(f, vdev->vq[i].vring.desc);
>          qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
>          if (k->save_queue) {
>              k->save_queue(qbus->parent, i, f);
> @@ -1044,13 +1058,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>          if (k->has_variable_vring_alignment) {
>              vdev->vq[i].vring.align = qemu_get_be32(f);
>          }
> -        vdev->vq[i].pa = qemu_get_be64(f);
> +        vdev->vq[i].vring.desc = qemu_get_be64(f);
>          qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
>          vdev->vq[i].signalled_used_valid = false;
>          vdev->vq[i].notification = true;
>  
> -        if (vdev->vq[i].pa) {
> -            virtqueue_init(&vdev->vq[i]);
> +        if (vdev->vq[i].vring.desc) {
> +            /* XXX virtio-1 devices */
> +            virtio_queue_update_rings(vdev, i);
>          } else if (vdev->vq[i].last_avail_idx) {
>              error_report("VQ %d address 0x0 "
>                           "inconsistent with Host index 0x%x",
> @@ -1084,7 +1099,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>      }
>  
>      for (i = 0; i < num; i++) {
> -        if (vdev->vq[i].pa) {
> +        if (vdev->vq[i].vring.desc) {
>              uint16_t nheads;
>              nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
>              /* Check it isn't doing strange things with descriptor numbers. */
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 68c40db..b63ced3 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -224,6 +224,9 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr);
>  hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n);
>  void virtio_queue_set_num(VirtIODevice *vdev, int n, int num);
>  int virtio_queue_get_num(VirtIODevice *vdev, int n);
> +void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
> +                            hwaddr avail, hwaddr used);
> +void virtio_queue_update_rings(VirtIODevice *vdev, int n);
>  void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>  void virtio_queue_notify(VirtIODevice *vdev, int n);
>  uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-22  2:12     ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  2:12 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 508 bytes --]

On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
> Handle endianness conversion for virtio-1 virtqueues correctly.
> 
> Note that dataplane now needs to be built per-target.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices
@ 2015-01-22  2:12     ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  2:12 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 508 bytes --]

On Thu, Dec 11, 2014 at 02:25:10PM +0100, Cornelia Huck wrote:
> Handle endianness conversion for virtio-1 virtqueues correctly.
> 
> Note that dataplane now needs to be built per-target.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
  2014-12-11 13:25   ` Cornelia Huck
@ 2015-01-22  2:15     ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  2:15 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, mst, qemu-devel, virtualization

[-- Attachment #1: Type: text/plain, Size: 539 bytes --]

On Thu, Dec 11, 2014 at 02:25:14PM +0100, Cornelia Huck wrote:
> For virtio-1 devices, the driver must not attempt to set feature bits
> after it set FEATURES_OK in the device status. Simply reject it in
> that case.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1
@ 2015-01-22  2:15     ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-22  2:15 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 539 bytes --]

On Thu, Dec 11, 2014 at 02:25:14PM +0100, Cornelia Huck wrote:
> For virtio-1 devices, the driver must not attempt to set feature bits
> after it set FEATURES_OK in the device status. Simply reject it in
> that case.
> 
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 15/20] virtio-net: no writeable mac for virtio-1
  2015-01-20 11:19     ` Stefan Hajnoczi
@ 2015-01-22 16:31       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-22 16:31 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 11:19:47 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:17PM +0100, Cornelia Huck wrote:
> > Devices operating as virtio 1.0 may not allow writes to the mac
> > address in config space.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/net/virtio-net.c |    1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index d6d1b98..ebbea60 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -87,6 +87,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
> >      memcpy(&netcfg, config, n->config_size);
> >  
> >      if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
> 
> I don't see VIRTIO_NET_F_CTRL_MAC_ADDR (23) in the VIRTIO 1.0 "5.1.3.1
> Legacy Interface: Feature bits" section.  Should it be there just so
> people don't try to reuse bit 23 in the future?

But this isn't a legacy flag. Virtio-1 devices simply may not
manipulate the mac address directly even if this feature has not been
negotiated.

> 
> The patch itself:
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 15/20] virtio-net: no writeable mac for virtio-1
@ 2015-01-22 16:31       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-22 16:31 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: thuth, mst, qemu-devel, virtualization

On Tue, 20 Jan 2015 11:19:47 +0000
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Thu, Dec 11, 2014 at 02:25:17PM +0100, Cornelia Huck wrote:
> > Devices operating as virtio 1.0 may not allow writes to the mac
> > address in config space.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/net/virtio-net.c |    1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index d6d1b98..ebbea60 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -87,6 +87,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
> >      memcpy(&netcfg, config, n->config_size);
> >  
> >      if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
> 
> I don't see VIRTIO_NET_F_CTRL_MAC_ADDR (23) in the VIRTIO 1.0 "5.1.3.1
> Legacy Interface: Feature bits" section.  Should it be there just so
> people don't try to reuse bit 23 in the future?

But this isn't a legacy flag. Virtio-1 devices simply may not
manipulate the mac address directly even if this feature has not been
negotiated.

> 
> The patch itself:
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
  2015-01-22  1:54   ` [Qemu-devel] " David Gibson
@ 2015-01-23 16:09       ` Greg Kurz
  0 siblings, 0 replies; 164+ messages in thread
From: Greg Kurz @ 2015-01-23 16:09 UTC (permalink / raw)
  To: David Gibson; +Cc: thuth, mst, rusty, qemu-devel, virtualization, Cornelia Huck

[-- Attachment #1: Type: text/plain, Size: 4257 bytes --]

On Thu, 22 Jan 2015 12:54:09 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Thu, Dec 11, 2014 at 02:25:08PM +0100, Cornelia Huck wrote:
> > Add code that checks for the VERSION_1 feature bit in order to make
> > decisions about the device's endianness. This allows us to support
> > transitional devices.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/virtio/virtio.c                |    6 +++++-
> >  include/hw/virtio/virtio-access.h |    4 ++++
> >  include/hw/virtio/virtio.h        |    8 ++++++--
> >  3 files changed, 15 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > index 7f74ae5..8f69ffa 100644
> > --- a/hw/virtio/virtio.c
> > +++ b/hw/virtio/virtio.c
> > @@ -881,7 +881,11 @@ static bool virtio_device_endian_needed(void *opaque)
> >      VirtIODevice *vdev = opaque;
> >  
> >      assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> > -    return vdev->device_endian != virtio_default_endian();
> > +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> > +        return vdev->device_endian != virtio_default_endian();
> > +    }
> > +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> > +    return vdev->device_endian != VIRTIO_DEVICE_ENDIAN_LITTLE;
> 
> This doesn't seem quite right.  Since virtio 1.0 is always LE, this
> should just assert that device_endian == LE and return false,
> right?
> 

The device_endian field is ONLY used by devices when the software is
legacy.

It is set at device reset time (see virtio_reset()) since we can reasonably
assume that when the software changes endianness, it always reset the device
before using it again (aka. reboot or kexec).

In the case we would have a BE guest, device_endian would be BE, even if the
software is virtio 1.0. So, no, we shouldn't assert.


I had questioned Cornelia about why we care to migrate device_endian when in
virtio 1.0 mode. I got these answers:

https://lists.nongnu.org/archive/html/qemu-devel/2014-10/msg03979.html
https://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg03888.html

My understanding is that a transitional device will necessarily be reset
if the software changes from legacy to 1.0 or vice-versa. So, yes, I still
think virtio_device_endian_needed() should return false.

> >  }
> >  
> >  static const VMStateDescription vmstate_virtio_device_endian = {
> > diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> > index 46456fd..ee28c21 100644
> > --- a/include/hw/virtio/virtio-access.h
> > +++ b/include/hw/virtio/virtio-access.h
> > @@ -19,6 +19,10 @@
> >  
> >  static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
> >  {
> > +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> > +        /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> > +        return false;
> > +    }
> >  #if defined(TARGET_IS_BIENDIAN)
> >      return virtio_is_big_endian(vdev);
> >  #elif defined(TARGET_WORDS_BIGENDIAN)
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index 08141c7..68c40db 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -297,7 +297,11 @@ static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> >  
> >  static inline bool virtio_is_big_endian(VirtIODevice *vdev)
> >  {
> > -    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> > -    return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> > +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> > +        assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> > +        return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> > +    }
> > +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> > +    return false;
> >  }
> >  #endif
> 
> AFAICT, the only real difference between virtio_is_big_endian() and
> virtio_access_is_big_endian() is that the latter will become
> compile-time constant on targets that don't do bi-endian.
> 
> With virtio 1.0 support, that's no longer true, so those two macros
> should just be merged, I think.
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices
@ 2015-01-23 16:09       ` Greg Kurz
  0 siblings, 0 replies; 164+ messages in thread
From: Greg Kurz @ 2015-01-23 16:09 UTC (permalink / raw)
  To: David Gibson; +Cc: thuth, mst, qemu-devel, virtualization


[-- Attachment #1.1: Type: text/plain, Size: 4257 bytes --]

On Thu, 22 Jan 2015 12:54:09 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Thu, Dec 11, 2014 at 02:25:08PM +0100, Cornelia Huck wrote:
> > Add code that checks for the VERSION_1 feature bit in order to make
> > decisions about the device's endianness. This allows us to support
> > transitional devices.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/virtio/virtio.c                |    6 +++++-
> >  include/hw/virtio/virtio-access.h |    4 ++++
> >  include/hw/virtio/virtio.h        |    8 ++++++--
> >  3 files changed, 15 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > index 7f74ae5..8f69ffa 100644
> > --- a/hw/virtio/virtio.c
> > +++ b/hw/virtio/virtio.c
> > @@ -881,7 +881,11 @@ static bool virtio_device_endian_needed(void *opaque)
> >      VirtIODevice *vdev = opaque;
> >  
> >      assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> > -    return vdev->device_endian != virtio_default_endian();
> > +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> > +        return vdev->device_endian != virtio_default_endian();
> > +    }
> > +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> > +    return vdev->device_endian != VIRTIO_DEVICE_ENDIAN_LITTLE;
> 
> This doesn't seem quite right.  Since virtio 1.0 is always LE, this
> should just assert that device_endian == LE and return false,
> right?
> 

The device_endian field is ONLY used by devices when the software is
legacy.

It is set at device reset time (see virtio_reset()) since we can reasonably
assume that when the software changes endianness, it always reset the device
before using it again (aka. reboot or kexec).

In the case we would have a BE guest, device_endian would be BE, even if the
software is virtio 1.0. So, no, we shouldn't assert.


I had questioned Cornelia about why we care to migrate device_endian when in
virtio 1.0 mode. I got these answers:

https://lists.nongnu.org/archive/html/qemu-devel/2014-10/msg03979.html
https://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg03888.html

My understanding is that a transitional device will necessarily be reset
if the software changes from legacy to 1.0 or vice-versa. So, yes, I still
think virtio_device_endian_needed() should return false.

> >  }
> >  
> >  static const VMStateDescription vmstate_virtio_device_endian = {
> > diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> > index 46456fd..ee28c21 100644
> > --- a/include/hw/virtio/virtio-access.h
> > +++ b/include/hw/virtio/virtio-access.h
> > @@ -19,6 +19,10 @@
> >  
> >  static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
> >  {
> > +    if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> > +        /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> > +        return false;
> > +    }
> >  #if defined(TARGET_IS_BIENDIAN)
> >      return virtio_is_big_endian(vdev);
> >  #elif defined(TARGET_WORDS_BIGENDIAN)
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index 08141c7..68c40db 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -297,7 +297,11 @@ static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
> >  
> >  static inline bool virtio_is_big_endian(VirtIODevice *vdev)
> >  {
> > -    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> > -    return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> > +    if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> > +        assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
> > +        return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
> > +    }
> > +    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
> > +    return false;
> >  }
> >  #endif
> 
> AFAICT, the only real difference between virtio_is_big_endian() and
> virtio_access_is_big_endian() is that the latter will become
> compile-time constant on targets that don't do bi-endian.
> 
> With virtio 1.0 support, that's no longer true, so those two macros
> should just be merged, I think.
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2015-01-22  1:43     ` David Gibson
@ 2015-01-28 15:59       ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-28 15:59 UTC (permalink / raw)
  To: David Gibson; +Cc: thuth, rusty, mst, qemu-devel, virtualization

On Thu, 22 Jan 2015 12:43:43 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > With virtio-1, we support more than 32 feature bits. Let's extend both
> > host and guest features to 64, which should suffice for a while.
> > 
> > vhost and migration have been ignored for now.
> 
> [snip]
> 
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index f6c0379..08141c7 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -55,6 +55,12 @@
> >  /* A guest should never accept this.  It implies negotiation is broken. */
> >  #define VIRTIO_F_BAD_FEATURE		30
> >  
> > +/* v1.0 compliant. */
> > +#define VIRTIO_F_VERSION_1              32
> 
> This is already in the kernel header, isn't it?
> 

Yes. But nearly all files include this header but not the kernel
header.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2015-01-28 15:59       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-28 15:59 UTC (permalink / raw)
  To: David Gibson; +Cc: thuth, mst, qemu-devel, virtualization

On Thu, 22 Jan 2015 12:43:43 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > With virtio-1, we support more than 32 feature bits. Let's extend both
> > host and guest features to 64, which should suffice for a while.
> > 
> > vhost and migration have been ignored for now.
> 
> [snip]
> 
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index f6c0379..08141c7 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -55,6 +55,12 @@
> >  /* A guest should never accept this.  It implies negotiation is broken. */
> >  #define VIRTIO_F_BAD_FEATURE		30
> >  
> > +/* v1.0 compliant. */
> > +#define VIRTIO_F_VERSION_1              32
> 
> This is already in the kernel header, isn't it?
> 

Yes. But nearly all files include this header but not the kernel
header.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
  2015-01-22  2:06   ` [Qemu-devel] " David Gibson
@ 2015-01-28 16:07       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-28 16:07 UTC (permalink / raw)
  To: David Gibson; +Cc: thuth, rusty, mst, qemu-devel, virtualization

On Thu, 22 Jan 2015 13:06:09 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Thu, Dec 11, 2014 at 02:25:09PM +0100, Cornelia Huck wrote:
> > For virtio-1 devices, we allow a more complex queue layout that doesn't
> > require descriptor table and rings on a physically-contigous memory area:
> > add virtio_queue_set_rings() to allow transports to set this up.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/virtio/virtio-mmio.c    |    3 +++
> >  hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
> >  include/hw/virtio/virtio.h |    3 +++
> >  3 files changed, 40 insertions(+), 19 deletions(-)
> > 
> > diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> > index 43b7e02..0c9b63b 100644
> > --- a/hw/virtio/virtio-mmio.c
> > +++ b/hw/virtio/virtio-mmio.c
> > @@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
> >      case VIRTIO_MMIO_QUEUENUM:
> >          DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
> >          virtio_queue_set_num(vdev, vdev->queue_sel, value);
> > +        /* Note: only call this function for legacy devices */
> 
> It's not clear to me if this is an assertion that this *does* only
> call the function for legacy devices or a fixme, that it *should* only
> call the function for legacy devices.

It's more like a note to whoever takes the virtio-mmio legacy device
code and writes a virtio-1 virtio-mmio device.

Does
/* Note: this function must only be called for legacy devices */
make that intention clearer?

> 
> > +        virtio_queue_update_rings(vdev, vdev->queue_sel);
> >          break;
> >      case VIRTIO_MMIO_QUEUEALIGN:
> > +        /* Note: this is only valid for legacy devices */
> >          virtio_queue_set_align(vdev, vdev->queue_sel, value);
> >          break;
> >      case VIRTIO_MMIO_QUEUEPFN:

(...)

> >  /* virt queue functions */
> > -static void virtqueue_init(VirtQueue *vq)
> > +void virtio_queue_update_rings(VirtIODevice *vdev, int n)
> 
> Perhaps something in the name to emphasise that this is only for <v1.0
> devices?

virtio_queue_legacy_update_rings()? Maybe a bit long...

> 
> >  {
> > -    hwaddr pa = vq->pa;
> > +    VRing *vring = &vdev->vq[n].vring;
> >  
> > -    vq->vring.desc = pa;
> > -    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
> > -    vq->vring.used = vring_align(vq->vring.avail +
> > -                                 offsetof(VRingAvail, ring[vq->vring.num]),
> > -                                 vq->vring.align);
> > +    if (!vring->desc) {
> > +        /* not yet setup -> nothing to do */
> > +        return;
> > +    }
> > +    vring->avail = vring->desc + vring->num * sizeof(VRingDesc);
> > +    vring->used = vring_align(vring->avail +
> > +                              offsetof(VRingAvail, ring[vring->num]),
> > +                              vring->align);
> 
> Would it make sense to implement this in terms of
> virtio_queue_set_rings()?

Perhaps a bit confusing, since that would re-write desc.
> 
> >  }

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
@ 2015-01-28 16:07       ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-28 16:07 UTC (permalink / raw)
  To: David Gibson; +Cc: thuth, mst, qemu-devel, virtualization

On Thu, 22 Jan 2015 13:06:09 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Thu, Dec 11, 2014 at 02:25:09PM +0100, Cornelia Huck wrote:
> > For virtio-1 devices, we allow a more complex queue layout that doesn't
> > require descriptor table and rings on a physically-contigous memory area:
> > add virtio_queue_set_rings() to allow transports to set this up.
> > 
> > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/virtio/virtio-mmio.c    |    3 +++
> >  hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
> >  include/hw/virtio/virtio.h |    3 +++
> >  3 files changed, 40 insertions(+), 19 deletions(-)
> > 
> > diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> > index 43b7e02..0c9b63b 100644
> > --- a/hw/virtio/virtio-mmio.c
> > +++ b/hw/virtio/virtio-mmio.c
> > @@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
> >      case VIRTIO_MMIO_QUEUENUM:
> >          DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
> >          virtio_queue_set_num(vdev, vdev->queue_sel, value);
> > +        /* Note: only call this function for legacy devices */
> 
> It's not clear to me if this is an assertion that this *does* only
> call the function for legacy devices or a fixme, that it *should* only
> call the function for legacy devices.

It's more like a note to whoever takes the virtio-mmio legacy device
code and writes a virtio-1 virtio-mmio device.

Does
/* Note: this function must only be called for legacy devices */
make that intention clearer?

> 
> > +        virtio_queue_update_rings(vdev, vdev->queue_sel);
> >          break;
> >      case VIRTIO_MMIO_QUEUEALIGN:
> > +        /* Note: this is only valid for legacy devices */
> >          virtio_queue_set_align(vdev, vdev->queue_sel, value);
> >          break;
> >      case VIRTIO_MMIO_QUEUEPFN:

(...)

> >  /* virt queue functions */
> > -static void virtqueue_init(VirtQueue *vq)
> > +void virtio_queue_update_rings(VirtIODevice *vdev, int n)
> 
> Perhaps something in the name to emphasise that this is only for <v1.0
> devices?

virtio_queue_legacy_update_rings()? Maybe a bit long...

> 
> >  {
> > -    hwaddr pa = vq->pa;
> > +    VRing *vring = &vdev->vq[n].vring;
> >  
> > -    vq->vring.desc = pa;
> > -    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
> > -    vq->vring.used = vring_align(vq->vring.avail +
> > -                                 offsetof(VRingAvail, ring[vq->vring.num]),
> > -                                 vq->vring.align);
> > +    if (!vring->desc) {
> > +        /* not yet setup -> nothing to do */
> > +        return;
> > +    }
> > +    vring->avail = vring->desc + vring->num * sizeof(VRingDesc);
> > +    vring->used = vring_align(vring->avail +
> > +                              offsetof(VRingAvail, ring[vring->num]),
> > +                              vring->align);
> 
> Would it make sense to implement this in terms of
> virtio_queue_set_rings()?

Perhaps a bit confusing, since that would re-write desc.
> 
> >  }

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2015-01-28 15:59       ` Cornelia Huck
@ 2015-01-29  0:11         ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-29  0:11 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, rusty, virtualization, thuth, mst

[-- Attachment #1: Type: text/plain, Size: 1303 bytes --]

On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> On Thu, 22 Jan 2015 12:43:43 +1100
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > host and guest features to 64, which should suffice for a while.
> > > 
> > > vhost and migration have been ignored for now.
> > 
> > [snip]
> > 
> > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > index f6c0379..08141c7 100644
> > > --- a/include/hw/virtio/virtio.h
> > > +++ b/include/hw/virtio/virtio.h
> > > @@ -55,6 +55,12 @@
> > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > >  #define VIRTIO_F_BAD_FEATURE		30
> > >  
> > > +/* v1.0 compliant. */
> > > +#define VIRTIO_F_VERSION_1              32
> > 
> > This is already in the kernel header, isn't it?

> 
> Yes. But nearly all files include this header but not the kernel
> header.

Can't you change that?  Or this file include the kernel header?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2015-01-29  0:11         ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-29  0:11 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, virtualization, thuth, mst


[-- Attachment #1.1: Type: text/plain, Size: 1303 bytes --]

On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> On Thu, 22 Jan 2015 12:43:43 +1100
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > host and guest features to 64, which should suffice for a while.
> > > 
> > > vhost and migration have been ignored for now.
> > 
> > [snip]
> > 
> > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > index f6c0379..08141c7 100644
> > > --- a/include/hw/virtio/virtio.h
> > > +++ b/include/hw/virtio/virtio.h
> > > @@ -55,6 +55,12 @@
> > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > >  #define VIRTIO_F_BAD_FEATURE		30
> > >  
> > > +/* v1.0 compliant. */
> > > +#define VIRTIO_F_VERSION_1              32
> > 
> > This is already in the kernel header, isn't it?

> 
> Yes. But nearly all files include this header but not the kernel
> header.

Can't you change that?  Or this file include the kernel header?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
  2015-01-28 16:07       ` Cornelia Huck
@ 2015-01-29  0:14         ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-29  0:14 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, rusty, virtualization, thuth, mst

[-- Attachment #1: Type: text/plain, Size: 2733 bytes --]

On Wed, Jan 28, 2015 at 05:07:01PM +0100, Cornelia Huck wrote:
> On Thu, 22 Jan 2015 13:06:09 +1100
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:09PM +0100, Cornelia Huck wrote:
> > > For virtio-1 devices, we allow a more complex queue layout that doesn't
> > > require descriptor table and rings on a physically-contigous memory area:
> > > add virtio_queue_set_rings() to allow transports to set this up.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > ---
> > >  hw/virtio/virtio-mmio.c    |    3 +++
> > >  hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
> > >  include/hw/virtio/virtio.h |    3 +++
> > >  3 files changed, 40 insertions(+), 19 deletions(-)
> > > 
> > > diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> > > index 43b7e02..0c9b63b 100644
> > > --- a/hw/virtio/virtio-mmio.c
> > > +++ b/hw/virtio/virtio-mmio.c
> > > @@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
> > >      case VIRTIO_MMIO_QUEUENUM:
> > >          DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
> > >          virtio_queue_set_num(vdev, vdev->queue_sel, value);
> > > +        /* Note: only call this function for legacy devices */
> > 
> > It's not clear to me if this is an assertion that this *does* only
> > call the function for legacy devices or a fixme, that it *should* only
> > call the function for legacy devices.
> 
> It's more like a note to whoever takes the virtio-mmio legacy device
> code and writes a virtio-1 virtio-mmio device.
> 
> Does
> /* Note: this function must only be called for legacy devices */
> make that intention clearer?

Yes, I think that's better.

> 
> > 
> > > +        virtio_queue_update_rings(vdev, vdev->queue_sel);
> > >          break;
> > >      case VIRTIO_MMIO_QUEUEALIGN:
> > > +        /* Note: this is only valid for legacy devices */
> > >          virtio_queue_set_align(vdev, vdev->queue_sel, value);
> > >          break;
> > >      case VIRTIO_MMIO_QUEUEPFN:
> 
> (...)
> 
> > >  /* virt queue functions */
> > > -static void virtqueue_init(VirtQueue *vq)
> > > +void virtio_queue_update_rings(VirtIODevice *vdev, int n)
> > 
> > Perhaps something in the name to emphasise that this is only for <v1.0
> > devices?
> 
> virtio_queue_legacy_update_rings()? Maybe a bit long...

There aren't many callers, so I think long is ok in this case.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout
@ 2015-01-29  0:14         ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-29  0:14 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, virtualization, thuth, mst


[-- Attachment #1.1: Type: text/plain, Size: 2733 bytes --]

On Wed, Jan 28, 2015 at 05:07:01PM +0100, Cornelia Huck wrote:
> On Thu, 22 Jan 2015 13:06:09 +1100
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Thu, Dec 11, 2014 at 02:25:09PM +0100, Cornelia Huck wrote:
> > > For virtio-1 devices, we allow a more complex queue layout that doesn't
> > > require descriptor table and rings on a physically-contigous memory area:
> > > add virtio_queue_set_rings() to allow transports to set this up.
> > > 
> > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > ---
> > >  hw/virtio/virtio-mmio.c    |    3 +++
> > >  hw/virtio/virtio.c         |   53 ++++++++++++++++++++++++++++----------------
> > >  include/hw/virtio/virtio.h |    3 +++
> > >  3 files changed, 40 insertions(+), 19 deletions(-)
> > > 
> > > diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> > > index 43b7e02..0c9b63b 100644
> > > --- a/hw/virtio/virtio-mmio.c
> > > +++ b/hw/virtio/virtio-mmio.c
> > > @@ -244,8 +244,11 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
> > >      case VIRTIO_MMIO_QUEUENUM:
> > >          DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
> > >          virtio_queue_set_num(vdev, vdev->queue_sel, value);
> > > +        /* Note: only call this function for legacy devices */
> > 
> > It's not clear to me if this is an assertion that this *does* only
> > call the function for legacy devices or a fixme, that it *should* only
> > call the function for legacy devices.
> 
> It's more like a note to whoever takes the virtio-mmio legacy device
> code and writes a virtio-1 virtio-mmio device.
> 
> Does
> /* Note: this function must only be called for legacy devices */
> make that intention clearer?

Yes, I think that's better.

> 
> > 
> > > +        virtio_queue_update_rings(vdev, vdev->queue_sel);
> > >          break;
> > >      case VIRTIO_MMIO_QUEUEALIGN:
> > > +        /* Note: this is only valid for legacy devices */
> > >          virtio_queue_set_align(vdev, vdev->queue_sel, value);
> > >          break;
> > >      case VIRTIO_MMIO_QUEUEPFN:
> 
> (...)
> 
> > >  /* virt queue functions */
> > > -static void virtqueue_init(VirtQueue *vq)
> > > +void virtio_queue_update_rings(VirtIODevice *vdev, int n)
> > 
> > Perhaps something in the name to emphasise that this is only for <v1.0
> > devices?
> 
> virtio_queue_legacy_update_rings()? Maybe a bit long...

There aren't many callers, so I think long is ok in this case.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2015-01-29  0:11         ` David Gibson
@ 2015-01-29  9:24           ` Thomas Huth
  -1 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2015-01-29  9:24 UTC (permalink / raw)
  To: David Gibson; +Cc: Cornelia Huck, rusty, virtualization, qemu-devel, mst

[-- Attachment #1: Type: text/plain, Size: 1602 bytes --]


 Hi,

On Thu, 29 Jan 2015 11:11:32 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > On Thu, 22 Jan 2015 12:43:43 +1100
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > host and guest features to 64, which should suffice for a while.
> > > > 
> > > > vhost and migration have been ignored for now.
> > > 
> > > [snip]
> > > 
> > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > index f6c0379..08141c7 100644
> > > > --- a/include/hw/virtio/virtio.h
> > > > +++ b/include/hw/virtio/virtio.h
> > > > @@ -55,6 +55,12 @@
> > > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > > >  #define VIRTIO_F_BAD_FEATURE		30
> > > >  
> > > > +/* v1.0 compliant. */
> > > > +#define VIRTIO_F_VERSION_1              32
> > > 
> > > This is already in the kernel header, isn't it?
> 
> > 
> > Yes. But nearly all files include this header but not the kernel
> > header.
> 
> Can't you change that?  Or this file include the kernel header?
 
AFAIK non-KVM code should never try to include one of the Linux headers
to avoid breaking on non-Linux platforms (for example <linux/types.h> is
not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
So it's a little bit ugly to define these things twice, but it seems
the only way to stay portable.

 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2015-01-29  9:24           ` Thomas Huth
  0 siblings, 0 replies; 164+ messages in thread
From: Thomas Huth @ 2015-01-29  9:24 UTC (permalink / raw)
  To: David Gibson; +Cc: virtualization, qemu-devel, mst


[-- Attachment #1.1: Type: text/plain, Size: 1602 bytes --]


 Hi,

On Thu, 29 Jan 2015 11:11:32 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > On Thu, 22 Jan 2015 12:43:43 +1100
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > host and guest features to 64, which should suffice for a while.
> > > > 
> > > > vhost and migration have been ignored for now.
> > > 
> > > [snip]
> > > 
> > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > index f6c0379..08141c7 100644
> > > > --- a/include/hw/virtio/virtio.h
> > > > +++ b/include/hw/virtio/virtio.h
> > > > @@ -55,6 +55,12 @@
> > > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > > >  #define VIRTIO_F_BAD_FEATURE		30
> > > >  
> > > > +/* v1.0 compliant. */
> > > > +#define VIRTIO_F_VERSION_1              32
> > > 
> > > This is already in the kernel header, isn't it?
> 
> > 
> > Yes. But nearly all files include this header but not the kernel
> > header.
> 
> Can't you change that?  Or this file include the kernel header?
 
AFAIK non-KVM code should never try to include one of the Linux headers
to avoid breaking on non-Linux platforms (for example <linux/types.h> is
not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
So it's a little bit ugly to define these things twice, but it seems
the only way to stay portable.

 Thomas

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2015-01-29  9:24           ` Thomas Huth
@ 2015-01-29 10:01             ` David Gibson
  -1 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-29 10:01 UTC (permalink / raw)
  To: Thomas Huth; +Cc: Cornelia Huck, rusty, virtualization, qemu-devel, mst

[-- Attachment #1: Type: text/plain, Size: 1958 bytes --]

On Thu, Jan 29, 2015 at 10:24:00AM +0100, Thomas Huth wrote:
> 
>  Hi,
> 
> On Thu, 29 Jan 2015 11:11:32 +1100
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > > On Thu, 22 Jan 2015 12:43:43 +1100
> > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > 
> > > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > > host and guest features to 64, which should suffice for a while.
> > > > > 
> > > > > vhost and migration have been ignored for now.
> > > > 
> > > > [snip]
> > > > 
> > > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > > index f6c0379..08141c7 100644
> > > > > --- a/include/hw/virtio/virtio.h
> > > > > +++ b/include/hw/virtio/virtio.h
> > > > > @@ -55,6 +55,12 @@
> > > > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > > > >  #define VIRTIO_F_BAD_FEATURE		30
> > > > >  
> > > > > +/* v1.0 compliant. */
> > > > > +#define VIRTIO_F_VERSION_1              32
> > > > 
> > > > This is already in the kernel header, isn't it?
> > 
> > > 
> > > Yes. But nearly all files include this header but not the kernel
> > > header.
> > 
> > Can't you change that?  Or this file include the kernel header?
>  
> AFAIK non-KVM code should never try to include one of the Linux headers
> to avoid breaking on non-Linux platforms (for example <linux/types.h> is
> not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
> So it's a little bit ugly to define these things twice, but it seems
> the only way to stay portable.

Ah, yeah, good point.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2015-01-29 10:01             ` David Gibson
  0 siblings, 0 replies; 164+ messages in thread
From: David Gibson @ 2015-01-29 10:01 UTC (permalink / raw)
  To: Thomas Huth; +Cc: virtualization, qemu-devel, mst


[-- Attachment #1.1: Type: text/plain, Size: 1958 bytes --]

On Thu, Jan 29, 2015 at 10:24:00AM +0100, Thomas Huth wrote:
> 
>  Hi,
> 
> On Thu, 29 Jan 2015 11:11:32 +1100
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > > On Thu, 22 Jan 2015 12:43:43 +1100
> > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > 
> > > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > > host and guest features to 64, which should suffice for a while.
> > > > > 
> > > > > vhost and migration have been ignored for now.
> > > > 
> > > > [snip]
> > > > 
> > > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > > index f6c0379..08141c7 100644
> > > > > --- a/include/hw/virtio/virtio.h
> > > > > +++ b/include/hw/virtio/virtio.h
> > > > > @@ -55,6 +55,12 @@
> > > > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > > > >  #define VIRTIO_F_BAD_FEATURE		30
> > > > >  
> > > > > +/* v1.0 compliant. */
> > > > > +#define VIRTIO_F_VERSION_1              32
> > > > 
> > > > This is already in the kernel header, isn't it?
> > 
> > > 
> > > Yes. But nearly all files include this header but not the kernel
> > > header.
> > 
> > Can't you change that?  Or this file include the kernel header?
>  
> AFAIK non-KVM code should never try to include one of the Linux headers
> to avoid breaking on non-Linux platforms (for example <linux/types.h> is
> not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
> So it's a little bit ugly to define these things twice, but it seems
> the only way to stay portable.

Ah, yeah, good point.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
  2015-01-29 10:01             ` David Gibson
@ 2015-01-29 10:54               ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-29 10:54 UTC (permalink / raw)
  To: David Gibson
  Cc: Cornelia Huck, rusty, virtualization, Thomas Huth, qemu-devel

On Thu, Jan 29, 2015 at 09:01:45PM +1100, David Gibson wrote:
> On Thu, Jan 29, 2015 at 10:24:00AM +0100, Thomas Huth wrote:
> > 
> >  Hi,
> > 
> > On Thu, 29 Jan 2015 11:11:32 +1100
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > > > On Thu, 22 Jan 2015 12:43:43 +1100
> > > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > > 
> > > > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > > > host and guest features to 64, which should suffice for a while.
> > > > > > 
> > > > > > vhost and migration have been ignored for now.
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > > > index f6c0379..08141c7 100644
> > > > > > --- a/include/hw/virtio/virtio.h
> > > > > > +++ b/include/hw/virtio/virtio.h
> > > > > > @@ -55,6 +55,12 @@
> > > > > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > > > > >  #define VIRTIO_F_BAD_FEATURE		30
> > > > > >  
> > > > > > +/* v1.0 compliant. */
> > > > > > +#define VIRTIO_F_VERSION_1              32
> > > > > 
> > > > > This is already in the kernel header, isn't it?
> > > 
> > > > 
> > > > Yes. But nearly all files include this header but not the kernel
> > > > header.
> > > 
> > > Can't you change that?  Or this file include the kernel header?
> >  
> > AFAIK non-KVM code should never try to include one of the Linux headers
> > to avoid breaking on non-Linux platforms (for example <linux/types.h> is
> > not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
> > So it's a little bit ugly to define these things twice, but it seems
> > the only way to stay portable.
> 
> Ah, yeah, good point.

I do intend to write a script to import more headers from linux,
changing them on the fly to drop dependency on linux/types.h
etc.

If someone wants to beat me to it, so much the better.

> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits
@ 2015-01-29 10:54               ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-01-29 10:54 UTC (permalink / raw)
  To: David Gibson; +Cc: virtualization, Thomas Huth, qemu-devel

On Thu, Jan 29, 2015 at 09:01:45PM +1100, David Gibson wrote:
> On Thu, Jan 29, 2015 at 10:24:00AM +0100, Thomas Huth wrote:
> > 
> >  Hi,
> > 
> > On Thu, 29 Jan 2015 11:11:32 +1100
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > > > On Thu, 22 Jan 2015 12:43:43 +1100
> > > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > > 
> > > > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > > > host and guest features to 64, which should suffice for a while.
> > > > > > 
> > > > > > vhost and migration have been ignored for now.
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > > > index f6c0379..08141c7 100644
> > > > > > --- a/include/hw/virtio/virtio.h
> > > > > > +++ b/include/hw/virtio/virtio.h
> > > > > > @@ -55,6 +55,12 @@
> > > > > >  /* A guest should never accept this.  It implies negotiation is broken. */
> > > > > >  #define VIRTIO_F_BAD_FEATURE		30
> > > > > >  
> > > > > > +/* v1.0 compliant. */
> > > > > > +#define VIRTIO_F_VERSION_1              32
> > > > > 
> > > > > This is already in the kernel header, isn't it?
> > > 
> > > > 
> > > > Yes. But nearly all files include this header but not the kernel
> > > > header.
> > > 
> > > Can't you change that?  Or this file include the kernel header?
> >  
> > AFAIK non-KVM code should never try to include one of the Linux headers
> > to avoid breaking on non-Linux platforms (for example <linux/types.h> is
> > not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
> > So it's a little bit ugly to define these things twice, but it seems
> > the only way to stay portable.
> 
> Ah, yeah, good point.

I do intend to write a script to import more headers from linux,
changing them on the fly to drop dependency on linux/types.h
etc.

If someone wants to beat me to it, so much the better.

> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features
  2015-01-07 19:10         ` Michael S. Tsirkin
@ 2015-01-30 14:08           ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-30 14:08 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Wed, 7 Jan 2015 21:10:07 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> > On Sun, 28 Dec 2014 10:32:06 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > > Devices may support different sets of feature bits depending on which
> > > > revision they're operating at. Let's give the transport a way to
> > > > re-query the device about its features when the revision has been
> > > > changed.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > 
> > > So now we have both get_features and get_features_rev, and
> > > it's never clear which revision does host_features refer to.
> > > IMHO that's just too messy.
> > > Let's add get_legacy_features and host_legacy_features instead?
> > 
> > I wanted to avoid touching anything that does not support version 1.
> > And this interface might still work for later revisions, no?
> 
> We can add _modern_ then, or rename host_features to host_legacy_features
> everywhere as preparation.
> 

OK, I've ditched the "don't modify old stuff" goal and introduced
->get_features_legacy(). For now, devices will add VERSION_1 in their
->get_features() callback when they support it. (For many devices, this
will be the only difference between the two callbacks.)

Two sets of host_features don't make much sense to me.

I've hacked up something and will play with it a bit; I might post a
new patch series next week.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 18/20] virtio: support revision-specific features
@ 2015-01-30 14:08           ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-30 14:08 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Wed, 7 Jan 2015 21:10:07 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> > On Sun, 28 Dec 2014 10:32:06 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > > Devices may support different sets of feature bits depending on which
> > > > revision they're operating at. Let's give the transport a way to
> > > > re-query the device about its features when the revision has been
> > > > changed.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > 
> > > So now we have both get_features and get_features_rev, and
> > > it's never clear which revision does host_features refer to.
> > > IMHO that's just too messy.
> > > Let's add get_legacy_features and host_legacy_features instead?
> > 
> > I wanted to avoid touching anything that does not support version 1.
> > And this interface might still work for later revisions, no?
> 
> We can add _modern_ then, or rename host_features to host_legacy_features
> everywhere as preparation.
> 

OK, I've ditched the "don't modify old stuff" goal and introduced
->get_features_legacy(). For now, devices will add VERSION_1 in their
->get_features() callback when they support it. (For many devices, this
will be the only difference between the two callbacks.)

Two sets of host_features don't make much sense to me.

I've hacked up something and will play with it a bit; I might post a
new patch series next week.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
  2015-01-07 19:11         ` Michael S. Tsirkin
@ 2015-01-30 14:10           ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-30 14:10 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Wed, 7 Jan 2015 21:11:44 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 07, 2015 at 05:29:49PM +0100, Cornelia Huck wrote:
> > On Sun, 28 Dec 2014 12:24:46 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> > > > Wire up virtio-blk to provide different feature bit sets depending
> > > > on whether legacy or v1.0 has been requested.
> > > > 
> > > > Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > 
> > > So we need some way for devices to tell transports
> > > not to negotiate rev 1.
> > > Does clearing VERSION_1 have this effect?
> > > 
> > I just noticed that my patch is running in circles here.
> > 
> > What we need is probably the transport-dependent maximum revision
> > checker (which at least for ccw is acting on a device) pass in the
> > requested revision and check if the feature bits for the revision
> > include VERSION_1. Does that make sense?
> 
> Just make devices set 'rev 1 supported' flag?

I'm now using the ->get_features() callback to check for VERSION_1
(assuming every device that supports it adds the bit in its callback)
and only allow rev 1 if it is present. Will play with this a bit as
well.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits
@ 2015-01-30 14:10           ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-01-30 14:10 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Wed, 7 Jan 2015 21:11:44 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 07, 2015 at 05:29:49PM +0100, Cornelia Huck wrote:
> > On Sun, 28 Dec 2014 12:24:46 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:21PM +0100, Cornelia Huck wrote:
> > > > Wire up virtio-blk to provide different feature bit sets depending
> > > > on whether legacy or v1.0 has been requested.
> > > > 
> > > > Note that VERSION_1 is still disabled due to missing ANY_LAYOUT support.
> > > > 
> > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > 
> > > So we need some way for devices to tell transports
> > > not to negotiate rev 1.
> > > Does clearing VERSION_1 have this effect?
> > > 
> > I just noticed that my patch is running in circles here.
> > 
> > What we need is probably the transport-dependent maximum revision
> > checker (which at least for ccw is acting on a device) pass in the
> > requested revision and check if the feature bits for the revision
> > include VERSION_1. Does that make sense?
> 
> Just make devices set 'rev 1 supported' flag?

I'm now using the ->get_features() callback to check for VERSION_1
(assuming every device that supports it adds the bit in its callback)
and only allow rev 1 if it is present. Will play with this a bit as
well.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features
  2015-01-30 14:08           ` Cornelia Huck
@ 2015-02-01 21:29             ` Michael S. Tsirkin
  -1 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-02-01 21:29 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, rusty, qemu-devel, virtualization

On Fri, Jan 30, 2015 at 03:08:08PM +0100, Cornelia Huck wrote:
> On Wed, 7 Jan 2015 21:10:07 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> > > On Sun, 28 Dec 2014 10:32:06 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > > > Devices may support different sets of feature bits depending on which
> > > > > revision they're operating at. Let's give the transport a way to
> > > > > re-query the device about its features when the revision has been
> > > > > changed.
> > > > > 
> > > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > 
> > > > So now we have both get_features and get_features_rev, and
> > > > it's never clear which revision does host_features refer to.
> > > > IMHO that's just too messy.
> > > > Let's add get_legacy_features and host_legacy_features instead?
> > > 
> > > I wanted to avoid touching anything that does not support version 1.
> > > And this interface might still work for later revisions, no?
> > 
> > We can add _modern_ then, or rename host_features to host_legacy_features
> > everywhere as preparation.
> > 
> 
> OK, I've ditched the "don't modify old stuff" goal and introduced
> ->get_features_legacy(). For now, devices will add VERSION_1 in their
> ->get_features() callback when they support it. (For many devices, this
> will be the only difference between the two callbacks.)
> 
> Two sets of host_features don't make much sense to me.

It's the most natural implementation given that
some features are only set for legacy and some (will be) only
for modern interfaces.
But we'll see.

> I've hacked up something and will play with it a bit; I might post a
> new patch series next week.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 18/20] virtio: support revision-specific features
@ 2015-02-01 21:29             ` Michael S. Tsirkin
  0 siblings, 0 replies; 164+ messages in thread
From: Michael S. Tsirkin @ 2015-02-01 21:29 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: thuth, qemu-devel, virtualization

On Fri, Jan 30, 2015 at 03:08:08PM +0100, Cornelia Huck wrote:
> On Wed, 7 Jan 2015 21:10:07 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> > > On Sun, 28 Dec 2014 10:32:06 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > > > Devices may support different sets of feature bits depending on which
> > > > > revision they're operating at. Let's give the transport a way to
> > > > > re-query the device about its features when the revision has been
> > > > > changed.
> > > > > 
> > > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > 
> > > > So now we have both get_features and get_features_rev, and
> > > > it's never clear which revision does host_features refer to.
> > > > IMHO that's just too messy.
> > > > Let's add get_legacy_features and host_legacy_features instead?
> > > 
> > > I wanted to avoid touching anything that does not support version 1.
> > > And this interface might still work for later revisions, no?
> > 
> > We can add _modern_ then, or rename host_features to host_legacy_features
> > everywhere as preparation.
> > 
> 
> OK, I've ditched the "don't modify old stuff" goal and introduced
> ->get_features_legacy(). For now, devices will add VERSION_1 in their
> ->get_features() callback when they support it. (For many devices, this
> will be the only difference between the two callbacks.)
> 
> Two sets of host_features don't make much sense to me.

It's the most natural implementation given that
some features are only set for legacy and some (will be) only
for modern interfaces.
But we'll see.

> I've hacked up something and will play with it a bit; I might post a
> new patch series next week.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features
  2015-02-01 21:29             ` Michael S. Tsirkin
@ 2015-02-02 14:10               ` Cornelia Huck
  -1 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-02-02 14:10 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, rusty, qemu-devel, virtualization

On Sun, 1 Feb 2015 23:29:20 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Jan 30, 2015 at 03:08:08PM +0100, Cornelia Huck wrote:
> > On Wed, 7 Jan 2015 21:10:07 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> > > > On Sun, 28 Dec 2014 10:32:06 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > > > > Devices may support different sets of feature bits depending on which
> > > > > > revision they're operating at. Let's give the transport a way to
> > > > > > re-query the device about its features when the revision has been
> > > > > > changed.
> > > > > > 
> > > > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > > 
> > > > > So now we have both get_features and get_features_rev, and
> > > > > it's never clear which revision does host_features refer to.
> > > > > IMHO that's just too messy.
> > > > > Let's add get_legacy_features and host_legacy_features instead?
> > > > 
> > > > I wanted to avoid touching anything that does not support version 1.
> > > > And this interface might still work for later revisions, no?
> > > 
> > > We can add _modern_ then, or rename host_features to host_legacy_features
> > > everywhere as preparation.
> > > 
> > 
> > OK, I've ditched the "don't modify old stuff" goal and introduced
> > ->get_features_legacy(). For now, devices will add VERSION_1 in their
> > ->get_features() callback when they support it. (For many devices, this
> > will be the only difference between the two callbacks.)
> > 
> > Two sets of host_features don't make much sense to me.
> 
> It's the most natural implementation given that
> some features are only set for legacy and some (will be) only
> for modern interfaces.

We may be talking about different things: There's the host_features
field which is referenced by the different device types, and there are
the sets of features for legacy or modern devices. These are currently
set dynamically in the ->get_features() callbacks, although we could
possibly convert them to pre-set values like in the kernel. Then I
agree, two sets would be natural. But I'd rather stick with the current
method, if only to avoid churn.

^ permalink raw reply	[flat|nested] 164+ messages in thread

* Re: [PATCH RFC v6 18/20] virtio: support revision-specific features
@ 2015-02-02 14:10               ` Cornelia Huck
  0 siblings, 0 replies; 164+ messages in thread
From: Cornelia Huck @ 2015-02-02 14:10 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: thuth, qemu-devel, virtualization

On Sun, 1 Feb 2015 23:29:20 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Jan 30, 2015 at 03:08:08PM +0100, Cornelia Huck wrote:
> > On Wed, 7 Jan 2015 21:10:07 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Wed, Jan 07, 2015 at 05:22:32PM +0100, Cornelia Huck wrote:
> > > > On Sun, 28 Dec 2014 10:32:06 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Thu, Dec 11, 2014 at 02:25:20PM +0100, Cornelia Huck wrote:
> > > > > > Devices may support different sets of feature bits depending on which
> > > > > > revision they're operating at. Let's give the transport a way to
> > > > > > re-query the device about its features when the revision has been
> > > > > > changed.
> > > > > > 
> > > > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > > 
> > > > > So now we have both get_features and get_features_rev, and
> > > > > it's never clear which revision does host_features refer to.
> > > > > IMHO that's just too messy.
> > > > > Let's add get_legacy_features and host_legacy_features instead?
> > > > 
> > > > I wanted to avoid touching anything that does not support version 1.
> > > > And this interface might still work for later revisions, no?
> > > 
> > > We can add _modern_ then, or rename host_features to host_legacy_features
> > > everywhere as preparation.
> > > 
> > 
> > OK, I've ditched the "don't modify old stuff" goal and introduced
> > ->get_features_legacy(). For now, devices will add VERSION_1 in their
> > ->get_features() callback when they support it. (For many devices, this
> > will be the only difference between the two callbacks.)
> > 
> > Two sets of host_features don't make much sense to me.
> 
> It's the most natural implementation given that
> some features are only set for legacy and some (will be) only
> for modern interfaces.

We may be talking about different things: There's the host_features
field which is referenced by the different device types, and there are
the sets of features for legacy or modern devices. These are currently
set dynamically in the ->get_features() callbacks, although we could
possibly convert them to pre-set values like in the kernel. Then I
agree, two sets would be natural. But I'd rather stick with the current
method, if only to avoid churn.

^ permalink raw reply	[flat|nested] 164+ messages in thread

end of thread, other threads:[~2015-02-02 14:10 UTC | newest]

Thread overview: 164+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-11 13:25 [Qemu-devel] [PATCH RFC v6 00/20] qemu: towards virtio-1 host support Cornelia Huck
2014-12-11 13:25 ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 01/20] linux-headers/virtio_config: Update with VIRTIO_F_VERSION_1 Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 02/20] virtio: cull virtio_bus_set_vdev_features Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-22  1:24   ` [Qemu-devel] " David Gibson
2015-01-22  1:24     ` David Gibson
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 03/20] virtio: feature bit manipulation helpers Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-11 14:29   ` Thomas Huth
2014-12-11 14:29   ` [Qemu-devel] " Thomas Huth
2015-01-22  1:25   ` David Gibson
2015-01-22  1:25     ` David Gibson
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 04/20] virtio: add feature checking helpers Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-11 14:46   ` [Qemu-devel] " Thomas Huth
2014-12-11 17:05     ` Michael S. Tsirkin
2014-12-11 17:05       ` Michael S. Tsirkin
2014-12-12  8:37       ` [Qemu-devel] " Cornelia Huck
2014-12-12  8:37         ` Cornelia Huck
2014-12-12 10:07     ` [Qemu-devel] " Cornelia Huck
2014-12-12 10:07       ` Cornelia Huck
2014-12-11 14:46   ` Thomas Huth
2015-01-22  1:28   ` [Qemu-devel] " David Gibson
2015-01-22  1:28   ` David Gibson
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-12 10:06   ` [Qemu-devel] " Thomas Huth
2014-12-12 10:06     ` Thomas Huth
2014-12-12 10:17     ` [Qemu-devel] " Cornelia Huck
2014-12-12 10:17       ` Cornelia Huck
2015-01-22  1:40       ` [Qemu-devel] " David Gibson
2015-01-22  1:40       ` David Gibson
2015-01-22  1:43   ` David Gibson
2015-01-22  1:43     ` David Gibson
2015-01-28 15:59     ` Cornelia Huck
2015-01-28 15:59       ` Cornelia Huck
2015-01-29  0:11       ` David Gibson
2015-01-29  0:11         ` David Gibson
2015-01-29  9:24         ` Thomas Huth
2015-01-29  9:24           ` Thomas Huth
2015-01-29 10:01           ` David Gibson
2015-01-29 10:01             ` David Gibson
2015-01-29 10:54             ` Michael S. Tsirkin
2015-01-29 10:54               ` Michael S. Tsirkin
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 06/20] virtio: endianness checks for virtio 1.0 devices Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 10:29   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 10:29     ` Stefan Hajnoczi
2015-01-22  1:54   ` [Qemu-devel] " David Gibson
2015-01-23 16:09     ` Greg Kurz
2015-01-23 16:09       ` Greg Kurz
2015-01-22  1:54   ` David Gibson
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 07/20] virtio: allow virtio-1 queue layout Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-22  2:06   ` [Qemu-devel] " David Gibson
2015-01-28 16:07     ` Cornelia Huck
2015-01-28 16:07       ` Cornelia Huck
2015-01-29  0:14       ` David Gibson
2015-01-29  0:14         ` David Gibson
2015-01-22  2:06   ` David Gibson
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 08/20] dataplane: allow virtio-1 devices Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 10:43   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 10:43     ` Stefan Hajnoczi
2015-01-20 12:56     ` [Qemu-devel] " Cornelia Huck
2015-01-20 12:56       ` Cornelia Huck
2015-01-20 14:47       ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 14:47         ` Stefan Hajnoczi
2015-01-22  2:12   ` [Qemu-devel] " David Gibson
2015-01-22  2:12     ` David Gibson
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 09/20] s390x/css: Add a callback for when subchannel gets disabled Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 10:50   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 10:50     ` Stefan Hajnoczi
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 10/20] s390x/virtio-ccw: add virtio set-revision call Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 11:00   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 11:00     ` Stefan Hajnoczi
2015-01-20 11:08   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 11:08     ` Stefan Hajnoczi
2015-01-21 11:23     ` [Qemu-devel] " Cornelia Huck
2015-01-21 11:23       ` Cornelia Huck
2015-01-21 11:51       ` [Qemu-devel] " Thomas Huth
2015-01-21 11:51         ` Thomas Huth
2015-01-21 12:39         ` Cornelia Huck
2015-01-21 12:39           ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 11/20] s390x/virtio-ccw: support virtio-1 set_vq format Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 11:06   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 11:06     ` Stefan Hajnoczi
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 12/20] virtio: disallow late feature changes for virtio-1 Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-12 10:55   ` [Qemu-devel] " Thomas Huth
2014-12-12 10:55     ` Thomas Huth
2014-12-12 11:18     ` [Qemu-devel] " Cornelia Huck
2014-12-12 11:18       ` Cornelia Huck
2014-12-12 11:25       ` [Qemu-devel] " Thomas Huth
2014-12-12 11:25         ` Thomas Huth
2015-01-20 11:14         ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 11:14           ` Stefan Hajnoczi
2015-01-22  2:15   ` [Qemu-devel] " David Gibson
2015-01-22  2:15     ` David Gibson
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 13/20] virtio: allow to fail setting status Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-30 12:25   ` [Qemu-devel] " Michael S. Tsirkin
2014-12-30 12:25     ` Michael S. Tsirkin
2015-01-07 16:13     ` [Qemu-devel] " Cornelia Huck
2015-01-07 16:13       ` Cornelia Huck
2015-01-07 19:08       ` [Qemu-devel] " Michael S. Tsirkin
2015-01-07 19:08         ` Michael S. Tsirkin
2015-01-08  7:20         ` [Qemu-devel] " Cornelia Huck
2015-01-08  7:20           ` Cornelia Huck
2015-01-08  8:09           ` [Qemu-devel] " Michael S. Tsirkin
2015-01-08  8:09             ` Michael S. Tsirkin
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 14/20] s390x/virtio-ccw: enable virtio 1.0 Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 11:15   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 11:15     ` Stefan Hajnoczi
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 15/20] virtio-net: no writeable mac for virtio-1 Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 11:19   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 11:19     ` Stefan Hajnoczi
2015-01-22 16:31     ` [Qemu-devel] " Cornelia Huck
2015-01-22 16:31       ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 16/20] virtio-net: support longer header Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2015-01-20 13:18   ` [Qemu-devel] " Stefan Hajnoczi
2015-01-20 13:18     ` Stefan Hajnoczi
2015-01-21 16:06     ` [Qemu-devel] " Cornelia Huck
2015-01-21 16:06       ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 17/20] virtio-net: enable virtio 1.0 Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-16 13:10   ` [Qemu-devel] " Michael S. Tsirkin
2014-12-16 13:10     ` Michael S. Tsirkin
2014-12-18 16:57     ` [Qemu-devel] " Cornelia Huck
2014-12-18 16:57       ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 18/20] virtio: support revision-specific features Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-28  8:32   ` [Qemu-devel] " Michael S. Tsirkin
2014-12-28  8:32     ` Michael S. Tsirkin
2015-01-07 16:22     ` [Qemu-devel] " Cornelia Huck
2015-01-07 16:22       ` Cornelia Huck
2015-01-07 19:10       ` [Qemu-devel] " Michael S. Tsirkin
2015-01-07 19:10         ` Michael S. Tsirkin
2015-01-30 14:08         ` [Qemu-devel] " Cornelia Huck
2015-01-30 14:08           ` Cornelia Huck
2015-02-01 21:29           ` [Qemu-devel] " Michael S. Tsirkin
2015-02-01 21:29             ` Michael S. Tsirkin
2015-02-02 14:10             ` [Qemu-devel] " Cornelia Huck
2015-02-02 14:10               ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 19/20] virtio-blk: revision specific feature bits Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck
2014-12-28 10:24   ` [Qemu-devel] " Michael S. Tsirkin
2014-12-28 10:24     ` Michael S. Tsirkin
2015-01-07 16:29     ` Cornelia Huck
2015-01-07 16:29     ` [Qemu-devel] " Cornelia Huck
2015-01-07 19:11       ` Michael S. Tsirkin
2015-01-07 19:11         ` Michael S. Tsirkin
2015-01-30 14:10         ` [Qemu-devel] " Cornelia Huck
2015-01-30 14:10           ` Cornelia Huck
2014-12-11 13:25 ` [Qemu-devel] [PATCH RFC v6 20/20] vhost: 64 bit features Cornelia Huck
2014-12-11 13:25   ` Cornelia Huck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.