Repository: firecracker-microvm/firecracker
File: src/vmm/src/lib.rs (Rust)

Code before:

        let cpu_configs = vcpu_responses
            .into_iter()
            .map(|response| match response {
                VcpuResponse::DumpedCpuConfig(cpu_config) => Ok(*cpu_config),
                VcpuResponse::Error(err) => Err(DumpCpuConfigError::DumpCpuConfig(err)),
                VcpuResponse::NotAllowed(reason) => Err(DumpCpuConfigError::NotAllowed(reason)),
                _ => Err(DumpCpuConfigError::UnexpectedResponse),
            })
            .collect::<Result<Vec<CpuConfiguration>, DumpCpuConfigError>>()?;

        Ok(cpu_configs)
    }

    /// Adds new vCPUs to VMM.
    #[cfg(target_arch = "x86_64")]
    pub fn hotplug_vcpus(
        &mut self,
        config: HotplugVcpuConfig,
    ) -> Result<MachineConfigUpdate, HotplugVcpuError> {
        use crate::logger::IncMetric;
        #[allow(clippy::cast_possible_truncation)]
        if config.vcpu_count < 1 {
            return Err(HotplugVcpuError::VcpuCountTooLow);
        } else if config.vcpu_count > MAX_SUPPORTED_VCPUS
            || self.vcpus_handles.len() as u8 + config.vcpu_count > MAX_SUPPORTED_VCPUS
        {
            return Err(HotplugVcpuError::VcpuCountTooHigh);
        }

        // Create and start new vcpus
        let mut vcpus = Vec::with_capacity(config.vcpu_count as usize);

        #[allow(clippy::cast_possible_truncation)]
        let start_idx = self.vcpus_handles.len() as u8;
        for cpu_idx in start_idx..(start_idx + config.vcpu_count) {
            let exit_evt = self
                .vcpus_exit_evt
                .try_clone()
                .map_err(HotplugVcpuError::EventFd)?;
            let vcpu =
                Vcpu::new(cpu_idx, &self.vm, exit_evt).map_err(HotplugVcpuError::VcpuCreate)?;
            vcpus.push(vcpu);
        }

        self.start_vcpus(
            vcpus,
            self.seccomp_filters
                .get("vcpu")
                .ok_or_else(|| HotplugVcpuError::MissingSeccompFilters("vcpu".to_string()))?
                .clone(),

Review comment (suggestion):
`self.vcpus_handles.len() as u8 + config.vcpu_count > MAX_SUPPORTED_VCPUS` check should be enough here.

Code after:

        let cpu_configs = vcpu_responses
            .into_iter()
            .map(|response| match response {
                VcpuResponse::DumpedCpuConfig(cpu_config) => Ok(*cpu_config),
                VcpuResponse::Error(err) => Err(DumpCpuConfigError::DumpCpuConfig(err)),
                VcpuResponse::NotAllowed(reason) => Err(DumpCpuConfigError::NotAllowed(reason)),
                _ => Err(DumpCpuConfigError::UnexpectedResponse),
            })
            .collect::<Result<Vec<CpuConfiguration>, DumpCpuConfigError>>()?;

        Ok(cpu_configs)
    }

    /// Adds new vCPUs to VMM.
    #[cfg(target_arch = "x86_64")]
    pub fn hotplug_vcpus(
        &mut self,
        config: HotplugVcpuConfig,
    ) -> Result<MachineConfigUpdate, HotplugVcpuError> {
        use crate::logger::IncMetric;
        if config.add < 1 {
            return Err(HotplugVcpuError::VcpuCountTooLow);
        } else if self
            .vcpus_handles
            .len()
            .checked_add(config.add.into())
            .ok_or(HotplugVcpuError::VcpuCountTooHigh)?
            > MAX_SUPPORTED_VCPUS.into()
        {
            return Err(HotplugVcpuError::VcpuCountTooHigh);
        }

        // Create and start new vcpus
        let mut vcpus = Vec::with_capacity(config.add.into());

        #[allow(clippy::cast_possible_truncation)]
        let start_idx = self.vcpus_handles.len().try_into().unwrap();
        for cpu_idx in start_idx..(start_idx + config.add) {
            let exit_evt = self
                .vcpus_exit_evt
                .try_clone()
                .map_err(HotplugVcpuError::EventFd)?;
            let vcpu =
                Vcpu::new(cpu_idx, &self.vm, exit_evt).map_err(HotplugVcpuError::VcpuCreate)?;
            vcpus.push(vcpu);
        }

        self.start_vcpus(
            vcpus,
            self.seccomp_filters