virtio-bus: common ioeventfd infrastructure

Introduce a set of ioeventfd callbacks on the virtio-bus level
that can be implemented by the individual transports. At the
virtio-bus level, do common handling for host notifiers (which
is actually most of it).

Two things of note:
- When setting the host notifier, we only switch from/to the
  generic ioeventfd handler. This fixes a latent bug where we
  had no ioeventfd assigned for a certain window.
- We always iterate over all possible virtio queues, even though
  ccw (currently) has a lower limit. It does not really matter
  here.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Cornelia Huck 2016-06-10 11:04:09 +02:00 committed by Michael S. Tsirkin
parent 1f3aba377d
commit 6798e245a3
2 changed files with 162 additions and 0 deletions

View file

@ -70,6 +70,29 @@ typedef struct VirtioBusClass {
*/
void (*device_unplugged)(DeviceState *d);
int (*query_nvectors)(DeviceState *d);
/*
* ioeventfd handling: if the transport implements ioeventfd_started,
* it must implement the other ioeventfd callbacks as well
*/
/* Returns true if the ioeventfd has been started for the device. */
bool (*ioeventfd_started)(DeviceState *d);
/*
* Sets the 'ioeventfd started' state after the ioeventfd has been
* started/stopped for the device. err signifies whether an error
* had occurred.
*/
void (*ioeventfd_set_started)(DeviceState *d, bool started, bool err);
/* Returns true if the ioeventfd has been disabled for the device. */
bool (*ioeventfd_disabled)(DeviceState *d);
/* Sets the 'ioeventfd disabled' state for the device. */
void (*ioeventfd_set_disabled)(DeviceState *d, bool disabled);
/*
* Assigns/deassigns the ioeventfd backing for the transport on
* the device for queue number n. Returns an error value on
* failure.
*/
int (*ioeventfd_assign)(DeviceState *d, EventNotifier *notifier,
int n, bool assign);
/*
* Does the transport have variable vring alignment?
* (ie can it ever call virtio_queue_set_align()?)
@ -111,4 +134,11 @@ static inline VirtIODevice *virtio_bus_get_device(VirtioBusState *bus)
return (VirtIODevice *)qdev;
}
/* Start the ioeventfd. */
void virtio_bus_start_ioeventfd(VirtioBusState *bus);
/* Stop the ioeventfd. */
void virtio_bus_stop_ioeventfd(VirtioBusState *bus);
/* Switch from/to the generic ioeventfd handler */
int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign);
#endif /* VIRTIO_BUS_H */