aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-10-03 21:45:32 -0400
committerMichael S. Tsirkin <mst@redhat.com>2023-10-22 05:18:16 -0400
commitc0c4f147291f37765a5275aa24c3e1195468903b (patch)
tree872c5daaef639ea2ea16fd7e307a232cdaf43f7b
parente6383293eb01928692047e617665a742cca87e23 (diff)
downloadqemu-c0c4f147291f37765a5275aa24c3e1195468903b.zip
qemu-c0c4f147291f37765a5275aa24c3e1195468903b.tar.gz
qemu-c0c4f147291f37765a5275aa24c3e1195468903b.tar.bz2
virtio: call ->vhost_reset_device() during reset
vhost-user-scsi has a VirtioDeviceClass->reset() function that calls ->vhost_reset_device(). The other vhost devices don't notify the vhost device upon reset. Stateful vhost devices may need to handle device reset in order to free resources or prevent stale device state from interfering after reset. Call ->vhost_device_reset() from virtio_reset() so that that vhost devices are notified of device reset. This patch affects behavior as follows: - vhost-kernel: No change in behavior since ->vhost_reset_device() is not implemented. - vhost-user: back-ends that negotiate VHOST_USER_PROTOCOL_F_RESET_DEVICE now receive a VHOST_USER_DEVICE_RESET message upon device reset. Otherwise there is no change in behavior. DPDK, SPDK, libvhost-user, and the vhost-user-backend crate do not negotiate VHOST_USER_PROTOCOL_F_RESET_DEVICE automatically. - vhost-vdpa: an extra SET_STATUS 0 call is made during device reset. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-Id: <20231004014532.1228637-4-stefanha@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com> Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
-rw-r--r--hw/scsi/vhost-user-scsi.c11
-rw-r--r--hw/virtio/vhost.c9
-rw-r--r--hw/virtio/virtio.c4
-rw-r--r--include/hw/virtio/vhost.h10
-rw-r--r--meson.build1
5 files changed, 24 insertions, 11 deletions
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 78aef47..b7c6100 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -62,16 +62,6 @@ static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status)
}
}
-static void vhost_user_scsi_reset(VirtIODevice *vdev)
-{
- VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev);
- struct vhost_dev *dev = &vsc->dev;
-
- if (dev->vhost_ops->vhost_reset_device) {
- dev->vhost_ops->vhost_reset_device(dev);
- }
-}
-
static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
}
@@ -191,7 +181,6 @@ static void vhost_user_scsi_class_init(ObjectClass *klass, void *data)
vdc->get_features = vhost_scsi_common_get_features;
vdc->set_config = vhost_scsi_common_set_config;
vdc->set_status = vhost_user_scsi_set_status;
- vdc->reset = vhost_user_scsi_reset;
fwc->get_dev_path = vhost_scsi_common_get_fw_dev_path;
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 9f37206..92a6933 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -2154,3 +2154,12 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
return -ENOSYS;
}
+
+int vhost_reset_device(struct vhost_dev *hdev)
+{
+ if (hdev->vhost_ops->vhost_reset_device) {
+ return hdev->vhost_ops->vhost_reset_device(hdev);
+ }
+
+ return -ENOSYS;
+}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 6facd64..fb24bc9 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2136,6 +2136,10 @@ void virtio_reset(void *opaque)
vdev->device_endian = virtio_default_endian();
}
+ if (vdev->vhost_started) {
+ vhost_reset_device(k->get_vhost(vdev));
+ }
+
if (k->reset) {
k->reset(vdev);
}
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index c7e54676..00e0a66 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -339,4 +339,14 @@ int vhost_dev_set_inflight(struct vhost_dev *dev,
int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
struct vhost_inflight *inflight);
bool vhost_dev_has_iommu(struct vhost_dev *dev);
+
+#ifdef CONFIG_VHOST
+int vhost_reset_device(struct vhost_dev *hdev);
+#else
+static inline int vhost_reset_device(struct vhost_dev *hdev)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_VHOST */
+
#endif
diff --git a/meson.build b/meson.build
index e0d1f84..cbee764 100644
--- a/meson.build
+++ b/meson.build
@@ -2134,6 +2134,7 @@ config_host_data.set('CONFIG_TPM', have_tpm)
config_host_data.set('CONFIG_TSAN', get_option('tsan'))
config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
config_host_data.set('CONFIG_VDE', vde.found())
+config_host_data.set('CONFIG_VHOST', have_vhost)
config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)