aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <khlebnikov@yandex-team.ru>2022-06-23 19:13:25 +0300
committerMichael S. Tsirkin <mst@redhat.com>2022-06-27 18:53:18 -0400
commitae50ae0b91bb5bebb0d074afaecba027d8da16a1 (patch)
tree93f8cb1f2a146a1d5f36ed5dbaa71fb830ab8b68 /hw/virtio
parent60dc3c5be9ce67f4195c432b22a88d8af6429d80 (diff)
downloadqemu-ae50ae0b91bb5bebb0d074afaecba027d8da16a1.zip
qemu-ae50ae0b91bb5bebb0d074afaecba027d8da16a1.tar.gz
qemu-ae50ae0b91bb5bebb0d074afaecba027d8da16a1.tar.bz2
vhost: setup error eventfd and dump errors
Vhost has error notifications, let's log them like other errors. For each virt-queue setup eventfd for vring error notifications. Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> [vsementsov: rename patch, change commit message and dump error like other errors in the file] Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Message-Id: <20220623161325.18813-3-vsementsov@yandex-team.ru> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Roman Kagan <rvkagan@yandex-team.ru>
Diffstat (limited to 'hw/virtio')
-rw-r--r--hw/virtio/vhost.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 6c41fa1..0827d63 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1278,6 +1278,19 @@ static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev,
return 0;
}
+static void vhost_virtqueue_error_notifier(EventNotifier *n)
+{
+ struct vhost_virtqueue *vq = container_of(n, struct vhost_virtqueue,
+ error_notifier);
+ struct vhost_dev *dev = vq->dev;
+ int index = vq - dev->vqs;
+
+ if (event_notifier_test_and_clear(n) && dev->vdev) {
+ VHOST_OPS_DEBUG(-EINVAL, "vhost vring error in virtqueue %d",
+ dev->vq_index + index);
+ }
+}
+
static int vhost_virtqueue_init(struct vhost_dev *dev,
struct vhost_virtqueue *vq, int n)
{
@@ -1299,7 +1312,27 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
vq->dev = dev;
+ if (dev->vhost_ops->vhost_set_vring_err) {
+ r = event_notifier_init(&vq->error_notifier, 0);
+ if (r < 0) {
+ goto fail_call;
+ }
+
+ file.fd = event_notifier_get_fd(&vq->error_notifier);
+ r = dev->vhost_ops->vhost_set_vring_err(dev, &file);
+ if (r) {
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_err failed");
+ goto fail_err;
+ }
+
+ event_notifier_set_handler(&vq->error_notifier,
+ vhost_virtqueue_error_notifier);
+ }
+
return 0;
+
+fail_err:
+ event_notifier_cleanup(&vq->error_notifier);
fail_call:
event_notifier_cleanup(&vq->masked_notifier);
return r;
@@ -1308,6 +1341,10 @@ fail_call:
static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
{
event_notifier_cleanup(&vq->masked_notifier);
+ if (vq->dev->vhost_ops->vhost_set_vring_err) {
+ event_notifier_set_handler(&vq->error_notifier, NULL);
+ event_notifier_cleanup(&vq->error_notifier);
+ }
}
int vhost_dev_init(struct vhost_dev *hdev, void *opaque,