@@ -9,6 +9,8 @@ address range, IRQ number, etc)
99
1010## Design
1111
12+ ### I/O
13+
1214The virtual device model is built around four traits, ` DevicePio ` and
1315` MutDevicePio ` for
1416[ Programmed I/O] ( https://en.wikipedia.org/wiki/Programmed_input%E2%80%93output )
@@ -42,8 +44,40 @@ that there’s a virtual device registered on the bus for the requested address,
4244and finally sends the request to that device.
4345![ vm-device] ( https://user-images.githubusercontent.com/241037/143853115-b1526028-6836-4845-a311-71cf989c60ef.png )
4446
47+ ### Interrupts
48+
49+ Interrupt configuration is built around the ` Interrupt ` and ` InterruptSourceGroup `
50+ traits. These traits allow device control code that is developed in separate
51+ crates from the VMM (which typically implements the interrupt mechanisms) to
52+ configure interrupt delivery to the guest VM without having a dependency on the
53+ implementation of the interrupt mechanism.
54+ The ` EdgeInterrupt ` and ` LevelInterrupt ` are traits that provide interrupt
55+ assertion mechanisms and can be used by device implementations directly in order
56+ to inject interrupts in the guest VM.
57+
58+ The ` Interrupt ` trait provides methods that are used by devices to enable and
59+ disable interrupt generation by registering the interrupt with the VMM. Access
60+ to additional interrupt properties is defined in new super-traits.
61+ ` ConfigurableInterrupt ` allows for devices to send or receive interrupt
62+ configuration parameters to/from the implementation inside the VMM. This is useful
63+ when devices need to specify custom data that the VMM will use when delivering the
64+ interrupt (e.g. MSI device id, PCI INTx pin etc).
65+ ` MaskableInterrupt ` is also defined as a super-trait for use with interrupts that
66+ can be masked/unmasked.
67+
68+ An ` InterruptSourceGroup ` stores a collection of interrupts of the same type. It
69+ is the interface through which a device may request or release interrupts and
70+ perform group related actions like enabling or disabling all interrupts at once.
71+ Each device that generates interrupts can be assigned one or more
72+ ` InterruptSourceGroup ` s (depending on the types of interrupts it uses or logical
73+ grouping). The following diagram depicts the interaction between the components
74+ that use the interrupt interface:
75+
76+ ![ vm-device-interrupts] ( https://user-images.githubusercontent.com/86006646/148783015-fea49a7c-cff8-4ec7-8766-00b0baed41c5.png )
77+
4578## Usage
4679
80+ ### I/O
4781A device is usually attached to a particular bus and thus needs to implement a
4882trait of only one type. For example, serial port on x86 is a PIO device, while
4983VirtIO devices use MMIO. It’s also possible for a device to implement both. Once
@@ -67,6 +101,44 @@ address range to the device. The requests are dispatched by the client code, for
67101example when handling VM exits, using ` IoManager ` 's methods ` pio_read ` ,
68102` pio_write ` , ` mmio_read ` and ` mmio_write ` .
69103
104+ ### Interrupts
105+
106+ To allow configuration of interrupts, a VMM must implement the ` Interrupt ` and
107+ ` InterruptSourceGroup ` traits for the interrupt mechanisms that the device
108+ requires. Implementation is machine or VMM specific and may depend on the types
109+ and number of IRQ chips that the machine has or interrupt delivery mechanisms
110+ (e.g. ` EventFd ` s).
111+ The device interrupt configuration code generally does not concern itself with
112+ the actual implementation of the interrupts and will be initialized with one or
113+ more ` InterruptSourceGroup ` s by the VMM.
114+
115+ In order to allow devices to inject interrupt lines in the guest, a VMM must
116+ also implement either the ` EdgeInterrupt ` or ` LevelInterrupt ` traits, depending
117+ on the type of interrupt assertion mechanism that is supported. Devices use
118+ objects that have these traits to signal an interrupt to the guest.
119+
120+ The device configuration code may define constraints for the types of interrupts
121+ that it needs by combining the supertraits defined into trait bounds (e.g. if it
122+ needs a ` ConfigurableInterrupt ` that can receive the ` LegacyIrqConfig `
123+ configuration struct). MSI and legacy interrupt traits are added in this crate
124+ for ease of use. Configuration of these interrupt types are standardised.
125+ ` MsiInterrupt ` can also be used for MSI-X interrupts. These traits only define
126+ the configuration bounds for these interrupt types. ` EdgeInterrupt ` or
127+ ` LevelInterrupt ` will still need to be implemented in order to allow devices
128+ to use these interrupts. MSI interrupts are considered edge-triggered while
129+ ` LegacyInterrupt ` can be either edge-triggered (typically in the case of ISA
130+ interrupts) or level triggered (in the case of INTx interrupts).
131+
132+ In order to have access to the underlying notification mechanisms used by the
133+ hypervisor, the device configuration may use the ` AsRefTriggerNotifier ` and the
134+ ` AsRefResampleNotifier ` conversion traits and specify the ` NotifierType ` associated
135+ type. This type defines the interrupt delivery mechanism and is specific to the
136+ Hypervisor (e.g. KVM irqfd, Xen evtchn etc).
137+
138+ One example of this requirement is the development of a VFIO device. Since VFIO
139+ can trigger a KVM irqfd directly, the VFIO device would need to get access to the
140+ underlying irqfd in order to register it with VFIO.
141+
70142## Examples
71143
72144### Implementing a simple log PIO device
@@ -119,3 +191,4 @@ This project is licensed under either of:
119191
120192- [ Apache License] ( http://www.apache.org/licenses/LICENSE-2.0 ) , Version 2.0
121193- [ BSD-3-Clause License] ( https://opensource.org/licenses/BSD-3-Clause )
194+
0 commit comments