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}