| 1 | /* |
| 2 | * VFIO migration |
| 3 | * |
| 4 | * Copyright Red Hat, Inc. 2025 |
| 5 | * |
| 6 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 7 | */ |
| 8 | |
| 9 | #ifndef HW_VFIO_VFIO_MIGRATION_INTERNAL_H |
| 10 | #define HW_VFIO_VFIO_MIGRATION_INTERNAL_H |
| 11 | |
| 12 | #ifdef CONFIG_LINUX |
| 13 | #include <linux/vfio.h> |
| 14 | #endif |
| 15 | |
| 16 | #include "qemu/notify.h" |
| 17 | |
| 18 | /* |
| 19 | * Flags to be used as unique delimiters for VFIO devices in the migration |
| 20 | * stream. These flags are composed as: |
| 21 | * 0xffffffff => MSB 32-bit all 1s |
| 22 | * 0xef10 => Magic ID, represents emulated (virtual) function IO |
| 23 | * 0x0000 => 16-bits reserved for flags |
| 24 | * |
| 25 | * The beginning of state information is marked by _DEV_CONFIG_STATE, |
| 26 | * _DEV_SETUP_STATE, or _DEV_DATA_STATE, respectively. The end of a |
| 27 | * certain state information is marked by _END_OF_STATE. |
| 28 | */ |
| 29 | #define VFIO_MIG_FLAG_END_OF_STATE (0xffffffffef100001ULL) |
| 30 | #define VFIO_MIG_FLAG_DEV_CONFIG_STATE (0xffffffffef100002ULL) |
| 31 | #define VFIO_MIG_FLAG_DEV_SETUP_STATE (0xffffffffef100003ULL) |
| 32 | #define VFIO_MIG_FLAG_DEV_DATA_STATE (0xffffffffef100004ULL) |
| 33 | #define VFIO_MIG_FLAG_DEV_INIT_DATA_SENT (0xffffffffef100005ULL) |
| 34 | #define VFIO_MIG_FLAG_DEV_CONFIG_LOAD_READY (0xffffffffef100006ULL) |
| 35 | |
| 36 | typedef struct VFIODevice VFIODevice; |
| 37 | typedef struct VFIOMultifd VFIOMultifd; |
| 38 | |
| 39 | typedef struct VFIOMigration { |
| 40 | struct VFIODevice *vbasedev; |
| 41 | VMChangeStateEntry *vm_state; |
| 42 | NotifierWithReturn migration_state; |
| 43 | uint32_t device_state; |
| 44 | int data_fd; |
| 45 | void *data_buffer; |
| 46 | size_t data_buffer_size; |
| 47 | uint64_t mig_flags; |
| 48 | bool precopy_info_v2_used; |
| 49 | /* |
| 50 | * NOTE: all three sizes cached are reported from VFIO's uAPI, which |
| 51 | * are defined as estimate only. QEMU should not trust these values |
| 52 | * but only use them to do best-effort estimates. Always be prepared |
| 53 | * that these sizes may either grow or even shrink in reality while |
| 54 | * read()ing from the VFIO fds. |
| 55 | */ |
| 56 | uint64_t precopy_init_size; |
| 57 | uint64_t precopy_dirty_size; |
| 58 | uint64_t stopcopy_size; |
| 59 | bool multifd_transfer; |
| 60 | VFIOMultifd *multifd; |
| 61 | bool initial_data_sent; |
| 62 | bool request_switchover_ack; |
| 63 | |
| 64 | bool event_save_iterate_started; |
| 65 | bool event_precopy_empty_hit; |
| 66 | } VFIOMigration; |
| 67 | |
| 68 | bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp); |
| 69 | void vfio_migration_exit(VFIODevice *vbasedev); |
| 70 | bool vfio_device_state_is_running(VFIODevice *vbasedev); |
| 71 | bool vfio_device_state_is_precopy(VFIODevice *vbasedev); |
| 72 | int vfio_save_device_config_state(QEMUFile *f, void *opaque, Error **errp); |
| 73 | int vfio_load_device_config_state(QEMUFile *f, void *opaque); |
| 74 | |
| 75 | #ifdef CONFIG_LINUX |
| 76 | int vfio_migration_set_state(VFIODevice *vbasedev, |
| 77 | enum vfio_device_mig_state new_state, |
| 78 | enum vfio_device_mig_state recover_state, |
| 79 | Error **errp); |
| 80 | #endif |
| 81 | |
| 82 | void vfio_migration_add_bytes_transferred(unsigned long val); |
| 83 | |
| 84 | #endif /* HW_VFIO_VFIO_MIGRATION_INTERNAL_H */ |