aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio/vhost-user-gpio.c
diff options
context:
space:
mode:
authorAlex Bennée <alex.bennee@linaro.org>2022-11-30 11:24:38 +0000
committerMichael S. Tsirkin <mst@redhat.com>2022-12-01 02:30:13 -0500
commit71e076a07dc195129fe25d90d4b276be3b2f12d8 (patch)
treeede68f35ad6fd8c5a9e785c01dbca02a76a92a98 /hw/virtio/vhost-user-gpio.c
parent060f4a944072ecf37cece0f16a0609babfb679b8 (diff)
downloadqemu-71e076a07dc195129fe25d90d4b276be3b2f12d8.zip
qemu-71e076a07dc195129fe25d90d4b276be3b2f12d8.tar.gz
qemu-71e076a07dc195129fe25d90d4b276be3b2f12d8.tar.bz2
hw/virtio: generalise CHR_EVENT_CLOSED handling
..and use for both virtio-user-blk and virtio-user-gpio. This avoids the circular close by deferring shutdown due to disconnection until a later point. virtio-user-blk already had this mechanism in place so generalise it as a vhost-user helper function and use for both blk and gpio devices. While we are at it we also fix up vhost-user-gpio to re-establish the event handler after close down so we can reconnect later. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com> Message-Id: <20221130112439.2527228-5-alex.bennee@linaro.org> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/virtio/vhost-user-gpio.c')
-rw-r--r--hw/virtio/vhost-user-gpio.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index be9be08..b7b82a1 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -233,6 +233,8 @@ static int vu_gpio_connect(DeviceState *dev, Error **errp)
return 0;
}
+static void vu_gpio_event(void *opaque, QEMUChrEvent event);
+
static void vu_gpio_disconnect(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -245,6 +247,11 @@ static void vu_gpio_disconnect(DeviceState *dev)
vu_gpio_stop(vdev);
vhost_dev_cleanup(&gpio->vhost_dev);
+
+ /* Re-instate the event handler for new connections */
+ qemu_chr_fe_set_handlers(&gpio->chardev,
+ NULL, NULL, vu_gpio_event,
+ NULL, dev, NULL, true);
}
static void vu_gpio_event(void *opaque, QEMUChrEvent event)
@@ -262,7 +269,9 @@ static void vu_gpio_event(void *opaque, QEMUChrEvent event)
}
break;
case CHR_EVENT_CLOSED:
- vu_gpio_disconnect(dev);
+ /* defer close until later to avoid circular close */
+ vhost_user_async_close(dev, &gpio->chardev, &gpio->vhost_dev,
+ vu_gpio_disconnect);
break;
case CHR_EVENT_BREAK:
case CHR_EVENT_MUX_IN: