This optional callback addresses migration problem in case some of negotiated features not present on the destination system. The device has a chance to avoid migration failure.
Signed-off-by: Yuri Benditovich <yuri.benditov...@daynix.com> --- hw/virtio/virtio.c | 8 ++++++++ include/hw/virtio/virtio.h | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 07f4e60b30..36dcac75e5 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3107,6 +3107,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) vdev->device_endian = virtio_default_endian(); } + if (vdc->missing_features_migrated) { + uint64_t missing = (vdev->guest_features & ~(vdev->host_features)); + if (missing && vdc->missing_features_migrated(vdev, missing)) { + vdev->host_features = + vdc->get_features(vdev, vdev->host_features, NULL); + } + } + if (virtio_64bit_features_needed(vdev)) { /* * Subsection load filled vdev->guest_features. Run them diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index b7ece7a6a8..fbfbec6ef2 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -158,6 +158,14 @@ struct VirtioDeviceClass { * processed, e.g. for bounds checking. */ int (*post_load)(VirtIODevice *vdev); + /* In case when some of negotiated features are missing on the destination + system, the migration is expected to fail. To avoid such failure, the + device may implement this callback and apply graceful configuration + change to extend host features (for example, disable vhost). + If the device returns true the virtio reinitializes the host features + and further set_features call may succeed. + */ + bool (*missing_features_migrated)(VirtIODevice *vdev, uint64_t val); const VMStateDescription *vmsd; bool (*primary_unplug_pending)(void *opaque); }; -- 2.26.2