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

Code before:
            bus: crate::devices::Bus::new(),
            id_to_dev_info: HashMap::new(),
            #[cfg(target_arch = "x86_64")]
            dsdt_data: vec![],
        }
    }

    /// Allocates resources for a new device to be added.
    fn allocate_mmio_resources(
        &mut self,
        resource_allocator: &mut ResourceAllocator,
        irq_count: u32,
    ) -> Result<MMIODeviceInfo, MmioError> {
        if irq_count != 0 && irq_count != 1 {
            return Err(MmioError::InvalidIrqConfig);
        }
        let irqs_vec = resource_allocator.allocate_gsi(irq_count)?; 
        let irq : Option<NonZeroU32> = if irqs_vec.len() == 0 {
            None
        } else {
            NonZeroU32::new(irqs_vec.get(0).unwrap().clone())
        };

        let device_info = MMIODeviceInfo {
            addr: resource_allocator.allocate_mmio_memory(
                MMIO_LEN,
                MMIO_LEN,
                AllocPolicy::FirstMatch,
            )?,
            len: MMIO_LEN,
            irq,
        };
        Ok(device_info)
    }

    /// Register a device at some MMIO address.
    fn register_mmio_device(
        &mut self,
        identifier: (DeviceType, String),
        device_info: MMIODeviceInfo,
        device: Arc<Mutex<BusDevice>>,
    ) -> Result<(), MmioError> {
        self.bus
            .insert(device, device_info.addr, device_info.len)
            .map_err(MmioError::BusInsert)?;
        self.id_to_dev_info.insert(identifier, device_info);
        Ok(())
    }

    /// Register a virtio-over-MMIO device to be used via MMIO transport at a specific slot.
    pub fn register_mmio_virtio(

Review comment (performance):
Slightly simpler (albeit less efficient on the error path, but, its the error path, so we don't really care)

```suggestion
        let irq = match &resource_allocator.allocate_gsi(irq_count)? {
            &[] => None, 
            &[irq] => NonZeroU32::new(irq),
            _ =>  return Err(MmioError::InvalidIrqConfig)
        };
```

Code after:
    #[cfg(target_arch = "x86_64")]
    pub(crate) dsdt_data: Vec<u8>,
}

impl MMIODeviceManager {
    /// Create a new DeviceManager handling mmio devices (virtio net, block).
    pub fn new() -> MMIODeviceManager {
        MMIODeviceManager {
            bus: crate::devices::Bus::new(),
            id_to_dev_info: HashMap::new(),
            #[cfg(target_arch = "x86_64")]
            dsdt_data: vec![],
        }
    }

    /// Allocates resources for a new device to be added.
    fn allocate_mmio_resources(
        &mut self,
        resource_allocator: &mut ResourceAllocator,
        irq_count: u32,
    ) -> Result<MMIODeviceInfo, MmioError> {
        let irq = match resource_allocator.allocate_gsi(irq_count)?[..] {
            [] => None,
            [irq] => NonZeroU32::new(irq),
            _ => return Err(MmioError::InvalidIrqConfig),
        };

        let device_info = MMIODeviceInfo {
            addr: resource_allocator.allocate_mmio_memory(
                MMIO_LEN,
                MMIO_LEN,
                AllocPolicy::FirstMatch,
            )?,
            len: MMIO_LEN,
            irq,
        };
        Ok(device_info)
    }

    /// Register a device at some MMIO address.
    fn register_mmio_device(
        &mut self,
        identifier: (DeviceType, String),
        device_info: MMIODeviceInfo,
        device: Arc<Mutex<BusDevice>>,
    ) -> Result<(), MmioError> {
        self.bus
            .insert(device, device_info.addr, device_info.len)
            .map_err(MmioError::BusInsert)?;
        self.id_to_dev_info.insert(identifier, device_info);
        Ok(())