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

Code before:
    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(
        &mut self,
        vm: &VmFd,
        device_id: String,
        mmio_device: MmioTransport,
        device_info: &MMIODeviceInfo,
    ) -> Result<(), MmioError> {
        // Our virtio devices are currently hardcoded to use a single IRQ.
        // Validate that requirement.
        if device_info.irq.is_none() {
            return Err(MmioError::InvalidIrqConfig);
        }
        let identifier;
        {
            let locked_device = mmio_device.locked_device();
            identifier = (DeviceType::Virtio(locked_device.device_type()), device_id);
            for (i, queue_evt) in locked_device.queue_events().iter().enumerate() {
                let io_addr = IoEventAddress::Mmio(
                    device_info.addr + u64::from(crate::devices::virtio::NOTIFY_REG_OFFSET),
                );
                vm.register_ioevent(queue_evt, &io_addr, u32::try_from(i).unwrap())
                    .map_err(MmioError::RegisterIoEvent)?;
            }
            vm.register_irqfd(locked_device.interrupt_evt(), device_info.irq.unwrap().get())
                .map_err(MmioError::RegisterIrqFd)?;
        }

        self.register_mmio_device(
            identifier,
            device_info.clone(),
            Arc::new(Mutex::new(BusDevice::MmioTransport(mmio_device))),
        )
    }

    /// Append a registered virtio-over-MMIO device to the kernel cmdline.
    #[cfg(target_arch = "x86_64")]
    pub fn add_virtio_device_to_cmdline(

Review comment (suggestion):
We can avoid the `unwrap()` below by doing

```suggestion
        let Some(irq) = device_info.irq else {
            return Err(MmioError::InvalidIrqConfig)
        };
```

Code after:
        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(
        &mut self,
        vm: &VmFd,
        device_id: String,
        mmio_device: MmioTransport,
        device_info: &MMIODeviceInfo,
    ) -> Result<(), MmioError> {
        // Our virtio devices are currently hardcoded to use a single IRQ.
        // Validate that requirement.
        let Some(irq) = device_info.irq else {
            return Err(MmioError::InvalidIrqConfig);
        };
        let identifier;
        {
            let locked_device = mmio_device.locked_device();
            identifier = (DeviceType::Virtio(locked_device.device_type()), device_id);
            for (i, queue_evt) in locked_device.queue_events().iter().enumerate() {
                let io_addr = IoEventAddress::Mmio(
                    device_info.addr + u64::from(crate::devices::virtio::NOTIFY_REG_OFFSET),
                );
                vm.register_ioevent(queue_evt, &io_addr, u32::try_from(i).unwrap())
                    .map_err(MmioError::RegisterIoEvent)?;
            }
            vm.register_irqfd(&locked_device.interrupt_trigger().irq_evt, irq.get())
                .map_err(MmioError::RegisterIrqFd)?;
        }

        self.register_mmio_device(
            identifier,
            device_info.clone(),
            Arc::new(Mutex::new(BusDevice::MmioTransport(mmio_device))),
        )
    }