Lines Matching +full:stop +full:- +full:ack
7 * the COPYING file in the top-level directory.
11 #include "qemu/main-loop.h"
14 #include "qemu/error-report.h"
19 #include "hw/vfio/vfio-device.h"
20 #include "hw/vfio/vfio-migration.h"
24 #include "migration/qemu-file.h"
27 #include "migration-multifd.h"
29 #include "qapi/qapi-events-vfio.h"
34 #include "vfio-migration-internal.h"
51 return "STOP"; in mig_state_to_str()
94 VFIOMigration *migration = vbasedev->migration; in vfio_migration_send_event()
95 DeviceState *dev = vbasedev->dev; in vfio_migration_send_event()
99 if (!vbasedev->migration_events) { in vfio_migration_send_event()
103 g_assert(vbasedev->ops->vfio_get_object); in vfio_migration_send_event()
104 obj = vbasedev->ops->vfio_get_object(vbasedev); in vfio_migration_send_event()
109 dev->id, qom_path, mig_state_to_qapi_state(migration->device_state)); in vfio_migration_send_event()
115 VFIOMigration *migration = vbasedev->migration; in vfio_migration_set_device_state()
117 trace_vfio_migration_set_device_state(vbasedev->name, in vfio_migration_set_device_state()
120 migration->device_state = state; in vfio_migration_set_device_state()
129 VFIOMigration *migration = vbasedev->migration; in vfio_migration_set_state()
135 (struct vfio_device_feature_mig_state *)feature->data; in vfio_migration_set_state()
139 vbasedev->name, mig_state_to_str(new_state)); in vfio_migration_set_state()
141 trace_vfio_migration_set_state(vbasedev->name, mig_state_to_str(new_state), in vfio_migration_set_state()
144 if (new_state == migration->device_state) { in vfio_migration_set_state()
148 feature->argsz = sizeof(buf); in vfio_migration_set_state()
149 feature->flags = in vfio_migration_set_state()
151 mig_state->device_state = new_state; in vfio_migration_set_state()
152 if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) { in vfio_migration_set_state()
154 ret = -errno; in vfio_migration_set_state()
168 mig_state->device_state = recover_state; in vfio_migration_set_state()
169 if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) { in vfio_migration_set_state()
170 ret = -errno; in vfio_migration_set_state()
177 vbasedev->name, strerror(errno)); in vfio_migration_set_state()
188 if (mig_state->data_fd != -1) { in vfio_migration_set_state()
189 if (migration->data_fd != -1) { in vfio_migration_set_state()
194 error_setg(errp, "%s: data_fd out of sync", vbasedev->name); in vfio_migration_set_state()
195 close(mig_state->data_fd); in vfio_migration_set_state()
197 return -EBADF; in vfio_migration_set_state()
200 migration->data_fd = mig_state->data_fd; in vfio_migration_set_state()
206 if (ioctl(vbasedev->fd, VFIO_DEVICE_RESET)) { in vfio_migration_set_state()
207 hw_error("%s: Failed resetting device, err: %s", vbasedev->name, in vfio_migration_set_state()
233 VFIOMigration *migration = vbasedev->migration; in vfio_load_buffer()
236 ret = qemu_file_get_to_fd(f, migration->data_fd, data_size); in vfio_load_buffer()
237 trace_vfio_load_state_device_data(vbasedev->name, data_size, ret); in vfio_load_buffer()
249 if (vbasedev->ops && vbasedev->ops->vfio_save_config) { in vfio_save_device_config_state()
250 ret = vbasedev->ops->vfio_save_config(vbasedev, f, errp); in vfio_save_device_config_state()
258 trace_vfio_save_device_config_state(vbasedev->name); in vfio_save_device_config_state()
262 error_setg_errno(errp, -ret, "Failed to save state"); in vfio_save_device_config_state()
272 trace_vfio_load_device_config_state_start(vbasedev->name); in vfio_load_device_config_state()
274 if (vbasedev->ops && vbasedev->ops->vfio_load_config) { in vfio_load_device_config_state()
277 ret = vbasedev->ops->vfio_load_config(vbasedev, f); in vfio_load_device_config_state()
280 vbasedev->name); in vfio_load_device_config_state()
288 "end flag incorrect 0x%"PRIx64, vbasedev->name, data); in vfio_load_device_config_state()
289 return -EINVAL; in vfio_load_device_config_state()
292 trace_vfio_load_device_config_state_end(vbasedev->name); in vfio_load_device_config_state()
298 VFIOMigration *migration = vbasedev->migration; in vfio_migration_cleanup()
300 close(migration->data_fd); in vfio_migration_cleanup()
301 migration->data_fd = -1; in vfio_migration_cleanup()
312 (struct vfio_device_feature_mig_data_size *)feature->data; in vfio_query_stop_copy_size()
314 feature->argsz = sizeof(buf); in vfio_query_stop_copy_size()
315 feature->flags = in vfio_query_stop_copy_size()
318 if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) { in vfio_query_stop_copy_size()
319 return -errno; in vfio_query_stop_copy_size()
322 *stop_copy_size = mig_data_size->stop_copy_length; in vfio_query_stop_copy_size()
333 migration->precopy_init_size = 0; in vfio_query_precopy_size()
334 migration->precopy_dirty_size = 0; in vfio_query_precopy_size()
336 if (ioctl(migration->data_fd, VFIO_MIG_GET_PRECOPY_INFO, &precopy)) { in vfio_query_precopy_size()
337 return -errno; in vfio_query_precopy_size()
340 migration->precopy_init_size = precopy.initial_bytes; in vfio_query_precopy_size()
341 migration->precopy_dirty_size = precopy.dirty_bytes; in vfio_query_precopy_size()
346 /* Returns the size of saved data on success and -errno on error */
351 data_size = read(migration->data_fd, migration->data_buffer, in vfio_save_block()
352 migration->data_buffer_size); in vfio_save_block()
355 * Pre-copy emptied all the device state for now. For more information, in vfio_save_block()
359 if (!migration->event_precopy_empty_hit) { in vfio_save_block()
360 trace_vfio_save_block_precopy_empty_hit(migration->vbasedev->name); in vfio_save_block()
361 migration->event_precopy_empty_hit = true; in vfio_save_block()
366 return -errno; in vfio_save_block()
372 /* Non-empty read: re-arm the trace event */ in vfio_save_block()
373 migration->event_precopy_empty_hit = false; in vfio_save_block()
377 qemu_put_buffer(f, migration->data_buffer, data_size); in vfio_save_block()
380 trace_vfio_save_block(migration->vbasedev->name, data_size); in vfio_save_block()
390 * Pre-copy emptied all the device state for now, update estimated sizes in vfio_update_estimated_pending_data()
393 migration->precopy_init_size = 0; in vfio_update_estimated_pending_data()
394 migration->precopy_dirty_size = 0; in vfio_update_estimated_pending_data()
399 if (migration->precopy_init_size) { in vfio_update_estimated_pending_data()
400 uint64_t init_size = MIN(migration->precopy_init_size, data_size); in vfio_update_estimated_pending_data()
402 migration->precopy_init_size -= init_size; in vfio_update_estimated_pending_data()
403 data_size -= init_size; in vfio_update_estimated_pending_data()
406 migration->precopy_dirty_size -= MIN(migration->precopy_dirty_size, in vfio_update_estimated_pending_data()
412 VFIOMigration *migration = vbasedev->migration; in vfio_precopy_supported()
414 return migration->mig_flags & VFIO_MIGRATION_PRE_COPY; in vfio_precopy_supported()
417 /* ---------------------------------------------------------------------- */
434 vbasedev->name); in vfio_save_prepare()
435 return -EOPNOTSUPP; in vfio_save_prepare()
442 vbasedev->name); in vfio_save_prepare()
443 return -EOPNOTSUPP; in vfio_save_prepare()
452 VFIOMigration *migration = vbasedev->migration; in vfio_save_setup()
457 return -EINVAL; in vfio_save_setup()
463 migration->data_buffer_size = MIN(VFIO_MIG_DEFAULT_DATA_BUFFER_SIZE, in vfio_save_setup()
465 migration->data_buffer = g_try_malloc0(migration->data_buffer_size); in vfio_save_setup()
466 if (!migration->data_buffer) { in vfio_save_setup()
468 vbasedev->name); in vfio_save_setup()
469 return -ENOMEM; in vfio_save_setup()
472 migration->event_save_iterate_started = false; in vfio_save_setup()
473 migration->event_precopy_empty_hit = false; in vfio_save_setup()
476 switch (migration->device_state) { in vfio_save_setup()
491 error_setg(errp, "%s: Invalid device state %d", vbasedev->name, in vfio_save_setup()
492 migration->device_state); in vfio_save_setup()
493 return -EINVAL; in vfio_save_setup()
497 trace_vfio_save_setup(vbasedev->name, migration->data_buffer_size); in vfio_save_setup()
503 error_setg_errno(errp, -ret, "%s: save setup failed", vbasedev->name); in vfio_save_setup()
512 VFIOMigration *migration = vbasedev->migration; in vfio_save_cleanup()
520 * Changing device state from STOP_COPY to STOP can take time. Do it here, in vfio_save_cleanup()
523 if (migration->device_state == VFIO_DEVICE_STATE_STOP_COPY) { in vfio_save_cleanup()
532 g_free(migration->data_buffer); in vfio_save_cleanup()
533 migration->data_buffer = NULL; in vfio_save_cleanup()
534 migration->precopy_init_size = 0; in vfio_save_cleanup()
535 migration->precopy_dirty_size = 0; in vfio_save_cleanup()
536 migration->initial_data_sent = false; in vfio_save_cleanup()
538 trace_vfio_save_cleanup(vbasedev->name); in vfio_save_cleanup()
545 VFIOMigration *migration = vbasedev->migration; in vfio_state_pending_estimate()
552 migration->precopy_init_size + migration->precopy_dirty_size; in vfio_state_pending_estimate()
554 trace_vfio_state_pending_estimate(vbasedev->name, *must_precopy, in vfio_state_pending_estimate()
556 migration->precopy_init_size, in vfio_state_pending_estimate()
557 migration->precopy_dirty_size); in vfio_state_pending_estimate()
570 VFIOMigration *migration = vbasedev->migration; in vfio_state_pending_exact()
584 trace_vfio_state_pending_exact(vbasedev->name, *must_precopy, *can_postcopy, in vfio_state_pending_exact()
585 stop_copy_size, migration->precopy_init_size, in vfio_state_pending_exact()
586 migration->precopy_dirty_size); in vfio_state_pending_exact()
605 VFIOMigration *migration = vbasedev->migration; in vfio_save_iterate()
608 if (!migration->event_save_iterate_started) { in vfio_save_iterate()
609 trace_vfio_save_iterate_start(vbasedev->name); in vfio_save_iterate()
610 migration->event_save_iterate_started = true; in vfio_save_iterate()
620 if (migrate_switchover_ack() && !migration->precopy_init_size && in vfio_save_iterate()
621 !migration->initial_data_sent) { in vfio_save_iterate()
623 migration->initial_data_sent = true; in vfio_save_iterate()
628 trace_vfio_save_iterate(vbasedev->name, migration->precopy_init_size, in vfio_save_iterate()
629 migration->precopy_dirty_size); in vfio_save_iterate()
631 return !migration->precopy_init_size && !migration->precopy_dirty_size; in vfio_save_iterate()
646 trace_vfio_save_complete_precopy_start(vbasedev->name); in vfio_save_complete_precopy()
648 /* We reach here with device state STOP or STOP_COPY only */ in vfio_save_complete_precopy()
657 data_size = vfio_save_block(f, vbasedev->migration); in vfio_save_complete_precopy()
666 trace_vfio_save_complete_precopy(vbasedev->name, ret); in vfio_save_complete_precopy()
685 "vfio: Failed to save device config space of %s - ", in vfio_save_state()
686 vbasedev->name); in vfio_save_state()
694 VFIOMigration *migration = vbasedev->migration; in vfio_load_setup()
698 return -EINVAL; in vfio_load_setup()
702 migration->device_state, errp); in vfio_load_setup()
717 trace_vfio_load_cleanup(vbasedev->name); in vfio_load_cleanup()
731 trace_vfio_load_state(vbasedev->name, data); in vfio_load_state()
739 vbasedev->name); in vfio_load_state()
740 return -EINVAL; in vfio_load_state()
752 vbasedev->name, data); in vfio_load_state()
753 return -EINVAL; in vfio_load_state()
773 error_report("%s: Received INIT_DATA_SENT but switchover ack " in vfio_load_state()
774 "is not used", vbasedev->name); in vfio_load_state()
775 return -EINVAL; in vfio_load_state()
782 vbasedev->name, ret, strerror(-ret)); in vfio_load_state()
788 error_report("%s: Unknown tag 0x%"PRIx64, vbasedev->name, data); in vfio_load_state()
789 return -EINVAL; in vfio_load_state()
841 /* ---------------------------------------------------------------------- */
847 VFIOMigration *migration = vbasedev->migration; in vfio_vmstate_change_prepare()
852 new_state = migration->device_state == VFIO_DEVICE_STATE_PRE_COPY ? in vfio_vmstate_change_prepare()
865 trace_vfio_vmstate_change_prepare(vbasedev->name, running, in vfio_vmstate_change_prepare()
896 trace_vfio_vmstate_change(vbasedev->name, running, RunState_str(state), in vfio_vmstate_change()
905 VFIODevice *vbasedev = migration->vbasedev; in vfio_migration_state_notifier()
909 trace_vfio_migration_state_notifier(vbasedev->name, e->type); in vfio_migration_state_notifier()
911 if (e->type == MIG_EVENT_PRECOPY_FAILED) { in vfio_migration_state_notifier()
929 g_free(vbasedev->migration); in vfio_migration_free()
930 vbasedev->migration = NULL; in vfio_migration_free()
940 (struct vfio_device_feature_migration *)feature->data; in vfio_migration_query_flags()
942 feature->argsz = sizeof(buf); in vfio_migration_query_flags()
943 feature->flags = VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_MIGRATION; in vfio_migration_query_flags()
944 if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) { in vfio_migration_query_flags()
945 return -errno; in vfio_migration_query_flags()
948 *mig_flags = mig->flags; in vfio_migration_query_flags()
959 feature->argsz = sizeof(buf); in vfio_dma_logging_supported()
960 feature->flags = VFIO_DEVICE_FEATURE_PROBE | in vfio_dma_logging_supported()
963 return !ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature); in vfio_dma_logging_supported()
976 if (!vbasedev->ops->vfio_get_object) { in vfio_migration_init()
977 return -EINVAL; in vfio_migration_init()
980 obj = vbasedev->ops->vfio_get_object(vbasedev); in vfio_migration_init()
982 return -EINVAL; in vfio_migration_init()
992 return -EOPNOTSUPP; in vfio_migration_init()
995 vbasedev->migration = g_new0(VFIOMigration, 1); in vfio_migration_init()
996 migration = vbasedev->migration; in vfio_migration_init()
997 migration->vbasedev = vbasedev; in vfio_migration_init()
998 migration->device_state = VFIO_DEVICE_STATE_RUNNING; in vfio_migration_init()
999 migration->data_fd = -1; in vfio_migration_init()
1000 migration->mig_flags = mig_flags; in vfio_migration_init()
1002 vbasedev->dirty_pages_supported = vfio_dma_logging_supported(vbasedev); in vfio_migration_init()
1015 prepare_cb = migration->mig_flags & VFIO_MIGRATION_P2P ? in vfio_migration_init()
1018 migration->vm_state = qdev_add_vm_change_state_handler_full( in vfio_migration_init()
1019 vbasedev->dev, vfio_vmstate_change, prepare_cb, NULL, vbasedev); in vfio_migration_init()
1020 migration_add_notifier(&migration->migration_state, in vfio_migration_init()
1040 if (vbasedev->migration) { in vfio_multiple_devices_migration_is_supported()
1043 if (!(vbasedev->migration->mig_flags & VFIO_MIGRATION_P2P)) { in vfio_multiple_devices_migration_is_supported()
1058 if (vbasedev->enable_migration == ON_OFF_AUTO_ON) { in vfio_block_multiple_devices_migration()
1061 return -EINVAL; in vfio_block_multiple_devices_migration()
1087 VFIOMigration *migration = vbasedev->migration; in vfio_migration_deinit()
1089 migration_remove_notifier(&migration->migration_state); in vfio_migration_deinit()
1090 qemu_del_vm_change_state_handler(migration->vm_state); in vfio_migration_deinit()
1091 unregister_savevm(VMSTATE_IF(vbasedev->dev), "vfio", vbasedev); in vfio_migration_deinit()
1098 if (vbasedev->enable_migration == ON_OFF_AUTO_ON) { in vfio_block_migration()
1100 return -EINVAL; in vfio_block_migration()
1103 vbasedev->migration_blocker = error_copy(err); in vfio_block_migration()
1106 return migrate_add_blocker_normal(&vbasedev->migration_blocker, errp); in vfio_block_migration()
1109 /* ---------------------------------------------------------------------- */
1135 if (vbasedev->migration_blocker) { in vfio_migration_active()
1144 return vbasedev->bcontainer->space->as != &address_space_memory; in vfio_viommu_preset()
1150 * de-register vfio device.
1157 if (vbasedev->enable_migration == ON_OFF_AUTO_OFF) { in vfio_migration_realize()
1159 vbasedev->name); in vfio_migration_realize()
1165 if (ret == -ENOTTY) { in vfio_migration_realize()
1167 vbasedev->name); in vfio_migration_realize()
1172 vbasedev->name, ret, strerror(-ret)); in vfio_migration_realize()
1178 if ((!vbasedev->dirty_pages_supported || in vfio_migration_realize()
1179 vbasedev->device_dirty_page_tracking == ON_OFF_AUTO_OFF) && in vfio_migration_realize()
1180 !vbasedev->iommu_dirty_tracking) { in vfio_migration_realize()
1181 if (vbasedev->enable_migration == ON_OFF_AUTO_AUTO) { in vfio_migration_realize()
1184 "IOMMU dirty tracking", vbasedev->name); in vfio_migration_realize()
1189 "IOMMU dirty tracking", vbasedev->name); in vfio_migration_realize()
1199 "with vIOMMU enabled", vbasedev->name); in vfio_migration_realize()
1203 trace_vfio_migration_realize(vbasedev->name); in vfio_migration_realize()
1217 if (vbasedev->migration) { in vfio_migration_exit()
1221 migrate_del_blocker(&vbasedev->migration_blocker); in vfio_migration_exit()
1226 VFIOMigration *migration = vbasedev->migration; in vfio_device_state_is_running()
1228 return migration->device_state == VFIO_DEVICE_STATE_RUNNING || in vfio_device_state_is_running()
1229 migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P; in vfio_device_state_is_running()
1234 VFIOMigration *migration = vbasedev->migration; in vfio_device_state_is_precopy()
1236 return migration->device_state == VFIO_DEVICE_STATE_PRE_COPY || in vfio_device_state_is_precopy()
1237 migration->device_state == VFIO_DEVICE_STATE_PRE_COPY_P2P; in vfio_device_state_is_precopy()