vmcore/irqfd.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Traits for irqfd-based interrupt delivery.
5//!
6//! irqfd allows a hypervisor to directly inject an MSI into a guest when an
7//! event is signaled, without involving userspace in the interrupt delivery
8//! path. This is used for device passthrough (e.g., VFIO) where the physical
9//! device signals an event and the hypervisor injects the corresponding MSI
10//! into the guest VM.
11
12use pal_event::Event;
13
14/// Trait for partitions that support irqfd-based interrupt delivery.
15///
16/// An irqfd associates an event with a GSI (Global System Interrupt), and a
17/// GSI routing table maps GSIs to MSI addresses and data values. When the
18/// event is signaled, the kernel looks up the GSI routing and injects the
19/// configured MSI into the guest without a usermode transition.
20pub trait IrqFd: Send + Sync {
21 /// Creates a new irqfd route.
22 ///
23 /// Allocates a GSI, creates an event, and registers the event with the
24 /// hypervisor so that signaling it injects the configured MSI into the
25 /// guest.
26 ///
27 /// The caller retrieves the event via [`IrqFdRoute::event`] to pass to
28 /// VFIO or other interrupt sources.
29 ///
30 /// When the route is dropped, the irqfd is unregistered and the GSI is
31 /// freed.
32 fn new_irqfd_route(&self) -> anyhow::Result<Box<dyn IrqFdRoute>>;
33}
34
35/// A handle to a registered irqfd route.
36///
37/// Each route represents a single GSI with an associated event. When the
38/// event is signaled (e.g., by VFIO on a device interrupt), the kernel injects
39/// the MSI configured via [`enable`](IrqFdRoute::enable) into the guest.
40///
41/// Dropping this handle unregisters the irqfd and frees the GSI.
42pub trait IrqFdRoute: Send + Sync {
43 /// Returns the event that triggers interrupt injection when signaled.
44 ///
45 /// Pass this to VFIO `map_msix` or any other interrupt source. On Linux,
46 /// this is an eventfd created by the implementation. On WHP (future), this
47 /// is the event handle returned by `WHvCreateTrigger`.
48 fn event(&self) -> &Event;
49
50 /// Sets the MSI routing for this irqfd's GSI.
51 ///
52 /// `address` and `data` are the MSI address and data values that the
53 /// hypervisor will use when injecting the interrupt into the guest.
54 /// `devid` is an optional device identity used by backends that need a
55 /// device ID for MSI routing (e.g., GICv3 ITS).
56 fn enable(&self, address: u64, data: u32, devid: Option<u32>);
57
58 /// Disables the MSI routing for this irqfd's GSI.
59 ///
60 /// Disarms the irqfd so that signaling the event no longer injects an
61 /// interrupt. Interrupts that arrive while disabled remain pending on
62 /// the event and will be delivered when [`enable`](IrqFdRoute::enable)
63 /// is called, or can be drained by waiting on the event directly.
64 fn disable(&self);
65}