Skip to main content

arcbox_hypervisor/linux/vm/
irq.rs

1use std::os::unix::io::RawFd;
2
3use crate::error::HypervisorError;
4
5use super::KvmVm;
6
7impl KvmVm {
8    /// Sets the IRQ line level on the in-kernel irqchip.
9    ///
10    /// For edge-triggered interrupts, call with level=true then level=false.
11    /// For level-triggered interrupts, keep level=true until acknowledged.
12    ///
13    /// # Arguments
14    /// * `gsi` - Global System Interrupt number
15    /// * `level` - true to assert, false to deassert
16    pub fn set_irq_line(&self, gsi: u32, level: bool) -> Result<(), HypervisorError> {
17        self.vm_fd
18            .set_irq_line(gsi, level)
19            .map_err(|e| HypervisorError::DeviceError(format!("Failed to set IRQ line: {}", e)))
20    }
21
22    /// Triggers an edge-triggered interrupt.
23    ///
24    /// Convenience method that asserts then immediately deasserts the IRQ line.
25    pub fn trigger_edge_irq(&self, gsi: u32) -> Result<(), HypervisorError> {
26        self.set_irq_line(gsi, true)?;
27        self.set_irq_line(gsi, false)
28    }
29
30    /// Registers an eventfd for IRQ injection (IRQFD).
31    ///
32    /// When the eventfd is signaled (write 1 to it), KVM will automatically
33    /// inject the specified GSI into the guest. This is the most efficient
34    /// method for interrupt delivery.
35    ///
36    /// # Arguments
37    /// * `eventfd` - The eventfd file descriptor
38    /// * `gsi` - The GSI to inject when eventfd is signaled
39    /// * `resample_fd` - For level-triggered IRQs, optional resample eventfd
40    pub fn register_irqfd(
41        &self,
42        eventfd: RawFd,
43        gsi: u32,
44        resample_fd: Option<RawFd>,
45    ) -> Result<(), HypervisorError> {
46        self.vm_fd
47            .register_irqfd(eventfd, gsi, resample_fd)
48            .map_err(|e| HypervisorError::DeviceError(format!("Failed to register IRQFD: {}", e)))
49    }
50
51    /// Unregisters an eventfd for IRQ injection.
52    pub fn unregister_irqfd(&self, eventfd: RawFd, gsi: u32) -> Result<(), HypervisorError> {
53        self.vm_fd
54            .unregister_irqfd(eventfd, gsi)
55            .map_err(|e| HypervisorError::DeviceError(format!("Failed to unregister IRQFD: {}", e)))
56    }
57}