@@ -26,6 +26,8 @@ typedef struct VirtIOBlock
char *serial;
unsigned short sector_mask;
DeviceState *qdev;
+
+ bool data_plane_started;
} VirtIOBlock;
static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -33,6 +35,39 @@ static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
return (VirtIOBlock *)vdev;
}
+static void virtio_blk_data_plane_start(VirtIOBlock *s)
+{
+ if (s->vdev.binding->set_host_notifier(s->vdev.binding_opaque, 0, true) != 0) {
+ fprintf(stderr, "virtio-blk failed to set host notifier\n");
+ return;
+ }
+
+ s->data_plane_started = true;
+}
+
+static void virtio_blk_data_plane_stop(VirtIOBlock *s)
+{
+ s->data_plane_started = false;
+
+ s->vdev.binding->set_host_notifier(s->vdev.binding_opaque, 0, false);
+}
+
+static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t val)
+{
+ VirtIOBlock *s = to_virtio_blk(vdev);
+
+ /* Toggle host notifier only on status change */
+ if (s->data_plane_started == !!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
+ return;
+ }
+
+ if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
+ virtio_blk_data_plane_start(s);
+ } else {
+ virtio_blk_data_plane_stop(s);
+ }
+}
+
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
fprintf(stderr, "virtio_blk_handle_output: should never get here,"
@@ -115,6 +150,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
s->vdev.get_config = virtio_blk_update_config;
s->vdev.get_features = virtio_blk_get_features;
+ s->vdev.set_status = virtio_blk_set_status;
s->bs = conf->bs;
s->conf = conf;
s->serial = *serial;
@@ -122,6 +158,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
+ s->data_plane_started = false;
s->qdev = dev;
bdrv_set_buffer_alignment(s->bs, conf->logical_block_size);
Set up the virtqueue notify ioeventfd that the data plane will monitor. Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> --- hw/virtio-blk.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)