@@ -9,6 +9,8 @@ address range, IRQ number, etc)
9
9
10
10
## Design
11
11
12
+ ### I/O
13
+
12
14
The virtual device model is built around four traits, ` DevicePio ` and
13
15
` MutDevicePio ` for
14
16
[ 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,
42
44
and finally sends the request to that device.
43
45
![ vm-device] ( https://user-images.githubusercontent.com/241037/143853115-b1526028-6836-4845-a311-71cf989c60ef.png )
44
46
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
+
45
78
## Usage
46
79
80
+ ### I/O
47
81
A device is usually attached to a particular bus and thus needs to implement a
48
82
trait of only one type. For example, serial port on x86 is a PIO device, while
49
83
VirtIO 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
67
101
example when handling VM exits, using ` IoManager ` 's methods ` pio_read ` ,
68
102
` pio_write ` , ` mmio_read ` and ` mmio_write ` .
69
103
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
+
70
142
## Examples
71
143
72
144
### Implementing a simple log PIO device
@@ -119,3 +191,4 @@ This project is licensed under either of:
119
191
120
192
- [ Apache License] ( http://www.apache.org/licenses/LICENSE-2.0 ) , Version 2.0
121
193
- [ BSD-3-Clause License] ( https://opensource.org/licenses/BSD-3-Clause )
194
+
0 commit comments