Skip to content

Commit

Permalink
README.md: Add design for interrupt abstractions
Browse files Browse the repository at this point in the history
Add a brief description of the design of the Interrupt abstractions.

Signed-off-by: Alexandru-Cezar Sardan <[email protected]>
  • Loading branch information
alsrdn authored and Alexandru-Cezar Sardan committed Jan 28, 2022
1 parent c84ce0c commit 3d87a2d
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ address range, IRQ number, etc)

## Design

### I/O

The virtual device model is built around four traits, `DevicePio` and
`MutDevicePio` for
[Programmed I/O](https://en.wikipedia.org/wiki/Programmed_input%E2%80%93output)
Expand Down Expand Up @@ -42,8 +44,38 @@ that there’s a virtual device registered on the bus for the requested address,
and finally sends the request to that device.
![vm-device](https://user-images.githubusercontent.com/241037/143853115-b1526028-6836-4845-a311-71cf989c60ef.png)

### Interrupts

Interrupt delivery and configuration is built around the `Interrupt` and
`InterruptSourceGroup` traits. These traits allow devices that are developped in
separate crates from the VMM to trigger and configure interrupt delivery to the
guest VM without having a dependency on the implementation of the interrupt
mechanism.

The `Interrupt` trait provides methods that are used by devices to trigger,
enable and disable interrupts. Access to additional interrupt properties
is defined in new super-traits. `ConfigurableInterrupt` allows for devices to
send or receive interrupt configuration parameters to/from the implementation
inside the VMM. This is useful when devices need to specify custom data that
the VMM will use when delivering the interrupt (e.g. MSI device id, PCI
INTx pin etc).
`MaskableInterrupt` is also defined as a supertrait for use with interrupts
that can be masked/unmasked.
Using super-traits for these properties allows further extension in the future.

An `InterruptSourceGroup` stores a collection of interrupts of the same type and
is the interface through which a device may request or release interrupts and
perform group related actions like enabling or disabling all interrupts at once.
Each device that generates interrupts can be assigned one or more
`InterruptSourceGroup`s (depending on the types of interrupts it uses or logical
grouping.) The following diagram depincts the interaction between the components
that use the interrupt interface:

![vm-device-interrupts](https://user-images.githubusercontent.com/86006646/148783015-fea49a7c-cff8-4ec7-8766-00b0baed41c5.png)

## Usage

### I/O
A device is usually attached to a particular bus and thus needs to implement a
trait of only one type. For example, serial port on x86 is a PIO device, while
VirtIO devices use MMIO. It’s also possible for a device to implement both. Once
Expand All @@ -67,6 +99,26 @@ address range to the device. The requests are dispatched by the client code, for
example when handling VM exits, using `IoManager`'s methods `pio_read`,
`pio_write`, `mmio_read` and `mmio_write`.

### Interrupts

To allow a device to use interrupts, a VMM must implement the `Interrupt` and
`InterruptSourceGroup` traits for the interrupt mechanisms that the device requires.
Implementation is machine or VMM speciffic and may depend on the types and number
of IRQ chips that the machine has or interrupt delivery mechanisms (e.g. `EventFd`s).
The device generally does not concern itself with the actual implementation of
the interrupts and will be initialized with one or more `InterruptSourceGroup`s
by the VMM.

The device may define constraints for the types of interrupts that it needs
(e.g. it needs a `ConfigurableInterrupt` that can receive the `LegacyIrqConfig`
configuration struct).
The device may also define constraints regarding the type of `NotifierType` that the
`Interrupt` is using. This type defines the interrupt delivery mechanism and is
specific to the Hypervisor (e.g. KVM irqfd, Xen evtchn etc).
One example of this requirement is the development of a VFIO device. Since VFIO
can trigger a KVM irqfd directly, the VFIO device would need to get access to the
underlying irqfd in order to register it with VFIO.

## Examples

### Implementing a simple log PIO device
Expand Down Expand Up @@ -119,3 +171,4 @@ This project is licensed under either of:

- [Apache License](http://www.apache.org/licenses/LICENSE-2.0), Version 2.0
- [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause)

0 comments on commit 3d87a2d

Please sign in to comment.