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;
}