| 961 | } |
| 962 | |
| 963 | fn create_vcpu( |
| 964 | &mut self, |
| 965 | cpu_id: u32, |
| 966 | snapshot: Option<&Snapshot>, |
| 967 | ) -> Result<Arc<Mutex<Vcpu>>> { |
| 968 | info!("Creating vCPU: cpu_id = {cpu_id}"); |
| 969 | |
| 970 | #[cfg(target_arch = "x86_64")] |
| 971 | let topology = self.get_vcpu_topology(); |
| 972 | #[cfg(target_arch = "x86_64")] |
| 973 | let x2apic_id = arch::x86_64::get_x2apic_id(cpu_id, topology); |
| 974 | #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] |
| 975 | let x2apic_id = cpu_id; |
| 976 | |
| 977 | let mut vcpu = Vcpu::new( |
| 978 | cpu_id, |
| 979 | x2apic_id, |
| 980 | self.vm.as_ref(), |
| 981 | Some(self.vm_ops.clone()), |
| 982 | #[cfg(target_arch = "x86_64")] |
| 983 | self.hypervisor.get_cpu_vendor(), |
| 984 | )?; |
| 985 | |
| 986 | if let Some(snapshot) = snapshot { |
| 987 | // AArch64 vCPUs should be initialized after created. |
| 988 | #[cfg(target_arch = "aarch64")] |
| 989 | vcpu.init(self.vm.as_ref())?; |
| 990 | |
| 991 | let state: CpuState = snapshot.to_state().map_err(|e| { |
| 992 | Error::VcpuCreate(anyhow!("Could not get vCPU state from snapshot {e:?}")) |
| 993 | })?; |
| 994 | vcpu.vcpu |
| 995 | .set_state(&state) |
| 996 | .map_err(|e| Error::VcpuCreate(anyhow!("Could not set the vCPU state {e:?}")))?; |
| 997 | |
| 998 | vcpu.saved_state = Some(state); |
| 999 | } |
| 1000 | |
| 1001 | let vcpu = Arc::new(Mutex::new(vcpu)); |
| 1002 | |
| 1003 | // Adding vCPU to the CpuManager's vCPU list. |
| 1004 | self.vcpus.push(vcpu.clone()); |
| 1005 | |
| 1006 | Ok(vcpu) |
| 1007 | } |
| 1008 | |
| 1009 | pub fn configure_vcpu( |
| 1010 | &self, |