Hi,

On 4/6/26 14:44, Bin Guo wrote:
vhost_virtqueue_start() unmasks the call notifier by calling
vhost_virtqueue_mask(), whose vhost_set_vring_call ioctl can fail
(closed vhost-user socket, kernel ENOMEM, revoked guest_notifier fd)
but whose void signature throws the error away. vhost_dev_start()
then reports success while the backend has no valid call eventfd for
that vq, leaving the guest with a working kick path but no virtqueue
interrupts -- a half-up state harder to diagnose than a clean failure.

Make vhost_virtqueue_mask() return int and handle the error in the
start path via the existing fail_vector unwind. Other callers reach
the function through VirtioDeviceClass.guest_notifier_mask, whose
void signature offers no upward error channel; they invoke it as a
statement and remain source-compatible.

Resolves a long-standing TODO at the unmask call.

Signed-off-by: Bin Guo <[email protected]>
---
  hw/virtio/vhost.c         | 12 +++++++++---
  include/hw/virtio/vhost.h |  4 ++--
  2 files changed, 11 insertions(+), 5 deletions(-)


  /* Mask/unmask events from this vq. */
-void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
+int vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
                           bool mask)
  {
      struct VirtQueue *vvq = virtio_get_queue(vdev, n);
@@ -1836,7 +1839,10 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, 
VirtIODevice *vdev, int n,
      r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
      if (r < 0) {
          error_report("vhost_set_vring_call failed %d", -r);

IIUC the intention behind this TODO is to convert to "a function
returning a boolean and taking Error** as last argument", replacing
this call with error_setg_errno().

See in "Error reporting system loosely patterned after Glib's GError"
rules in "qapi/error.h".

+        return r;
      }
+
+    return 0;
  }


Reply via email to