(
&self,
src_vm_config: &Arc<Mutex<VmConfig>>,
src_vm_cpuid: &[hypervisor::arch::x86::CpuIdEntry],
)
| 1554 | |
| 1555 | #[cfg(all(feature = "kvm", target_arch = "x86_64"))] |
| 1556 | fn vm_check_cpuid_compatibility( |
| 1557 | &self, |
| 1558 | src_vm_config: &Arc<Mutex<VmConfig>>, |
| 1559 | src_vm_cpuid: &[hypervisor::arch::x86::CpuIdEntry], |
| 1560 | ) -> result::Result<(), MigratableError> { |
| 1561 | #[cfg(feature = "tdx")] |
| 1562 | if src_vm_config.lock().unwrap().is_tdx_enabled() { |
| 1563 | return Err(MigratableError::MigrateReceive(anyhow!( |
| 1564 | "Live Migration is not supported when TDX is enabled" |
| 1565 | ))); |
| 1566 | } |
| 1567 | |
| 1568 | // We check the `CPUID` compatibility of between the source vm and destination, which is |
| 1569 | // mostly about feature compatibility. |
| 1570 | let dest_cpuid = &{ |
| 1571 | let vm_config = &src_vm_config.lock().unwrap(); |
| 1572 | |
| 1573 | let phys_bits = |
| 1574 | vm::physical_bits(self.hypervisor.as_ref(), vm_config.cpus.max_phys_bits); |
| 1575 | arch::generate_common_cpuid( |
| 1576 | self.hypervisor.as_ref(), |
| 1577 | &arch::CpuidConfig { |
| 1578 | phys_bits, |
| 1579 | kvm_hyperv: vm_config.cpus.kvm_hyperv, |
| 1580 | #[cfg(feature = "tdx")] |
| 1581 | tdx: false, |
| 1582 | amx: vm_config.cpus.features.amx, |
| 1583 | }, |
| 1584 | ) |
| 1585 | .map_err(|e| { |
| 1586 | MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {e:?}")) |
| 1587 | })? |
| 1588 | }; |
| 1589 | arch::CpuidFeatureEntry::check_cpuid_compatibility(src_vm_cpuid, dest_cpuid).map_err(|e| { |
| 1590 | MigratableError::MigrateReceive(anyhow!( |
| 1591 | "Error checking cpu feature compatibility': {e:?}" |
| 1592 | )) |
| 1593 | }) |
| 1594 | } |
| 1595 | |
| 1596 | fn vm_restore( |
| 1597 | &mut self, |
no test coverage detected