Repository: firecracker-microvm/firecracker
File: src/vmm/src/vstate/vcpu/x86_64.rs (Rust)

Code before:
    /// the list of MSR indices into chunks, call `KVM_GET_MSRS` for each
    /// chunk, and collect into a [`Vec<Msrs>`].
    ///
    /// # Arguments
    ///
    /// * `msr_index_iter`: Iterator over MSR indices.
    ///
    /// # Errors
    ///
    /// * When [`kvm_bindings::Msrs::new`] returns errors.
    /// * When [`kvm_ioctls::VcpuFd::get_msrs`] returns errors.
    /// * When the return value of [`kvm_ioctls::VcpuFd::get_msrs`] (the number of entries that
    ///   could be gotten) is less than expected.
    fn get_msr_chunks(
        &self,
        mut msr_index_iter: impl ExactSizeIterator<Item = u32>,
    ) -> Result<Vec<Msrs>, KvmVcpuError> {
        let num_chunks = msr_index_iter.len() / KVM_MAX_MSR_ENTRIES;
        let excess = msr_index_iter.len() % KVM_MAX_MSR_ENTRIES;

        let mut msr_chunks: Vec<Msrs> = Vec::with_capacity(num_chunks);

        for _ in 0..num_chunks {
            let chunk = self.get_msr_chunk(&mut msr_index_iter, KVM_MAX_MSR_ENTRIES)?;
            msr_chunks.push(chunk);
        }
        if excess != 0 {
            let chunk = self.get_msr_chunk(&mut msr_index_iter, excess)?;
            msr_chunks.push(chunk);
        }

        Self::fix_zero_tsc_deadline_msr(&mut msr_chunks);

        Ok(msr_chunks)
    }

    /// Get single MSR chunk for the given MSR index iterator with
    /// specified maximum length.
    ///
    /// # Arguments
    ///
    /// * `msr_index_iter`: Iterator over MSR indices.
    /// * `max_chunk_len`: Maximum lenght of a chunk to get.
    ///
    /// # Errors
    ///
    /// * When [`kvm_bindings::Msrs::new`] returns errors.
    /// * When [`kvm_ioctls::VcpuFd::get_msrs`] returns errors.
    /// * When the return value of [`kvm_ioctls::VcpuFd::get_msrs`] (the number of entries that
    ///   could be gotten) is less than expected.
    pub fn get_msr_chunk(

Review comment (suggestion):
The `num_chunks` is not the correct length if `excess != 0`. How about this?
```suggestion
        let num_chunks = (msr_index_iter.len() + KVM_MAX_MSR_ENTRIES - 1) / KVM_MAX_MSR_ENTRIES;
        let mut msr_chunks: Vec<Msrs> = Vec::with_capacity(num_chunks);
        for _ in 0..num_chunks - 1 {
            let chunk = self.get_msr_chunk(&mut msr_index_iter, KVM_MAX_MSR_ENTRIES)?;
            msr_chunks.push(chunk);
        }
        let last = msr_index_iter.len() - KVM_MAX_MSR_ENTRIES * (num_chunks - 1);
        let chunk = self.get_msr_chunk(&mut msr_index_iter, last)?;
        msr_chunks.push(chunk);
```

Code after:
    /// the list of MSR indices into chunks, call `KVM_GET_MSRS` for each
    /// chunk, and collect into a [`Vec<Msrs>`].
    ///
    /// # Arguments
    ///
    /// * `msr_index_iter`: Iterator over MSR indices.
    ///
    /// # Errors
    ///
    /// * When [`kvm_bindings::Msrs::new`] returns errors.
    /// * When [`kvm_ioctls::VcpuFd::get_msrs`] returns errors.
    /// * When the return value of [`kvm_ioctls::VcpuFd::get_msrs`] (the number of entries that
    ///   could be gotten) is less than expected.
    fn get_msr_chunks(
        &self,
        mut msr_index_iter: impl ExactSizeIterator<Item = u32>,
    ) -> Result<Vec<Msrs>, KvmVcpuError> {
        let num_chunks = msr_index_iter.len().div_ceil(KVM_MAX_MSR_ENTRIES);

        let mut msr_chunks: Vec<Msrs> = Vec::with_capacity(num_chunks);

        for _ in 0..num_chunks {
            let chunk_len = msr_index_iter.len().min(KVM_MAX_MSR_ENTRIES);
            let chunk = self.get_msr_chunk(&mut msr_index_iter, chunk_len)?;
            msr_chunks.push(chunk);
        }

        Self::fix_zero_tsc_deadline_msr(&mut msr_chunks);

        Ok(msr_chunks)
    }

    /// Get single MSR chunk for the given MSR index iterator with
    /// specified length. Iterator should have enough elements
    /// to fill the chunk with indices, otherwise KVM will
    /// return an error when processing half filled chunk.
    ///
    /// # Arguments
    ///
    /// * `msr_index_iter`: Iterator over MSR indices.
    /// * `chunk_size`: Lenght of a chunk.
    ///
    /// # Errors
    ///
    /// * When [`kvm_bindings::Msrs::new`] returns errors.
    /// * When [`kvm_ioctls::VcpuFd::get_msrs`] returns errors.
    /// * When the return value of [`kvm_ioctls::VcpuFd::get_msrs`] (the number of entries that
    ///   could be gotten) is less than expected.
    pub fn get_msr_chunk(
        &self,
        msr_index_iter: impl Iterator<Item = u32>,