virtio-fs.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support
@ 2024-03-13 11:54 Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data Jonah Palmer
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 11:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, eperezma, si-wei.liu, boris.ostrovsky,
	jonah.palmer, raphael, kwolf, hreitz, pasic, borntraeger, farman,
	thuth, richard.henderson, david, iii, cohuck, pbonzini, fam,
	stefanha, qemu-block, qemu-s390x, leiyang, schalla, vattunuru,
	jerinj, dtatulea, virtio-fs

The goal of these patches are to add support to a variety of virtio and
vhost devices for the VIRTIO_F_NOTIFICATION_DATA transport feature. This
feature indicates that a driver will pass extra data (instead of just a
virtqueue's index) when notifying the corresponding device.

The data passed in by the driver when this feature is enabled varies in
format depending on if the device is using a split or packed virtqueue
layout:

 Split VQ
  - Upper 16 bits: shadow_avail_idx
  - Lower 16 bits: virtqueue index

 Packed VQ
  - Upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
  - Lower 16 bits: virtqueue index

Also, due to the limitations of ioeventfd not being able to carry the
extra provided by the driver, having both VIRTIO_F_NOTIFICATION_DATA
feature and ioeventfd enabled is a functional mismatch. The user must
explicitly disable ioeventfd for the device in the Qemu arguments when
using this feature, else the device will fail to complete realization.

For example, a device must explicitly enable notification_data as well
as disable ioeventfd:

    -device virtio-scsi-pci,...,ioeventfd=off,notification_data=on

A significant aspect of this effort has been to maintain compatibility
across different backends. As such, the feature is offered by backend
devices only when supported, with fallback mechanisms where backend
support is absent.

v2: Don't disable ioeventfd by default, user must disable it
    Drop tags on patch 2/6

Jonah Palmer (6):
  virtio/virtio-pci: Handle extra notification data
  virtio: Prevent creation of device using notification-data with ioeventfd
  virtio-mmio: Handle extra notification data
  virtio-ccw: Handle extra notification data
  vhost/vhost-user: Add VIRTIO_F_NOTIFICATION_DATA to vhost feature bits
  virtio: Add VIRTIO_F_NOTIFICATION_DATA property definition

 hw/block/vhost-user-blk.c    |  1 +
 hw/net/vhost_net.c           |  2 ++
 hw/s390x/s390-virtio-ccw.c   | 16 +++++++++++----
 hw/scsi/vhost-scsi.c         |  1 +
 hw/scsi/vhost-user-scsi.c    |  1 +
 hw/virtio/vhost-user-fs.c    |  2 +-
 hw/virtio/vhost-user-vsock.c |  1 +
 hw/virtio/virtio-mmio.c      |  9 ++++++--
 hw/virtio/virtio-pci.c       | 10 ++++++---
 hw/virtio/virtio.c           | 40 ++++++++++++++++++++++++++++++++++++
 include/hw/virtio/virtio.h   |  7 ++++++-
 net/vhost-vdpa.c             |  1 +
 12 files changed, 80 insertions(+), 11 deletions(-)

-- 
2.39.3


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

* [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-13 11:54 [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support Jonah Palmer
@ 2024-03-13 11:54 ` Jonah Palmer
  2024-03-14  3:01   ` Jason Wang
  2024-03-13 11:54 ` [PATCH v2 2/6] virtio: Prevent creation of device using notification-data with ioeventfd Jonah Palmer
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 11:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, eperezma, si-wei.liu, boris.ostrovsky,
	jonah.palmer, raphael, kwolf, hreitz, pasic, borntraeger, farman,
	thuth, richard.henderson, david, iii, cohuck, pbonzini, fam,
	stefanha, qemu-block, qemu-s390x, leiyang, schalla, vattunuru,
	jerinj, dtatulea, virtio-fs

Add support to virtio-pci devices for handling the extra data sent
from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
transport feature has been negotiated.

The extra data that's passed to the virtio-pci device when this
feature is enabled varies depending on the device's virtqueue
layout.

In a split virtqueue layout, this data includes:
 - upper 16 bits: shadow_avail_idx
 - lower 16 bits: virtqueue index

In a packed virtqueue layout, this data includes:
 - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
 - lower 16 bits: virtqueue index

Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 hw/virtio/virtio-pci.c     | 10 +++++++---
 hw/virtio/virtio.c         | 18 ++++++++++++++++++
 include/hw/virtio/virtio.h |  1 +
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index cb6940fc0e..0f5c3c3b2f 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-    uint16_t vector;
+    uint16_t vector, vq_idx;
     hwaddr pa;
 
     switch (addr) {
@@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             vdev->queue_sel = val;
         break;
     case VIRTIO_PCI_QUEUE_NOTIFY:
-        if (val < VIRTIO_QUEUE_MAX) {
-            virtio_queue_notify(vdev, val);
+        vq_idx = val;
+        if (vq_idx < VIRTIO_QUEUE_MAX) {
+            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
+                virtio_queue_set_shadow_avail_data(vdev, val);
+            }
+            virtio_queue_notify(vdev, vq_idx);
         }
         break;
     case VIRTIO_PCI_STATUS:
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index d229755eae..bcb9e09df0 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
     }
 }
 
+void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)
+{
+    /* Lower 16 bits is the virtqueue index */
+    uint16_t i = data;
+    VirtQueue *vq = &vdev->vq[i];
+
+    if (!vq->vring.desc) {
+        return;
+    }
+
+    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
+        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
+        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
+    } else {
+        vq->shadow_avail_idx = (data >> 16);
+    }
+}
+
 static void virtio_queue_notify_vq(VirtQueue *vq)
 {
     if (vq->vring.desc && vq->handle_output) {
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index c8f72850bc..53915947a7 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
 void virtio_init_region_cache(VirtIODevice *vdev, int n);
 void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
 void virtio_queue_notify(VirtIODevice *vdev, int n);
+void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
 uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
 void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
 int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
-- 
2.39.3


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

* [PATCH v2 2/6] virtio: Prevent creation of device using notification-data with ioeventfd
  2024-03-13 11:54 [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data Jonah Palmer
@ 2024-03-13 11:54 ` Jonah Palmer
  2024-03-13 14:35   ` Eugenio Perez Martin
  2024-03-13 11:54 ` [PATCH v2 3/6] virtio-mmio: Handle extra notification data Jonah Palmer
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 11:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, eperezma, si-wei.liu, boris.ostrovsky,
	jonah.palmer, raphael, kwolf, hreitz, pasic, borntraeger, farman,
	thuth, richard.henderson, david, iii, cohuck, pbonzini, fam,
	stefanha, qemu-block, qemu-s390x, leiyang, schalla, vattunuru,
	jerinj, dtatulea, virtio-fs

Prevent the realization of a virtio device that attempts to use the
VIRTIO_F_NOTIFICATION_DATA transport feature without disabling
ioeventfd.

Due to ioeventfd not being able to carry the extra data associated with
this feature, having both enabled is a functional mismatch and therefore
Qemu should not continue the device's realization process.

Although the device does not yet know if the feature will be
successfully negotiated, many devices using this feature wont actually
work without this extra data and would fail FEATURES_OK anyway.

If ioeventfd is able to work with the extra notification data in the
future, this compatibility check can be removed.

Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 hw/virtio/virtio.c         | 22 ++++++++++++++++++++++
 include/hw/virtio/virtio.h |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index bcb9e09df0..d0a433b465 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2971,6 +2971,20 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
     return ret;
 }
 
+void virtio_device_check_notification_compatibility(VirtIODevice *vdev,
+                                                    Error **errp)
+{
+    VirtioBusState *bus = VIRTIO_BUS(qdev_get_parent_bus(DEVICE(vdev)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
+    DeviceState *proxy = DEVICE(BUS(bus)->parent);
+
+    if (virtio_host_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA) &&
+        k->ioeventfd_enabled(proxy)) {
+        error_setg(errp,
+                   "notification_data=on without ioeventfd=off is not supported");
+    }
+}
+
 size_t virtio_get_config_size(const VirtIOConfigSizeParams *params,
                               uint64_t host_features)
 {
@@ -3731,6 +3745,14 @@ static void virtio_device_realize(DeviceState *dev, Error **errp)
         }
     }
 
+    /* Devices should not use both ioeventfd and notification data feature */
+    virtio_device_check_notification_compatibility(vdev, &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        vdc->unrealize(dev);
+        return;
+    }
+
     virtio_bus_device_plugged(vdev, &err);
     if (err != NULL) {
         error_propagate(errp, err);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 53915947a7..e0325d84d0 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -346,6 +346,8 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
 void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
 void virtio_update_irq(VirtIODevice *vdev);
 int virtio_set_features(VirtIODevice *vdev, uint64_t val);
+void virtio_device_check_notification_compatibility(VirtIODevice *vdev,
+                                                    Error **errp);
 
 /* Base devices.  */
 typedef struct VirtIOBlkConf VirtIOBlkConf;
-- 
2.39.3


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

* [PATCH v2 3/6] virtio-mmio: Handle extra notification data
  2024-03-13 11:54 [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 2/6] virtio: Prevent creation of device using notification-data with ioeventfd Jonah Palmer
@ 2024-03-13 11:54 ` Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 4/6] virtio-ccw: " Jonah Palmer
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 11:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, eperezma, si-wei.liu, boris.ostrovsky,
	jonah.palmer, raphael, kwolf, hreitz, pasic, borntraeger, farman,
	thuth, richard.henderson, david, iii, cohuck, pbonzini, fam,
	stefanha, qemu-block, qemu-s390x, leiyang, schalla, vattunuru,
	jerinj, dtatulea, virtio-fs

Add support to virtio-mmio devices for handling the extra data sent from
the driver to the device when the VIRTIO_F_NOTIFICATION_DATA transport
feature has been negotiated.

The extra data that's passed to the virtio-mmio device when this feature
is enabled varies depending on the device's virtqueue layout.

The data passed to the virtio-mmio device is in the same format as the
data passed to virtio-pci devices.

Tested-by: Lei Yang <leiyang@redhat.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 hw/virtio/virtio-mmio.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 22f9fbcf5a..f99d5851a2 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -248,6 +248,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
 {
     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    uint16_t vq_idx;
 
     trace_virtio_mmio_write_offset(offset, value);
 
@@ -407,8 +408,12 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
         }
         break;
     case VIRTIO_MMIO_QUEUE_NOTIFY:
-        if (value < VIRTIO_QUEUE_MAX) {
-            virtio_queue_notify(vdev, value);
+        vq_idx = value;
+        if (vq_idx < VIRTIO_QUEUE_MAX) {
+            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
+                virtio_queue_set_shadow_avail_data(vdev, value);
+            }
+            virtio_queue_notify(vdev, vq_idx);
         }
         break;
     case VIRTIO_MMIO_INTERRUPT_ACK:
-- 
2.39.3


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

* [PATCH v2 4/6] virtio-ccw: Handle extra notification data
  2024-03-13 11:54 [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support Jonah Palmer
                   ` (2 preceding siblings ...)
  2024-03-13 11:54 ` [PATCH v2 3/6] virtio-mmio: Handle extra notification data Jonah Palmer
@ 2024-03-13 11:54 ` Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 5/6] vhost/vhost-user: Add VIRTIO_F_NOTIFICATION_DATA to vhost feature bits Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 6/6] virtio: Add VIRTIO_F_NOTIFICATION_DATA property definition Jonah Palmer
  5 siblings, 0 replies; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 11:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, eperezma, si-wei.liu, boris.ostrovsky,
	jonah.palmer, raphael, kwolf, hreitz, pasic, borntraeger, farman,
	thuth, richard.henderson, david, iii, cohuck, pbonzini, fam,
	stefanha, qemu-block, qemu-s390x, leiyang, schalla, vattunuru,
	jerinj, dtatulea, virtio-fs

Add support to virtio-ccw devices for handling the extra data sent from
the driver to the device when the VIRTIO_F_NOTIFICATION_DATA transport
feature has been negotiated.

The extra data that's passed to the virtio-ccw device when this feature
is enabled varies depending on the device's virtqueue layout.

That data passed to the virtio-ccw device is in the same format as the
data passed to virtio-pci devices.

Tested-by: Lei Yang <leiyang@redhat.com>
Acked-by: Eric Farman <farman@linux.ibm.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 hw/s390x/s390-virtio-ccw.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index b1dcb3857f..7631e4aa41 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -140,9 +140,11 @@ static void subsystem_reset(void)
 static int virtio_ccw_hcall_notify(const uint64_t *args)
 {
     uint64_t subch_id = args[0];
-    uint64_t queue = args[1];
+    uint64_t data = args[1];
     SubchDev *sch;
+    VirtIODevice *vdev;
     int cssid, ssid, schid, m;
+    uint16_t vq_idx = data;
 
     if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
         return -EINVAL;
@@ -151,12 +153,18 @@ static int virtio_ccw_hcall_notify(const uint64_t *args)
     if (!sch || !css_subch_visible(sch)) {
         return -EINVAL;
     }
-    if (queue >= VIRTIO_QUEUE_MAX) {
+
+    if (vq_idx >= VIRTIO_QUEUE_MAX) {
         return -EINVAL;
     }
-    virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
-    return 0;
 
+    vdev = virtio_ccw_get_vdev(sch);
+    if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
+        virtio_queue_set_shadow_avail_data(vdev, data);
+    }
+
+    virtio_queue_notify(vdev, vq_idx);
+    return 0;
 }
 
 static int virtio_ccw_hcall_early_printk(const uint64_t *args)
-- 
2.39.3


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

* [PATCH v2 5/6] vhost/vhost-user: Add VIRTIO_F_NOTIFICATION_DATA to vhost feature bits
  2024-03-13 11:54 [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support Jonah Palmer
                   ` (3 preceding siblings ...)
  2024-03-13 11:54 ` [PATCH v2 4/6] virtio-ccw: " Jonah Palmer
@ 2024-03-13 11:54 ` Jonah Palmer
  2024-03-13 11:54 ` [PATCH v2 6/6] virtio: Add VIRTIO_F_NOTIFICATION_DATA property definition Jonah Palmer
  5 siblings, 0 replies; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 11:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, eperezma, si-wei.liu, boris.ostrovsky,
	jonah.palmer, raphael, kwolf, hreitz, pasic, borntraeger, farman,
	thuth, richard.henderson, david, iii, cohuck, pbonzini, fam,
	stefanha, qemu-block, qemu-s390x, leiyang, schalla, vattunuru,
	jerinj, dtatulea, virtio-fs

Add support for the VIRTIO_F_NOTIFICATION_DATA feature across a variety
of vhost devices.

The inclusion of VIRTIO_F_NOTIFICATION_DATA in the feature bits arrays
for these devices ensures that the backend is capable of offering and
providing support for this feature, and that it can be disabled if the
backend does not support it.

Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 hw/block/vhost-user-blk.c    | 1 +
 hw/net/vhost_net.c           | 2 ++
 hw/scsi/vhost-scsi.c         | 1 +
 hw/scsi/vhost-user-scsi.c    | 1 +
 hw/virtio/vhost-user-fs.c    | 2 +-
 hw/virtio/vhost-user-vsock.c | 1 +
 net/vhost-vdpa.c             | 1 +
 7 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 6a856ad51a..983c0657da 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -51,6 +51,7 @@ static const int user_feature_bits[] = {
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_IOMMU_PLATFORM,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
 
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index e8e1661646..bb1f975b39 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -48,6 +48,7 @@ static const int kernel_feature_bits[] = {
     VIRTIO_F_IOMMU_PLATFORM,
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_NOTIFICATION_DATA,
     VIRTIO_NET_F_HASH_REPORT,
     VHOST_INVALID_FEATURE_BIT
 };
@@ -55,6 +56,7 @@ static const int kernel_feature_bits[] = {
 /* Features supported by others. */
 static const int user_feature_bits[] = {
     VIRTIO_F_NOTIFY_ON_EMPTY,
+    VIRTIO_F_NOTIFICATION_DATA,
     VIRTIO_RING_F_INDIRECT_DESC,
     VIRTIO_RING_F_EVENT_IDX,
 
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index ae26bc19a4..3d5fe0994d 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -38,6 +38,7 @@ static const int kernel_feature_bits[] = {
     VIRTIO_RING_F_EVENT_IDX,
     VIRTIO_SCSI_F_HOTPLUG,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
 
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index a63b1f4948..0b050805a8 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -36,6 +36,7 @@ static const int user_feature_bits[] = {
     VIRTIO_RING_F_EVENT_IDX,
     VIRTIO_SCSI_F_HOTPLUG,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
 
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index cca2cd41be..ae48cc1c96 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -33,7 +33,7 @@ static const int user_feature_bits[] = {
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_IOMMU_PLATFORM,
     VIRTIO_F_RING_RESET,
-
+    VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
 
diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c
index 9431b9792c..802b44a07d 100644
--- a/hw/virtio/vhost-user-vsock.c
+++ b/hw/virtio/vhost-user-vsock.c
@@ -21,6 +21,7 @@ static const int user_feature_bits[] = {
     VIRTIO_RING_F_INDIRECT_DESC,
     VIRTIO_RING_F_EVENT_IDX,
     VIRTIO_F_NOTIFY_ON_EMPTY,
+    VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
 
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 2a9ddb4552..5583ce5279 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -61,6 +61,7 @@ const int vdpa_feature_bits[] = {
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_RING_RESET,
     VIRTIO_F_VERSION_1,
+    VIRTIO_F_NOTIFICATION_DATA,
     VIRTIO_NET_F_CSUM,
     VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
     VIRTIO_NET_F_CTRL_MAC_ADDR,
-- 
2.39.3


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

* [PATCH v2 6/6] virtio: Add VIRTIO_F_NOTIFICATION_DATA property definition
  2024-03-13 11:54 [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support Jonah Palmer
                   ` (4 preceding siblings ...)
  2024-03-13 11:54 ` [PATCH v2 5/6] vhost/vhost-user: Add VIRTIO_F_NOTIFICATION_DATA to vhost feature bits Jonah Palmer
@ 2024-03-13 11:54 ` Jonah Palmer
  5 siblings, 0 replies; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 11:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: mst, jasowang, eperezma, si-wei.liu, boris.ostrovsky,
	jonah.palmer, raphael, kwolf, hreitz, pasic, borntraeger, farman,
	thuth, richard.henderson, david, iii, cohuck, pbonzini, fam,
	stefanha, qemu-block, qemu-s390x, leiyang, schalla, vattunuru,
	jerinj, dtatulea, virtio-fs

Extend the virtio device property definitions to include the
VIRTIO_F_NOTIFICATION_DATA feature.

The default state of this feature is disabled, allowing it to be
explicitly enabled where it's supported.

Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
 include/hw/virtio/virtio.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index e0325d84d0..bc54c5e037 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -371,7 +371,9 @@ typedef struct VirtIORNGConf VirtIORNGConf;
     DEFINE_PROP_BIT64("packed", _state, _field, \
                       VIRTIO_F_RING_PACKED, false), \
     DEFINE_PROP_BIT64("queue_reset", _state, _field, \
-                      VIRTIO_F_RING_RESET, true)
+                      VIRTIO_F_RING_RESET, true), \
+    DEFINE_PROP_BIT64("notification_data", _state, _field, \
+                      VIRTIO_F_NOTIFICATION_DATA, false)
 
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
 bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n);
-- 
2.39.3


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

* Re: [PATCH v2 2/6] virtio: Prevent creation of device using notification-data with ioeventfd
  2024-03-13 11:54 ` [PATCH v2 2/6] virtio: Prevent creation of device using notification-data with ioeventfd Jonah Palmer
@ 2024-03-13 14:35   ` Eugenio Perez Martin
  2024-03-13 14:44     ` Jonah Palmer
  0 siblings, 1 reply; 16+ messages in thread
From: Eugenio Perez Martin @ 2024-03-13 14:35 UTC (permalink / raw)
  To: Jonah Palmer
  Cc: qemu-devel, mst, jasowang, si-wei.liu, boris.ostrovsky, raphael,
	kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs

On Wed, Mar 13, 2024 at 12:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>
> Prevent the realization of a virtio device that attempts to use the
> VIRTIO_F_NOTIFICATION_DATA transport feature without disabling
> ioeventfd.
>
> Due to ioeventfd not being able to carry the extra data associated with
> this feature, having both enabled is a functional mismatch and therefore
> Qemu should not continue the device's realization process.
>
> Although the device does not yet know if the feature will be
> successfully negotiated, many devices using this feature wont actually
> work without this extra data and would fail FEATURES_OK anyway.
>
> If ioeventfd is able to work with the extra notification data in the
> future, this compatibility check can be removed.
>
> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
> ---
>  hw/virtio/virtio.c         | 22 ++++++++++++++++++++++
>  include/hw/virtio/virtio.h |  2 ++
>  2 files changed, 24 insertions(+)
>
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index bcb9e09df0..d0a433b465 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -2971,6 +2971,20 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
>      return ret;
>  }
>
> +void virtio_device_check_notification_compatibility(VirtIODevice *vdev,
> +                                                    Error **errp)
> +{
> +    VirtioBusState *bus = VIRTIO_BUS(qdev_get_parent_bus(DEVICE(vdev)));
> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
> +    DeviceState *proxy = DEVICE(BUS(bus)->parent);
> +
> +    if (virtio_host_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA) &&
> +        k->ioeventfd_enabled(proxy)) {
> +        error_setg(errp,
> +                   "notification_data=on without ioeventfd=off is not supported");
> +    }
> +}
> +
>  size_t virtio_get_config_size(const VirtIOConfigSizeParams *params,
>                                uint64_t host_features)
>  {
> @@ -3731,6 +3745,14 @@ static void virtio_device_realize(DeviceState *dev, Error **errp)
>          }
>      }
>
> +    /* Devices should not use both ioeventfd and notification data feature */
> +    virtio_device_check_notification_compatibility(vdev, &err);
> +    if (err != NULL) {
> +        error_propagate(errp, err);
> +        vdc->unrealize(dev);
> +        return;
> +    }
> +
>      virtio_bus_device_plugged(vdev, &err);
>      if (err != NULL) {
>          error_propagate(errp, err);
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 53915947a7..e0325d84d0 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -346,6 +346,8 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
>  void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
>  void virtio_update_irq(VirtIODevice *vdev);
>  int virtio_set_features(VirtIODevice *vdev, uint64_t val);
> +void virtio_device_check_notification_compatibility(VirtIODevice *vdev,
> +                                                    Error **errp);

Why not make it static?

>
>  /* Base devices.  */
>  typedef struct VirtIOBlkConf VirtIOBlkConf;
> --
> 2.39.3
>


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

* Re: [PATCH v2 2/6] virtio: Prevent creation of device using notification-data with ioeventfd
  2024-03-13 14:35   ` Eugenio Perez Martin
@ 2024-03-13 14:44     ` Jonah Palmer
  0 siblings, 0 replies; 16+ messages in thread
From: Jonah Palmer @ 2024-03-13 14:44 UTC (permalink / raw)
  To: Eugenio Perez Martin
  Cc: qemu-devel, mst, jasowang, si-wei.liu, boris.ostrovsky, raphael,
	kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs



On 3/13/24 10:35 AM, Eugenio Perez Martin wrote:
> On Wed, Mar 13, 2024 at 12:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>>
>> Prevent the realization of a virtio device that attempts to use the
>> VIRTIO_F_NOTIFICATION_DATA transport feature without disabling
>> ioeventfd.
>>
>> Due to ioeventfd not being able to carry the extra data associated with
>> this feature, having both enabled is a functional mismatch and therefore
>> Qemu should not continue the device's realization process.
>>
>> Although the device does not yet know if the feature will be
>> successfully negotiated, many devices using this feature wont actually
>> work without this extra data and would fail FEATURES_OK anyway.
>>
>> If ioeventfd is able to work with the extra notification data in the
>> future, this compatibility check can be removed.
>>
>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
>> ---
>>   hw/virtio/virtio.c         | 22 ++++++++++++++++++++++
>>   include/hw/virtio/virtio.h |  2 ++
>>   2 files changed, 24 insertions(+)
>>
>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
>> index bcb9e09df0..d0a433b465 100644
>> --- a/hw/virtio/virtio.c
>> +++ b/hw/virtio/virtio.c
>> @@ -2971,6 +2971,20 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
>>       return ret;
>>   }
>>
>> +void virtio_device_check_notification_compatibility(VirtIODevice *vdev,
>> +                                                    Error **errp)
>> +{
>> +    VirtioBusState *bus = VIRTIO_BUS(qdev_get_parent_bus(DEVICE(vdev)));
>> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
>> +    DeviceState *proxy = DEVICE(BUS(bus)->parent);
>> +
>> +    if (virtio_host_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA) &&
>> +        k->ioeventfd_enabled(proxy)) {
>> +        error_setg(errp,
>> +                   "notification_data=on without ioeventfd=off is not supported");
>> +    }
>> +}
>> +
>>   size_t virtio_get_config_size(const VirtIOConfigSizeParams *params,
>>                                 uint64_t host_features)
>>   {
>> @@ -3731,6 +3745,14 @@ static void virtio_device_realize(DeviceState *dev, Error **errp)
>>           }
>>       }
>>
>> +    /* Devices should not use both ioeventfd and notification data feature */
>> +    virtio_device_check_notification_compatibility(vdev, &err);
>> +    if (err != NULL) {
>> +        error_propagate(errp, err);
>> +        vdc->unrealize(dev);
>> +        return;
>> +    }
>> +
>>       virtio_bus_device_plugged(vdev, &err);
>>       if (err != NULL) {
>>           error_propagate(errp, err);
>> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
>> index 53915947a7..e0325d84d0 100644
>> --- a/include/hw/virtio/virtio.h
>> +++ b/include/hw/virtio/virtio.h
>> @@ -346,6 +346,8 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
>>   void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
>>   void virtio_update_irq(VirtIODevice *vdev);
>>   int virtio_set_features(VirtIODevice *vdev, uint64_t val);
>> +void virtio_device_check_notification_compatibility(VirtIODevice *vdev,
>> +                                                    Error **errp);
> 
> Why not make it static?
> 

Great question with no good answer! Will fix this.

>>
>>   /* Base devices.  */
>>   typedef struct VirtIOBlkConf VirtIOBlkConf;
>> --
>> 2.39.3
>>
> 

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

* Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-13 11:54 ` [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data Jonah Palmer
@ 2024-03-14  3:01   ` Jason Wang
  2024-03-14 12:16     ` Jonah Palmer
  0 siblings, 1 reply; 16+ messages in thread
From: Jason Wang @ 2024-03-14  3:01 UTC (permalink / raw)
  To: Jonah Palmer
  Cc: qemu-devel, mst, eperezma, si-wei.liu, boris.ostrovsky, raphael,
	kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs

On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>
> Add support to virtio-pci devices for handling the extra data sent
> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
> transport feature has been negotiated.
>
> The extra data that's passed to the virtio-pci device when this
> feature is enabled varies depending on the device's virtqueue
> layout.
>
> In a split virtqueue layout, this data includes:
>  - upper 16 bits: shadow_avail_idx
>  - lower 16 bits: virtqueue index
>
> In a packed virtqueue layout, this data includes:
>  - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
>  - lower 16 bits: virtqueue index
>
> Tested-by: Lei Yang <leiyang@redhat.com>
> Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
> ---
>  hw/virtio/virtio-pci.c     | 10 +++++++---
>  hw/virtio/virtio.c         | 18 ++++++++++++++++++
>  include/hw/virtio/virtio.h |  1 +
>  3 files changed, 26 insertions(+), 3 deletions(-)
>
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index cb6940fc0e..0f5c3c3b2f 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>  {
>      VirtIOPCIProxy *proxy = opaque;
>      VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> -    uint16_t vector;
> +    uint16_t vector, vq_idx;
>      hwaddr pa;
>
>      switch (addr) {
> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>              vdev->queue_sel = val;
>          break;
>      case VIRTIO_PCI_QUEUE_NOTIFY:
> -        if (val < VIRTIO_QUEUE_MAX) {
> -            virtio_queue_notify(vdev, val);
> +        vq_idx = val;
> +        if (vq_idx < VIRTIO_QUEUE_MAX) {
> +            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
> +                virtio_queue_set_shadow_avail_data(vdev, val);
> +            }
> +            virtio_queue_notify(vdev, vq_idx);
>          }
>          break;
>      case VIRTIO_PCI_STATUS:
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index d229755eae..bcb9e09df0 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>      }
>  }
>
> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)
> +{
> +    /* Lower 16 bits is the virtqueue index */
> +    uint16_t i = data;
> +    VirtQueue *vq = &vdev->vq[i];
> +
> +    if (!vq->vring.desc) {
> +        return;
> +    }
> +
> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
> +        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
> +        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
> +    } else {
> +        vq->shadow_avail_idx = (data >> 16);

Do we need to do a sanity check for this value?

Thanks

> +    }
> +}
> +
>  static void virtio_queue_notify_vq(VirtQueue *vq)
>  {
>      if (vq->vring.desc && vq->handle_output) {
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index c8f72850bc..53915947a7 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
>  void virtio_init_region_cache(VirtIODevice *vdev, int n);
>  void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>  void virtio_queue_notify(VirtIODevice *vdev, int n);
> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
>  uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
>  void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
>  int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
> --
> 2.39.3
>


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

* Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-14  3:01   ` Jason Wang
@ 2024-03-14 12:16     ` Jonah Palmer
  2024-03-14 14:55       ` Eugenio Perez Martin
  0 siblings, 1 reply; 16+ messages in thread
From: Jonah Palmer @ 2024-03-14 12:16 UTC (permalink / raw)
  To: Jason Wang
  Cc: qemu-devel, mst, eperezma, si-wei.liu, boris.ostrovsky, raphael,
	kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs



On 3/13/24 11:01 PM, Jason Wang wrote:
> On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>>
>> Add support to virtio-pci devices for handling the extra data sent
>> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
>> transport feature has been negotiated.
>>
>> The extra data that's passed to the virtio-pci device when this
>> feature is enabled varies depending on the device's virtqueue
>> layout.
>>
>> In a split virtqueue layout, this data includes:
>>   - upper 16 bits: shadow_avail_idx
>>   - lower 16 bits: virtqueue index
>>
>> In a packed virtqueue layout, this data includes:
>>   - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
>>   - lower 16 bits: virtqueue index
>>
>> Tested-by: Lei Yang <leiyang@redhat.com>
>> Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
>> ---
>>   hw/virtio/virtio-pci.c     | 10 +++++++---
>>   hw/virtio/virtio.c         | 18 ++++++++++++++++++
>>   include/hw/virtio/virtio.h |  1 +
>>   3 files changed, 26 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
>> index cb6940fc0e..0f5c3c3b2f 100644
>> --- a/hw/virtio/virtio-pci.c
>> +++ b/hw/virtio/virtio-pci.c
>> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>>   {
>>       VirtIOPCIProxy *proxy = opaque;
>>       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>> -    uint16_t vector;
>> +    uint16_t vector, vq_idx;
>>       hwaddr pa;
>>
>>       switch (addr) {
>> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>>               vdev->queue_sel = val;
>>           break;
>>       case VIRTIO_PCI_QUEUE_NOTIFY:
>> -        if (val < VIRTIO_QUEUE_MAX) {
>> -            virtio_queue_notify(vdev, val);
>> +        vq_idx = val;
>> +        if (vq_idx < VIRTIO_QUEUE_MAX) {
>> +            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
>> +                virtio_queue_set_shadow_avail_data(vdev, val);
>> +            }
>> +            virtio_queue_notify(vdev, vq_idx);
>>           }
>>           break;
>>       case VIRTIO_PCI_STATUS:
>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
>> index d229755eae..bcb9e09df0 100644
>> --- a/hw/virtio/virtio.c
>> +++ b/hw/virtio/virtio.c
>> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>>       }
>>   }
>>
>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)
>> +{
>> +    /* Lower 16 bits is the virtqueue index */
>> +    uint16_t i = data;
>> +    VirtQueue *vq = &vdev->vq[i];
>> +
>> +    if (!vq->vring.desc) {
>> +        return;
>> +    }
>> +
>> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
>> +        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
>> +        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
>> +    } else {
>> +        vq->shadow_avail_idx = (data >> 16);
> 
> Do we need to do a sanity check for this value?
> 
> Thanks
> 

It can't hurt, right? What kind of check did you have in mind?

if (vq->shadow_avail_idx >= vq->vring.num)

Or something else?

>> +    }
>> +}
>> +
>>   static void virtio_queue_notify_vq(VirtQueue *vq)
>>   {
>>       if (vq->vring.desc && vq->handle_output) {
>> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
>> index c8f72850bc..53915947a7 100644
>> --- a/include/hw/virtio/virtio.h
>> +++ b/include/hw/virtio/virtio.h
>> @@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
>>   void virtio_init_region_cache(VirtIODevice *vdev, int n);
>>   void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>>   void virtio_queue_notify(VirtIODevice *vdev, int n);
>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
>>   uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
>>   void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
>>   int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
>> --
>> 2.39.3
>>
> 

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

* Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-14 12:16     ` Jonah Palmer
@ 2024-03-14 14:55       ` Eugenio Perez Martin
  2024-03-14 16:05         ` Jonah Palmer
  0 siblings, 1 reply; 16+ messages in thread
From: Eugenio Perez Martin @ 2024-03-14 14:55 UTC (permalink / raw)
  To: Jonah Palmer
  Cc: Jason Wang, qemu-devel, mst, si-wei.liu, boris.ostrovsky,
	raphael, kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs

On Thu, Mar 14, 2024 at 1:16 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>
>
>
> On 3/13/24 11:01 PM, Jason Wang wrote:
> > On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
> >>
> >> Add support to virtio-pci devices for handling the extra data sent
> >> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
> >> transport feature has been negotiated.
> >>
> >> The extra data that's passed to the virtio-pci device when this
> >> feature is enabled varies depending on the device's virtqueue
> >> layout.
> >>
> >> In a split virtqueue layout, this data includes:
> >>   - upper 16 bits: shadow_avail_idx
> >>   - lower 16 bits: virtqueue index
> >>
> >> In a packed virtqueue layout, this data includes:
> >>   - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
> >>   - lower 16 bits: virtqueue index
> >>
> >> Tested-by: Lei Yang <leiyang@redhat.com>
> >> Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
> >> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
> >> ---
> >>   hw/virtio/virtio-pci.c     | 10 +++++++---
> >>   hw/virtio/virtio.c         | 18 ++++++++++++++++++
> >>   include/hw/virtio/virtio.h |  1 +
> >>   3 files changed, 26 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> >> index cb6940fc0e..0f5c3c3b2f 100644
> >> --- a/hw/virtio/virtio-pci.c
> >> +++ b/hw/virtio/virtio-pci.c
> >> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
> >>   {
> >>       VirtIOPCIProxy *proxy = opaque;
> >>       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >> -    uint16_t vector;
> >> +    uint16_t vector, vq_idx;
> >>       hwaddr pa;
> >>
> >>       switch (addr) {
> >> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
> >>               vdev->queue_sel = val;
> >>           break;
> >>       case VIRTIO_PCI_QUEUE_NOTIFY:
> >> -        if (val < VIRTIO_QUEUE_MAX) {
> >> -            virtio_queue_notify(vdev, val);
> >> +        vq_idx = val;
> >> +        if (vq_idx < VIRTIO_QUEUE_MAX) {
> >> +            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
> >> +                virtio_queue_set_shadow_avail_data(vdev, val);
> >> +            }
> >> +            virtio_queue_notify(vdev, vq_idx);
> >>           }
> >>           break;
> >>       case VIRTIO_PCI_STATUS:
> >> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> >> index d229755eae..bcb9e09df0 100644
> >> --- a/hw/virtio/virtio.c
> >> +++ b/hw/virtio/virtio.c
> >> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
> >>       }
> >>   }
> >>
> >> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)

Maybe I didn't explain well, but I think it is better to pass directly
idx to a VirtQueue *. That way only the caller needs to check for a
valid vq idx, and (my understanding is) the virtio.c interface is
migrating to VirtQueue * use anyway.

> >> +{
> >> +    /* Lower 16 bits is the virtqueue index */
> >> +    uint16_t i = data;
> >> +    VirtQueue *vq = &vdev->vq[i];
> >> +
> >> +    if (!vq->vring.desc) {
> >> +        return;
> >> +    }
> >> +
> >> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
> >> +        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
> >> +        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
> >> +    } else {
> >> +        vq->shadow_avail_idx = (data >> 16);
> >
> > Do we need to do a sanity check for this value?
> >
> > Thanks
> >
>
> It can't hurt, right? What kind of check did you have in mind?
>
> if (vq->shadow_avail_idx >= vq->vring.num)
>

I'm a little bit lost too. shadow_avail_idx can take all uint16_t
values. Maybe you meant checking for a valid vq index, Jason?

Thanks!

> Or something else?
>
> >> +    }
> >> +}
> >> +
> >>   static void virtio_queue_notify_vq(VirtQueue *vq)
> >>   {
> >>       if (vq->vring.desc && vq->handle_output) {
> >> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> >> index c8f72850bc..53915947a7 100644
> >> --- a/include/hw/virtio/virtio.h
> >> +++ b/include/hw/virtio/virtio.h
> >> @@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
> >>   void virtio_init_region_cache(VirtIODevice *vdev, int n);
> >>   void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
> >>   void virtio_queue_notify(VirtIODevice *vdev, int n);
> >> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
> >>   uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
> >>   void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
> >>   int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
> >> --
> >> 2.39.3
> >>
> >
>


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

* Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-14 14:55       ` Eugenio Perez Martin
@ 2024-03-14 16:05         ` Jonah Palmer
  2024-03-14 19:05           ` Eugenio Perez Martin
  0 siblings, 1 reply; 16+ messages in thread
From: Jonah Palmer @ 2024-03-14 16:05 UTC (permalink / raw)
  To: Eugenio Perez Martin
  Cc: Jason Wang, qemu-devel, mst, si-wei.liu, boris.ostrovsky,
	raphael, kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs



On 3/14/24 10:55 AM, Eugenio Perez Martin wrote:
> On Thu, Mar 14, 2024 at 1:16 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>>
>>
>>
>> On 3/13/24 11:01 PM, Jason Wang wrote:
>>> On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>>>>
>>>> Add support to virtio-pci devices for handling the extra data sent
>>>> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
>>>> transport feature has been negotiated.
>>>>
>>>> The extra data that's passed to the virtio-pci device when this
>>>> feature is enabled varies depending on the device's virtqueue
>>>> layout.
>>>>
>>>> In a split virtqueue layout, this data includes:
>>>>    - upper 16 bits: shadow_avail_idx
>>>>    - lower 16 bits: virtqueue index
>>>>
>>>> In a packed virtqueue layout, this data includes:
>>>>    - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
>>>>    - lower 16 bits: virtqueue index
>>>>
>>>> Tested-by: Lei Yang <leiyang@redhat.com>
>>>> Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
>>>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
>>>> ---
>>>>    hw/virtio/virtio-pci.c     | 10 +++++++---
>>>>    hw/virtio/virtio.c         | 18 ++++++++++++++++++
>>>>    include/hw/virtio/virtio.h |  1 +
>>>>    3 files changed, 26 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
>>>> index cb6940fc0e..0f5c3c3b2f 100644
>>>> --- a/hw/virtio/virtio-pci.c
>>>> +++ b/hw/virtio/virtio-pci.c
>>>> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>>>>    {
>>>>        VirtIOPCIProxy *proxy = opaque;
>>>>        VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>>>> -    uint16_t vector;
>>>> +    uint16_t vector, vq_idx;
>>>>        hwaddr pa;
>>>>
>>>>        switch (addr) {
>>>> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>>>>                vdev->queue_sel = val;
>>>>            break;
>>>>        case VIRTIO_PCI_QUEUE_NOTIFY:
>>>> -        if (val < VIRTIO_QUEUE_MAX) {
>>>> -            virtio_queue_notify(vdev, val);
>>>> +        vq_idx = val;
>>>> +        if (vq_idx < VIRTIO_QUEUE_MAX) {
>>>> +            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
>>>> +                virtio_queue_set_shadow_avail_data(vdev, val);
>>>> +            }
>>>> +            virtio_queue_notify(vdev, vq_idx);
>>>>            }
>>>>            break;
>>>>        case VIRTIO_PCI_STATUS:
>>>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
>>>> index d229755eae..bcb9e09df0 100644
>>>> --- a/hw/virtio/virtio.c
>>>> +++ b/hw/virtio/virtio.c
>>>> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>>>>        }
>>>>    }
>>>>
>>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)
> 
> Maybe I didn't explain well, but I think it is better to pass directly
> idx to a VirtQueue *. That way only the caller needs to check for a
> valid vq idx, and (my understanding is) the virtio.c interface is
> migrating to VirtQueue * use anyway.
> 

Oh, are you saying to just pass in a VirtQueue *vq instead of 
VirtIODevice *vdev and get rid of the vq->vring.desc check in the function?

>>>> +{
>>>> +    /* Lower 16 bits is the virtqueue index */
>>>> +    uint16_t i = data;
>>>> +    VirtQueue *vq = &vdev->vq[i];
>>>> +
>>>> +    if (!vq->vring.desc) {
>>>> +        return;
>>>> +    }
>>>> +
>>>> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
>>>> +        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
>>>> +        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
>>>> +    } else {
>>>> +        vq->shadow_avail_idx = (data >> 16);
>>>
>>> Do we need to do a sanity check for this value?
>>>
>>> Thanks
>>>
>>
>> It can't hurt, right? What kind of check did you have in mind?
>>
>> if (vq->shadow_avail_idx >= vq->vring.num)
>>
> 
> I'm a little bit lost too. shadow_avail_idx can take all uint16_t
> values. Maybe you meant checking for a valid vq index, Jason?
> 
> Thanks!
> 
>> Or something else?
>>
>>>> +    }
>>>> +}
>>>> +
>>>>    static void virtio_queue_notify_vq(VirtQueue *vq)
>>>>    {
>>>>        if (vq->vring.desc && vq->handle_output) {
>>>> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
>>>> index c8f72850bc..53915947a7 100644
>>>> --- a/include/hw/virtio/virtio.h
>>>> +++ b/include/hw/virtio/virtio.h
>>>> @@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
>>>>    void virtio_init_region_cache(VirtIODevice *vdev, int n);
>>>>    void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>>>>    void virtio_queue_notify(VirtIODevice *vdev, int n);
>>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
>>>>    uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
>>>>    void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
>>>>    int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
>>>> --
>>>> 2.39.3
>>>>
>>>
>>
> 

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

* Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-14 16:05         ` Jonah Palmer
@ 2024-03-14 19:05           ` Eugenio Perez Martin
  2024-03-14 20:23             ` Jonah Palmer
  0 siblings, 1 reply; 16+ messages in thread
From: Eugenio Perez Martin @ 2024-03-14 19:05 UTC (permalink / raw)
  To: Jonah Palmer
  Cc: Jason Wang, qemu-devel, mst, si-wei.liu, boris.ostrovsky,
	raphael, kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs

On Thu, Mar 14, 2024 at 5:06 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>
>
>
> On 3/14/24 10:55 AM, Eugenio Perez Martin wrote:
> > On Thu, Mar 14, 2024 at 1:16 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
> >>
> >>
> >>
> >> On 3/13/24 11:01 PM, Jason Wang wrote:
> >>> On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
> >>>>
> >>>> Add support to virtio-pci devices for handling the extra data sent
> >>>> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
> >>>> transport feature has been negotiated.
> >>>>
> >>>> The extra data that's passed to the virtio-pci device when this
> >>>> feature is enabled varies depending on the device's virtqueue
> >>>> layout.
> >>>>
> >>>> In a split virtqueue layout, this data includes:
> >>>>    - upper 16 bits: shadow_avail_idx
> >>>>    - lower 16 bits: virtqueue index
> >>>>
> >>>> In a packed virtqueue layout, this data includes:
> >>>>    - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
> >>>>    - lower 16 bits: virtqueue index
> >>>>
> >>>> Tested-by: Lei Yang <leiyang@redhat.com>
> >>>> Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
> >>>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
> >>>> ---
> >>>>    hw/virtio/virtio-pci.c     | 10 +++++++---
> >>>>    hw/virtio/virtio.c         | 18 ++++++++++++++++++
> >>>>    include/hw/virtio/virtio.h |  1 +
> >>>>    3 files changed, 26 insertions(+), 3 deletions(-)
> >>>>
> >>>> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> >>>> index cb6940fc0e..0f5c3c3b2f 100644
> >>>> --- a/hw/virtio/virtio-pci.c
> >>>> +++ b/hw/virtio/virtio-pci.c
> >>>> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
> >>>>    {
> >>>>        VirtIOPCIProxy *proxy = opaque;
> >>>>        VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >>>> -    uint16_t vector;
> >>>> +    uint16_t vector, vq_idx;
> >>>>        hwaddr pa;
> >>>>
> >>>>        switch (addr) {
> >>>> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
> >>>>                vdev->queue_sel = val;
> >>>>            break;
> >>>>        case VIRTIO_PCI_QUEUE_NOTIFY:
> >>>> -        if (val < VIRTIO_QUEUE_MAX) {
> >>>> -            virtio_queue_notify(vdev, val);
> >>>> +        vq_idx = val;
> >>>> +        if (vq_idx < VIRTIO_QUEUE_MAX) {
> >>>> +            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
> >>>> +                virtio_queue_set_shadow_avail_data(vdev, val);
> >>>> +            }
> >>>> +            virtio_queue_notify(vdev, vq_idx);
> >>>>            }
> >>>>            break;
> >>>>        case VIRTIO_PCI_STATUS:
> >>>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> >>>> index d229755eae..bcb9e09df0 100644
> >>>> --- a/hw/virtio/virtio.c
> >>>> +++ b/hw/virtio/virtio.c
> >>>> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
> >>>>        }
> >>>>    }
> >>>>
> >>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)
> >
> > Maybe I didn't explain well, but I think it is better to pass directly
> > idx to a VirtQueue *. That way only the caller needs to check for a
> > valid vq idx, and (my understanding is) the virtio.c interface is
> > migrating to VirtQueue * use anyway.
> >
>
> Oh, are you saying to just pass in a VirtQueue *vq instead of
> VirtIODevice *vdev and get rid of the vq->vring.desc check in the function?
>

No, that needs to be kept. I meant the access to vdev->vq[i] without
checking for a valid i.

You can get the VirtQueue in the caller with virtio_get_queue. Which
also does not check for a valid index, but that way is clearer the
caller needs to check it.

As a side note, the check for desc != 0 is widespread in QEMU but the
driver may use 0 address for desc, so it's not 100% valid. But to
change that now requires a deeper change out of the scope of this
series, so let's keep it for now :).

Thanks!

> >>>> +{
> >>>> +    /* Lower 16 bits is the virtqueue index */
> >>>> +    uint16_t i = data;
> >>>> +    VirtQueue *vq = &vdev->vq[i];
> >>>> +
> >>>> +    if (!vq->vring.desc) {
> >>>> +        return;
> >>>> +    }
> >>>> +
> >>>> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
> >>>> +        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
> >>>> +        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
> >>>> +    } else {
> >>>> +        vq->shadow_avail_idx = (data >> 16);
> >>>
> >>> Do we need to do a sanity check for this value?
> >>>
> >>> Thanks
> >>>
> >>
> >> It can't hurt, right? What kind of check did you have in mind?
> >>
> >> if (vq->shadow_avail_idx >= vq->vring.num)
> >>
> >
> > I'm a little bit lost too. shadow_avail_idx can take all uint16_t
> > values. Maybe you meant checking for a valid vq index, Jason?
> >
> > Thanks!
> >
> >> Or something else?
> >>
> >>>> +    }
> >>>> +}
> >>>> +
> >>>>    static void virtio_queue_notify_vq(VirtQueue *vq)
> >>>>    {
> >>>>        if (vq->vring.desc && vq->handle_output) {
> >>>> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> >>>> index c8f72850bc..53915947a7 100644
> >>>> --- a/include/hw/virtio/virtio.h
> >>>> +++ b/include/hw/virtio/virtio.h
> >>>> @@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
> >>>>    void virtio_init_region_cache(VirtIODevice *vdev, int n);
> >>>>    void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
> >>>>    void virtio_queue_notify(VirtIODevice *vdev, int n);
> >>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
> >>>>    uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
> >>>>    void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
> >>>>    int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
> >>>> --
> >>>> 2.39.3
> >>>>
> >>>
> >>
> >
>


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

* Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-14 19:05           ` Eugenio Perez Martin
@ 2024-03-14 20:23             ` Jonah Palmer
  2024-03-15  9:23               ` Eugenio Perez Martin
  0 siblings, 1 reply; 16+ messages in thread
From: Jonah Palmer @ 2024-03-14 20:23 UTC (permalink / raw)
  To: Eugenio Perez Martin
  Cc: Jason Wang, qemu-devel, mst, si-wei.liu, boris.ostrovsky,
	raphael, kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs



On 3/14/24 3:05 PM, Eugenio Perez Martin wrote:
> On Thu, Mar 14, 2024 at 5:06 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>>
>>
>>
>> On 3/14/24 10:55 AM, Eugenio Perez Martin wrote:
>>> On Thu, Mar 14, 2024 at 1:16 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>>>>
>>>>
>>>>
>>>> On 3/13/24 11:01 PM, Jason Wang wrote:
>>>>> On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>>>>>>
>>>>>> Add support to virtio-pci devices for handling the extra data sent
>>>>>> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
>>>>>> transport feature has been negotiated.
>>>>>>
>>>>>> The extra data that's passed to the virtio-pci device when this
>>>>>> feature is enabled varies depending on the device's virtqueue
>>>>>> layout.
>>>>>>
>>>>>> In a split virtqueue layout, this data includes:
>>>>>>     - upper 16 bits: shadow_avail_idx
>>>>>>     - lower 16 bits: virtqueue index
>>>>>>
>>>>>> In a packed virtqueue layout, this data includes:
>>>>>>     - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
>>>>>>     - lower 16 bits: virtqueue index
>>>>>>
>>>>>> Tested-by: Lei Yang <leiyang@redhat.com>
>>>>>> Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
>>>>>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
>>>>>> ---
>>>>>>     hw/virtio/virtio-pci.c     | 10 +++++++---
>>>>>>     hw/virtio/virtio.c         | 18 ++++++++++++++++++
>>>>>>     include/hw/virtio/virtio.h |  1 +
>>>>>>     3 files changed, 26 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
>>>>>> index cb6940fc0e..0f5c3c3b2f 100644
>>>>>> --- a/hw/virtio/virtio-pci.c
>>>>>> +++ b/hw/virtio/virtio-pci.c
>>>>>> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>>>>>>     {
>>>>>>         VirtIOPCIProxy *proxy = opaque;
>>>>>>         VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>>>>>> -    uint16_t vector;
>>>>>> +    uint16_t vector, vq_idx;
>>>>>>         hwaddr pa;
>>>>>>
>>>>>>         switch (addr) {
>>>>>> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>>>>>>                 vdev->queue_sel = val;
>>>>>>             break;
>>>>>>         case VIRTIO_PCI_QUEUE_NOTIFY:
>>>>>> -        if (val < VIRTIO_QUEUE_MAX) {
>>>>>> -            virtio_queue_notify(vdev, val);
>>>>>> +        vq_idx = val;
>>>>>> +        if (vq_idx < VIRTIO_QUEUE_MAX) {
>>>>>> +            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
>>>>>> +                virtio_queue_set_shadow_avail_data(vdev, val);
>>>>>> +            }
>>>>>> +            virtio_queue_notify(vdev, vq_idx);
>>>>>>             }
>>>>>>             break;
>>>>>>         case VIRTIO_PCI_STATUS:
>>>>>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
>>>>>> index d229755eae..bcb9e09df0 100644
>>>>>> --- a/hw/virtio/virtio.c
>>>>>> +++ b/hw/virtio/virtio.c
>>>>>> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
>>>>>>         }
>>>>>>     }
>>>>>>
>>>>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)
>>>
>>> Maybe I didn't explain well, but I think it is better to pass directly
>>> idx to a VirtQueue *. That way only the caller needs to check for a
>>> valid vq idx, and (my understanding is) the virtio.c interface is
>>> migrating to VirtQueue * use anyway.
>>>
>>
>> Oh, are you saying to just pass in a VirtQueue *vq instead of
>> VirtIODevice *vdev and get rid of the vq->vring.desc check in the function?
>>
> 
> No, that needs to be kept. I meant the access to vdev->vq[i] without
> checking for a valid i.
> 

Ahh okay I see what you mean. But I thought the following was checking 
for a valid VQ index:

if (vq_idx < VIRTIO_QUEUE_MAX)

Of course the virtio device may not have up to VIRTIO_QUEUE_MAX 
virtqueues, so maybe we should be checking for validity like this?

if (vdev->vq[i].vring.num == 0)

Or was there something else you had in mind? Apologies for the confusion.

> You can get the VirtQueue in the caller with virtio_get_queue. Which
> also does not check for a valid index, but that way is clearer the
> caller needs to check it.
> 

Roger, I'll use this instead for clarity.

> As a side note, the check for desc != 0 is widespread in QEMU but the
> driver may use 0 address for desc, so it's not 100% valid. But to
> change that now requires a deeper change out of the scope of this
> series, so let's keep it for now :).
> 
> Thanks! >

I'll add it to the todo list =]

>>>>>> +{
>>>>>> +    /* Lower 16 bits is the virtqueue index */
>>>>>> +    uint16_t i = data;
>>>>>> +    VirtQueue *vq = &vdev->vq[i];
>>>>>> +
>>>>>> +    if (!vq->vring.desc) {
>>>>>> +        return;
>>>>>> +    }
>>>>>> +
>>>>>> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
>>>>>> +        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
>>>>>> +        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
>>>>>> +    } else {
>>>>>> +        vq->shadow_avail_idx = (data >> 16);
>>>>>
>>>>> Do we need to do a sanity check for this value?
>>>>>
>>>>> Thanks
>>>>>
>>>>
>>>> It can't hurt, right? What kind of check did you have in mind?
>>>>
>>>> if (vq->shadow_avail_idx >= vq->vring.num)
>>>>
>>>
>>> I'm a little bit lost too. shadow_avail_idx can take all uint16_t
>>> values. Maybe you meant checking for a valid vq index, Jason?
>>>
>>> Thanks!
>>>
>>>> Or something else?
>>>>
>>>>>> +    }
>>>>>> +}
>>>>>> +
>>>>>>     static void virtio_queue_notify_vq(VirtQueue *vq)
>>>>>>     {
>>>>>>         if (vq->vring.desc && vq->handle_output) {
>>>>>> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
>>>>>> index c8f72850bc..53915947a7 100644
>>>>>> --- a/include/hw/virtio/virtio.h
>>>>>> +++ b/include/hw/virtio/virtio.h
>>>>>> @@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
>>>>>>     void virtio_init_region_cache(VirtIODevice *vdev, int n);
>>>>>>     void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
>>>>>>     void virtio_queue_notify(VirtIODevice *vdev, int n);
>>>>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
>>>>>>     uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
>>>>>>     void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
>>>>>>     int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
>>>>>> --
>>>>>> 2.39.3
>>>>>>
>>>>>
>>>>
>>>
>>
> 

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

* Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data
  2024-03-14 20:23             ` Jonah Palmer
@ 2024-03-15  9:23               ` Eugenio Perez Martin
  0 siblings, 0 replies; 16+ messages in thread
From: Eugenio Perez Martin @ 2024-03-15  9:23 UTC (permalink / raw)
  To: Jonah Palmer
  Cc: Jason Wang, qemu-devel, mst, si-wei.liu, boris.ostrovsky,
	raphael, kwolf, hreitz, pasic, borntraeger, farman, thuth,
	richard.henderson, david, iii, cohuck, pbonzini, fam, stefanha,
	qemu-block, qemu-s390x, leiyang, schalla, vattunuru, jerinj,
	dtatulea, virtio-fs

On Thu, Mar 14, 2024 at 9:24 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
>
>
>
> On 3/14/24 3:05 PM, Eugenio Perez Martin wrote:
> > On Thu, Mar 14, 2024 at 5:06 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
> >>
> >>
> >>
> >> On 3/14/24 10:55 AM, Eugenio Perez Martin wrote:
> >>> On Thu, Mar 14, 2024 at 1:16 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 3/13/24 11:01 PM, Jason Wang wrote:
> >>>>> On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer <jonah.palmer@oracle.com> wrote:
> >>>>>>
> >>>>>> Add support to virtio-pci devices for handling the extra data sent
> >>>>>> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
> >>>>>> transport feature has been negotiated.
> >>>>>>
> >>>>>> The extra data that's passed to the virtio-pci device when this
> >>>>>> feature is enabled varies depending on the device's virtqueue
> >>>>>> layout.
> >>>>>>
> >>>>>> In a split virtqueue layout, this data includes:
> >>>>>>     - upper 16 bits: shadow_avail_idx
> >>>>>>     - lower 16 bits: virtqueue index
> >>>>>>
> >>>>>> In a packed virtqueue layout, this data includes:
> >>>>>>     - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
> >>>>>>     - lower 16 bits: virtqueue index
> >>>>>>
> >>>>>> Tested-by: Lei Yang <leiyang@redhat.com>
> >>>>>> Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
> >>>>>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
> >>>>>> ---
> >>>>>>     hw/virtio/virtio-pci.c     | 10 +++++++---
> >>>>>>     hw/virtio/virtio.c         | 18 ++++++++++++++++++
> >>>>>>     include/hw/virtio/virtio.h |  1 +
> >>>>>>     3 files changed, 26 insertions(+), 3 deletions(-)
> >>>>>>
> >>>>>> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> >>>>>> index cb6940fc0e..0f5c3c3b2f 100644
> >>>>>> --- a/hw/virtio/virtio-pci.c
> >>>>>> +++ b/hw/virtio/virtio-pci.c
> >>>>>> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
> >>>>>>     {
> >>>>>>         VirtIOPCIProxy *proxy = opaque;
> >>>>>>         VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >>>>>> -    uint16_t vector;
> >>>>>> +    uint16_t vector, vq_idx;
> >>>>>>         hwaddr pa;
> >>>>>>
> >>>>>>         switch (addr) {
> >>>>>> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
> >>>>>>                 vdev->queue_sel = val;
> >>>>>>             break;
> >>>>>>         case VIRTIO_PCI_QUEUE_NOTIFY:
> >>>>>> -        if (val < VIRTIO_QUEUE_MAX) {
> >>>>>> -            virtio_queue_notify(vdev, val);
> >>>>>> +        vq_idx = val;
> >>>>>> +        if (vq_idx < VIRTIO_QUEUE_MAX) {
> >>>>>> +            if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
> >>>>>> +                virtio_queue_set_shadow_avail_data(vdev, val);
> >>>>>> +            }
> >>>>>> +            virtio_queue_notify(vdev, vq_idx);
> >>>>>>             }
> >>>>>>             break;
> >>>>>>         case VIRTIO_PCI_STATUS:
> >>>>>> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> >>>>>> index d229755eae..bcb9e09df0 100644
> >>>>>> --- a/hw/virtio/virtio.c
> >>>>>> +++ b/hw/virtio/virtio.c
> >>>>>> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
> >>>>>>         }
> >>>>>>     }
> >>>>>>
> >>>>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data)
> >>>
> >>> Maybe I didn't explain well, but I think it is better to pass directly
> >>> idx to a VirtQueue *. That way only the caller needs to check for a
> >>> valid vq idx, and (my understanding is) the virtio.c interface is
> >>> migrating to VirtQueue * use anyway.
> >>>
> >>
> >> Oh, are you saying to just pass in a VirtQueue *vq instead of
> >> VirtIODevice *vdev and get rid of the vq->vring.desc check in the function?
> >>
> >
> > No, that needs to be kept. I meant the access to vdev->vq[i] without
> > checking for a valid i.
> >
>
> Ahh okay I see what you mean. But I thought the following was checking
> for a valid VQ index:
>
> if (vq_idx < VIRTIO_QUEUE_MAX)
>

Right, but then the (potentially multiple) callers are responsible to
check for that. If we accept a VirtQueue *, it is assumed it is valid
already.

> Of course the virtio device may not have up to VIRTIO_QUEUE_MAX
> virtqueues, so maybe we should be checking for validity like this?
>
> if (vdev->vq[i].vring.num == 0)
>

Actually yes, if you're going to send a new version I think checking
against num is better. Good find!

> Or was there something else you had in mind? Apologies for the confusion.
>

No worries, virtio.c is full of checks like that :).

Thanks!

> > You can get the VirtQueue in the caller with virtio_get_queue. Which
> > also does not check for a valid index, but that way is clearer the
> > caller needs to check it.
> >
>
> Roger, I'll use this instead for clarity.
>
> > As a side note, the check for desc != 0 is widespread in QEMU but the
> > driver may use 0 address for desc, so it's not 100% valid. But to
> > change that now requires a deeper change out of the scope of this
> > series, so let's keep it for now :).
> >
> > Thanks! >
>
> I'll add it to the todo list =]
>
> >>>>>> +{
> >>>>>> +    /* Lower 16 bits is the virtqueue index */
> >>>>>> +    uint16_t i = data;
> >>>>>> +    VirtQueue *vq = &vdev->vq[i];
> >>>>>> +
> >>>>>> +    if (!vq->vring.desc) {
> >>>>>> +        return;
> >>>>>> +    }
> >>>>>> +
> >>>>>> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
> >>>>>> +        vq->shadow_avail_wrap_counter = (data >> 31) & 0x1;
> >>>>>> +        vq->shadow_avail_idx = (data >> 16) & 0x7FFF;
> >>>>>> +    } else {
> >>>>>> +        vq->shadow_avail_idx = (data >> 16);
> >>>>>
> >>>>> Do we need to do a sanity check for this value?
> >>>>>
> >>>>> Thanks
> >>>>>
> >>>>
> >>>> It can't hurt, right? What kind of check did you have in mind?
> >>>>
> >>>> if (vq->shadow_avail_idx >= vq->vring.num)
> >>>>
> >>>
> >>> I'm a little bit lost too. shadow_avail_idx can take all uint16_t
> >>> values. Maybe you meant checking for a valid vq index, Jason?
> >>>
> >>> Thanks!
> >>>
> >>>> Or something else?
> >>>>
> >>>>>> +    }
> >>>>>> +}
> >>>>>> +
> >>>>>>     static void virtio_queue_notify_vq(VirtQueue *vq)
> >>>>>>     {
> >>>>>>         if (vq->vring.desc && vq->handle_output) {
> >>>>>> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> >>>>>> index c8f72850bc..53915947a7 100644
> >>>>>> --- a/include/hw/virtio/virtio.h
> >>>>>> +++ b/include/hw/virtio/virtio.h
> >>>>>> @@ -335,6 +335,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n);
> >>>>>>     void virtio_init_region_cache(VirtIODevice *vdev, int n);
> >>>>>>     void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
> >>>>>>     void virtio_queue_notify(VirtIODevice *vdev, int n);
> >>>>>> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t data);
> >>>>>>     uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
> >>>>>>     void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
> >>>>>>     int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
> >>>>>> --
> >>>>>> 2.39.3
> >>>>>>
> >>>>>
> >>>>
> >>>
> >>
> >
>


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

end of thread, other threads:[~2024-03-15  9:24 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-13 11:54 [PATCH v2 0/6] virtio,vhost: Add VIRTIO_F_NOTIFICATION_DATA support Jonah Palmer
2024-03-13 11:54 ` [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data Jonah Palmer
2024-03-14  3:01   ` Jason Wang
2024-03-14 12:16     ` Jonah Palmer
2024-03-14 14:55       ` Eugenio Perez Martin
2024-03-14 16:05         ` Jonah Palmer
2024-03-14 19:05           ` Eugenio Perez Martin
2024-03-14 20:23             ` Jonah Palmer
2024-03-15  9:23               ` Eugenio Perez Martin
2024-03-13 11:54 ` [PATCH v2 2/6] virtio: Prevent creation of device using notification-data with ioeventfd Jonah Palmer
2024-03-13 14:35   ` Eugenio Perez Martin
2024-03-13 14:44     ` Jonah Palmer
2024-03-13 11:54 ` [PATCH v2 3/6] virtio-mmio: Handle extra notification data Jonah Palmer
2024-03-13 11:54 ` [PATCH v2 4/6] virtio-ccw: " Jonah Palmer
2024-03-13 11:54 ` [PATCH v2 5/6] vhost/vhost-user: Add VIRTIO_F_NOTIFICATION_DATA to vhost feature bits Jonah Palmer
2024-03-13 11:54 ` [PATCH v2 6/6] virtio: Add VIRTIO_F_NOTIFICATION_DATA property definition Jonah Palmer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).