Repository: firecracker-microvm/firecracker
File: src/vmm/src/devices/acpi/vmgenid.rs (Rust)

Code before:
        }
    }

    /// Create a new VMGenID device
    ///
    /// Allocate memory and a GSI for sending notifications and build the device
    pub fn new(resource_allocator: &mut ResourceAllocator) -> Self {
        let gsi = resource_allocator
            .allocate_gsi_legacy(1)
            .expect("vmgenid: Could not allocate GSI for VMGenID");
        // The generation ID needs to live in an 8-byte aligned buffer
        let addr = resource_allocator
            .allocate_system_memory(VMGENID_MEM_SIZE, 8, vm_allocator::AllocPolicy::LastMatch)
            .expect("vmgenid: Could not allocate guest RAM for VMGenID");

        Self::from_parts(GuestAddress(addr), gsi[0])
    }

    // Create a 16-bytes random number
    fn make_genid() -> u128 {
        let mut gen_id_bytes = [0u8; 16];
        rand::fill(&mut gen_id_bytes).expect("vmgenid: could not create new generation ID");
        u128::from_le_bytes(gen_id_bytes)
    }

    /// Notify guest afetr snapshot restore
    ///
    /// This will only have effect if we have updated the generation ID in guest memory, i.e. when
    /// re-creating the device after snapshot resumption.
    pub fn post_restore(&self) -> Result<(), std::io::Error> {
        self.interrupt_evt
            .trigger()
            .inspect_err(|err| error!("vmgenid: could not send guest notification: {err}"))?;
        debug!("vmgenid: notifying guest about new generation ID");
        Ok(())
    }

    /// Attach the [`VmGenId`] device
    pub fn activate(&self, mem: &GuestMemoryMmap) -> Result<(), GuestMemoryError> {
        debug!(
            "vmgenid: writing new generation ID to guest: {:#034x}",
            self.gen_id
        );
        mem.write_slice(&self.gen_id.to_le_bytes(), self.guest_address)
            .inspect_err(|err| error!("vmgenid: could not write generation ID to guest: {err}"))?;

        Ok(())
    }
}

/// Logic to save/restore the state of a VMGenID device

Review comment (suggestion):
```suggestion
    /// Notify guest after snapshot restore
```

Code after:
            "vmgenid: building VMGenID device. Address: {:#010x}. IRQ: {}",
            guest_address.0, gsi
        );
        let interrupt_evt = EventFdTrigger::new(
            EventFd::new(libc::EFD_NONBLOCK).map_err(VmGenIdError::CreateEventFd)?,
        );
        let gen_id = Self::make_genid();

        Ok(Self {
            gen_id,
            interrupt_evt,
            guest_address,
            gsi,
        })
    }

    /// Create a new VMGenID device
    ///
    /// Allocate memory and a GSI for sending notifications and build the device
    pub fn new(resource_allocator: &mut ResourceAllocator) -> Result<Self, VmGenIdError> {
        let gsi = resource_allocator
            .allocate_gsi_legacy(1)
            .map_err(VmGenIdError::AllocateGsi)?[0];
        // The generation ID needs to live in an 8-byte aligned buffer
        let addr = resource_allocator
            .allocate_system_memory(VMGENID_MEM_SIZE, 8, vm_allocator::AllocPolicy::LastMatch)
            .map_err(VmGenIdError::AllocateMemory)?;

        Self::from_parts(GuestAddress(addr), gsi)
    }

    // Create a 16-bytes random number
    fn make_genid() -> u128 {
        let mut gen_id_bytes = [0u8; 16];
        rand::fill(&mut gen_id_bytes).expect("vmgenid: could not create new generation ID");
        u128::from_le_bytes(gen_id_bytes)
    }

    /// Notify guest after snapshot restore
    ///
    /// This will only have effect if we have updated the generation ID in guest memory, i.e. when
    /// re-creating the device after snapshot resumption.
    pub fn post_restore(&self) -> Result<(), VmGenIdError> {
        self.interrupt_evt
            .trigger()
            .map_err(VmGenIdError::NotifyGuest)?;
        debug!("vmgenid: notifying guest about new generation ID");
        Ok(())
    }

    /// Attach the [`VmGenId`] device