Thanks to visit codestin.com
Credit goes to github.com

Skip to content

pci: vfio: Implement migration v2 for snapshot and restore - #8303

Merged
likebreath merged 5 commits into
cloud-hypervisor:mainfrom
saravan2:vfio-migration
Jul 2, 2026
Merged

likebreath merged 5 commits into
cloud-hypervisor:mainfrom
saravan2:vfio-migration

Conversation

@saravan2

@saravan2 saravan2 commented May 30, 2026

Copy link
Copy Markdown
Member

Summary

Adds VFIO v2 migration protocol support for same host snapshot and restore of migratable VFIO devices, for example ConnectX VFs bound to mlx5_vfio_pci. Non migratable devices retain their existing snapshot behavior. Live migration with VFIO Devices, DMA dirty page tracking, and precopy iteration are follow up work and are not in this PR.

VFIO Migration v2 State Transitions

Phase Action Device State Transition
Save pause() RUNNING → STOP
Save snapshot() requests data STOP → STOP_COPY
Save snapshot() drains data_fd (device blob) no transition
Save snapshot() finalizes STOP_COPY → STOP
Restore load_migration_data() requests data_fd RUNNING → RESUMING (*)
Restore load_migration_data() writes device blob no transition
Restore post load fixups (PCI_COMMAND, rearm MSI or MSI-X) no transition
Resume resume() after save (optional) STOP → RUNNING
Resume resume() after restore (mandatory) RESUMING → RUNNING (*)

(*) Each arrow (→) is one VFIO_DEVICE_FEATURE_SET_MIG_DEVICE_STATE ioctl.
Non adjacent transitions such as RUNNING → RESUMING, RESUMING → RUNNING has to pass through STOP as per the protocol, and the host kernel walks that intermediate STOP state internally via the variant driver (mlx5_vfio_pci), therefore in this implementation Cloud-Hypervisor avoids enforcing STOP in the restore, resume phases. Referred QEMU's VFIO Migration ioctl sequence.

Test

  • Unit Tests
cargo test -p pci --lib vfio::tests
   Compiling log v0.4.30
   Compiling either v1.16.0
   Compiling serde_json v1.0.150
   Compiling vm-allocator v0.1.0 (/home/saravanand/cloud-hypervisor/vm-allocator)
   Compiling vfio-ioctls v0.6.1
   Compiling itertools v0.14.0
   Compiling hypervisor v0.1.0 (/home/saravanand/cloud-hypervisor/hypervisor)
   Compiling vfio_user v0.1.3
   Compiling vm-device v0.1.0 (/home/saravanand/cloud-hypervisor/vm-device)
   Compiling vm-migration v0.1.0 (/home/saravanand/cloud-hypervisor/vm-migration)
   Compiling pci v0.1.0 (/home/saravanand/cloud-hypervisor/pci)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 1.79s
     Running unittests src/lib.rs (target/debug/deps/pci-2f3a4b128c172bab)

running 9 tests
test vfio::tests::default_query_migration_support_returns_none ... ok
test vfio::tests::default_set_migration_state_errors ... ok
test vfio::tests::load_migration_data_recovers_on_failure ... ok
test vfio::tests::vfio_migration_state_invalid_errors ... ok
test vfio::tests::load_migration_data_happy_path ... ok
test vfio::tests::save_migration_data_happy_path ... ok
test vfio::tests::vfio_migration_state_round_trips ... ok
test vfio::tests::save_migration_data_recovers_on_failure ... ok
test vfio::tests::write_config_register_mirrors_non_bar_into_shadow ... ok

test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 9 filtered out; finished in 0.00s

  • Snapshot and Restore validated on a Mellanox ConnectX 7 VF (mlx5_vfio_pci, firmware 28.43.1014)
Snaphsot-Restore-VM-small.mov

@saravan2
saravan2 requested a review from a team as a code owner May 30, 2026 01:27
@saravan2 saravan2 self-assigned this May 30, 2026
@saravan2

Copy link
Copy Markdown
Member Author

@Lencerf VFIO migration v2 implementation for snapshot and restore

@saravan2

saravan2 commented May 30, 2026

Copy link
Copy Markdown
Member Author

I require assistance in re-running CI / integration-x86-64-pr (pull_request) to determine whether the integration vfio test failure is caused due to the changes introduced in this PR.

@saravan2

saravan2 commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

I require assistance in re-running CI / integration-x86-64-pr (pull_request) to determine whether the integration vfio test failure is caused due to the changes introduced in this PR.

Found the root cause. I was missing the new VFIO_DEVICE_FEATURE ioctl in the VMM seccomp filter. It went unnoticed during development because I had to use --seccomp=false

@saravan2
saravan2 force-pushed the vfio-migration branch 2 times, most recently from 497d516 to 5e5fafe Compare June 2, 2026 00:54
@rbradford

Copy link
Copy Markdown
Member

@saravan2 Is this going to conflict with #8287 - should we wait until that is merged before reviewing?

@saravan2

Copy link
Copy Markdown
Member Author

@saravan2 Is this going to conflict with #8287 - should we wait until that is merged before reviewing?

This PR and #8287 share the first commit in the series updating the rust-vmm/VFIO crate and nothing else. So this PR can be reviewed independently.

Comment thread pci/src/vfio.rs Outdated
Comment thread pci/src/vfio.rs Outdated
Comment thread pci/src/vfio.rs Outdated
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs Outdated
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs Outdated
@likebreath

Copy link
Copy Markdown
Member

@saravan2 You will need a rebase, as the rust-vmm crates were updated from main.

@rbradford
rbradford marked this pull request as draft June 18, 2026 21:29

@saravan2 saravan2 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed review suggestions @sboeuf

Comment thread pci/src/vfio.rs Outdated
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs Outdated
@saravan2
saravan2 force-pushed the vfio-migration branch 2 times, most recently from f0a15cb to 43780b0 Compare June 25, 2026 03:16
@saravan2
saravan2 marked this pull request as ready for review June 25, 2026 03:21
@saravan2
saravan2 requested a review from sboeuf June 25, 2026 03:33
Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs
@saravan2
saravan2 force-pushed the vfio-migration branch 2 times, most recently from d8414ce to 7e81585 Compare June 25, 2026 23:13
@saravan2

saravan2 commented Jun 30, 2026

Copy link
Copy Markdown
Member Author

@likebreath I have rebased #8303 and it is ready for merge with no open items from my side to fulfill. Let me know if you require any more changes.

@likebreath likebreath left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saravan2 Thank you for the good work and the patience. Overall looks good. Some comments below that should be quick to address.

Comment thread pci/src/vfio.rs
Comment thread pci/src/vfio.rs Outdated
Comment thread docs/vfio.md Outdated
Comment thread docs/snapshot_restore.md Outdated
Comment thread docs/snapshot_restore.md Outdated
Comment thread docs/vfio.md Outdated
@saravan2
saravan2 requested a review from likebreath July 1, 2026 01:53
@saravan2

saravan2 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@saravan2 Thank you for the good work and the patience. Overall looks good. Some comments below that should be quick to address.

@likebreath Applied all of your suggestions and resubmitted #8303 after rebase. Thanks for your review.

Comment thread pci/src/vfio.rs

@likebreath likebreath left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the prompt turn-around. One more suggestion. Very close to land.

Comment thread pci/src/vfio.rs Outdated
Comment thread pci/src/vfio.rs
saravan2 added 5 commits July 1, 2026 23:15
Probe VFIO_DEVICE_FEATURE_MIGRATION during VfioCommon::new() and store
the result in a new migration_flags field so later migration phases can
gate state machine transitions.

The probe runs on every instantiation, including snapshot restore,
because migration capability is a property of the host kernel and its
variant driver rather than of any saved VM state.

migration_flags() is added to the internal Vfio trait with a default
implementation that returns Ok(None), meaning not migratable.
VfioDeviceWrapper overrides it to issue the kernel ioctl, while
vfio-user devices keep the default and are always treated as non
migratable.

Allow the VFIO_DEVICE_FEATURE ioctl in the VMM seccomp filter.

Signed-off-by: Saravanan D <[email protected]>
Wire a migratable VFIO device's migration state to the VM lifecycle so
the device's internal state survives snapshot and restore. A device such
as a ConnectX VF bound to mlx5_vfio_pci would otherwise come back blank,
because a plain snapshot saves only the PCI configuration Cloud
Hypervisor owns, not the device's own state.

On save, pause moves the device to STOP and snapshot() drives it through
STOP_COPY to extract the opaque state blob, attached to the device
snapshot as a base64 encoded child. resume() returns it to RUNNING.

All new behavior is gated on migration_flags.is_some(), so devices
without migration support (including vfio-user) retain their previous
snapshot behavior.

If the data read fails after STOP_COPY was entered, the device is
returned to STOP before the error is bubbled, since the STOP_COPY
to STOP arc stays valid. A failed transition into STOP_COPY returns
immediately because a STOP from the resulting ERROR state cannot
help. Full recovery including device reset is deferred.

Since the non BAR write path goes directly to the VFIO device and not
the shadow, the PciConfiguration shadow can get stale. Mirror every
non BAR, non MSI config write into the shadow via write_byte /
write_word / write_reg so snapshot() can capture PCI_COMMAND. Without
this the shadow keeps the values set at device init and snapshot()
encodes PCI_COMMAND as zero.

Use the raw write_byte, write_word, and write_reg helpers rather than
PciConfiguration::write_config_register, which would otherwise drain
pending_bar_reprogram, consumed by the BAR block below, and rerun
MSI-X set_msg_ctl, already done by update_msix_capabilities.

Signed-off-by: Saravanan D <[email protected]>
When a snapshot is loaded, walk the migration v2 state machine
from VfioCommon::set_state() after interrupt state has been
restored. If the device supports migration and a blob is
present, drive RUNNING to RESUMING in a single transition and
write the blob to the data_fd. The kernel handles the
intermediate STOP arc internally. An explicit STOP dwell was
observed to make mlx5_vfio_pci re initialize SQ, CQ, and EQ
indices on top of the just loaded blob, wedging queue state on
resume. The device is left in RESUMING and resume() drives it
to RUNNING during VM resume.

set_state() also pushes PCI_COMMAND to the device via
write_config() after the blob load. Rebuilding the in memory
MSI or MSI-X structs does not touch the kernel's view of
PCI_COMMAND, so without this the VF sits at post reset defaults
with no bus master and mlx5_core ACCESS_REG times out. It
rearms VFIO_DEVICE_SET_IRQS via enable_msi or enable_msix for
the same reason, since replaying the in memory interrupt state
does not reissue the ioctl and the kernel has no eventfds for
this device until it does. Both match QEMU
vfio_pci_load_config().

In allocate_bars, skip add_pci_bar and add_pci_rom_bar on
restore. PciConfiguration::new(Some(state)) already populated
the BAR registers with used=true, so the extra call trips
BarInUse. The bars vec and mmio_regions pushes still need to
happen so the caller can wire bus mappings.

set_state() retrieves the migration blob from the snapshot
unconditionally and rejects a snapshot that carries migration
state when the device does not support migration, rather than
silently dropping the saved state. A device without migration
support and no blob, including vfio-user, still skips the load.

On any transition or write failure during restore, STOP is
attempted as best effort before bubbling the error.

Signed-off-by: Saravanan D <[email protected]>
The VFIO save and load paths drive the kernel migration state machine
through a strict transition sequence and must recover correctly when a
transition or the data transfer fails. Validating that on real hardware
needs a migratable device, which CI does not have, so the behavior would
otherwise go unverified until it breaks in the field.

Introduce a mock Vfio wrapper that records state transitions and keeps
the migration blob in memory, then test VfioCommon save and load against
it. This pins the transition ordering, the data round trip, and the
failure recovery in CI on any host, independent of hardware. The trait
defaults and the VfioMigrationState conversions are covered too, so a
non migratable device and an unknown state value stay well defined. A
restore that carries migration state onto a device without migration
support is checked to fail instead of dropping the state.

A shadow sync test guards the related save path change, confirming a non
BAR config write reaches the PciConfiguration shadow so a snapshot
captures the live value instead of the post init zero.

Signed-off-by: Saravanan D <[email protected]>
Add a Snapshot and Restore section to docs/vfio.md covering the
migration v2 requirements (Linux 5.18 kernel, variant VFIO
driver such as mlx5_vfio_pci) and the restore sequence for
devices that advertise migration v2.

The behavior description covers the full restore sequence. It
documents the RUNNING to RESUMING single transition (the kernel
walks the intermediate STOP arc), the post load PCI_COMMAND push
to the device, and the MSI or MSI-X eventfd rearm that the
kernel state does not carry. Behavior matches QEMU
vfio_pci_load_config().

It notes one limitation, the snapshot format stores the opaque
device blob as base64 inside the snapshot JSON, which may benefit
from a binary transport path for very large state.

docs/snapshot_restore.md replaces its VFIO out of scope
limitation with a short section that points to docs/vfio.md for
the requirements and behavior.

Signed-off-by: Saravanan D <[email protected]>
@saravan2
saravan2 requested a review from likebreath July 2, 2026 00:22
@saravan2

saravan2 commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

@likebreath

Thank you for the prompt turn-around. One more suggestion. Very close to land.

Resubmitted with your suggested changes. Thanks again.

@likebreath
likebreath added this pull request to the merge queue Jul 2, 2026
Merged via the queue into cloud-hypervisor:main with commit f5967cf Jul 2, 2026
39 checks passed
@github-project-automation github-project-automation Bot moved this from 📋 Backlog to ✅ Done in Cloud Hypervisor Roadmap Jul 2, 2026
@rbradford rbradford added the new-feature New feature to include in release notes label Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-feature New feature to include in release notes

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

5 participants