static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign, bool with_irqfd) { VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); VirtQueue *vq = virtio_get_queue(vdev, n); EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); if (assign) { int r = event_notifier_init(notifier, 0); if (r < 0) { return r; } virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); } else { virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); event_notifier_cleanup(notifier); } if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) { vdc->guest_notifier_mask(vdev, n, !assign); } return 0; }
static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n, bool assign, bool with_irqfd) { VirtQueue *vq = virtio_get_queue(dev->vdev, n); EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev); if (assign) { int r = event_notifier_init(notifier, 0); if (r < 0) { return r; } virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); /* We do not support irqfd for classic I/O interrupts, because the * classic interrupts are intermixed with the subchannel status, that * is queried with test subchannel. We want to use vhost, though. * Lets make sure to have vhost running and wire up the irq fd to * land in qemu (and only the irq fd) in this code. */ if (k->guest_notifier_mask) { k->guest_notifier_mask(dev->vdev, n, false); } /* get lost events and re-inject */ if (k->guest_notifier_pending && k->guest_notifier_pending(dev->vdev, n)) { event_notifier_set(notifier); } } else { if (k->guest_notifier_mask) { k->guest_notifier_mask(dev->vdev, n, true); } virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); event_notifier_cleanup(notifier); } return 0; }