/* On success, ioeventfd ownership belongs to the caller. */ int virtio_bus_grab_ioeventfd(VirtioBusState *bus) { VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus); /* vhost can be used even if ioeventfd=off in the proxy device, * so do not check k->ioeventfd_enabled. */ if (!k->ioeventfd_assign) { return -ENOSYS; } if (bus->ioeventfd_grabbed == 0 && bus->ioeventfd_started) { virtio_bus_stop_ioeventfd(bus); /* Remember that we need to restart ioeventfd * when ioeventfd_grabbed becomes zero. */ bus->ioeventfd_started = true; } bus->ioeventfd_grabbed++; return 0; }
/* * This function switches from/to the generic ioeventfd handler. * assign==false means 'use generic ioeventfd handler'. */ int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign) { VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus); DeviceState *proxy = DEVICE(BUS(bus)->parent); if (!k->ioeventfd_started) { return -ENOSYS; } k->ioeventfd_set_disabled(proxy, assign); if (assign) { /* * Stop using the generic ioeventfd, we are doing eventfd handling * ourselves below * * FIXME: We should just switch the handler and not deassign the * ioeventfd. * Otherwise, there's a window where we don't have an * ioeventfd and we may end up with a notification where * we don't expect one. */ virtio_bus_stop_ioeventfd(bus); } return set_host_notifier_internal(proxy, bus, n, assign, false); }
static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy *proxy) { virtio_bus_stop_ioeventfd(&proxy->bus); }