Skip to main content

petri/vm/qemu/
devices.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! QEMU device configurations.
5// TODO: should some/all of these be backend agnostic?
6
7/// A device to add to the platform.
8#[derive(Debug, Clone)]
9pub enum DeviceConfig {
10    /// A virtio-blk disk device.
11    VirtioBlk(VirtioBlkDeviceConfig),
12    /// A QEMU `edu` device — a simple PCI device with a register-programmed
13    /// DMA engine. Used as a P2P DMA *initiator* in device-assignment tests.
14    Edu(EduDeviceConfig),
15    /// A QEMU `ivshmem-plain` device — a PCI device whose BAR2 is a
16    /// prefetchable, RAM-backed memory window. Used as a P2P DMA *target*
17    /// (peer BAR) in device-assignment tests.
18    IvshmemPlain(IvshmemPlainDeviceConfig),
19}
20
21impl DeviceConfig {
22    /// The device's name
23    pub fn name(&self) -> &str {
24        match self {
25            DeviceConfig::VirtioBlk(cfg) => &cfg.name,
26            DeviceConfig::Edu(cfg) => &cfg.name,
27            DeviceConfig::IvshmemPlain(cfg) => &cfg.name,
28        }
29    }
30
31    /// Whether the device should be bound to vfio-pci after boot so it can be
32    /// assigned into the L2 guest.
33    pub fn vfio(&self) -> bool {
34        match self {
35            DeviceConfig::VirtioBlk(cfg) => cfg.vfio,
36            DeviceConfig::Edu(cfg) => cfg.vfio,
37            DeviceConfig::IvshmemPlain(cfg) => cfg.vfio,
38        }
39    }
40
41    /// The capability this device advertises once provisioned, derived from
42    /// its name with `-` replaced by `_` so it is a valid `requires(...)`
43    /// identifier (e.g. `edu-initiator` → `edu_initiator`). Tests gate on this
44    /// via `requires(...)`.
45    pub fn capability(&self) -> String {
46        self.name().replace('-', "_")
47    }
48}
49
50/// Configuration for a virtio-blk device.
51#[derive(Debug, Clone)]
52pub struct VirtioBlkDeviceConfig {
53    /// Name for this device
54    pub name: String,
55    /// Size of the RAM-backed disk in bytes.
56    pub size: u64,
57    /// If true, bind the device to vfio-pci after boot, making it available
58    /// for passthrough into the L2 guest.
59    pub vfio: bool,
60}
61
62/// Configuration for a QEMU `edu` device.
63#[derive(Debug, Clone)]
64pub struct EduDeviceConfig {
65    /// Name for this device.
66    pub name: String,
67    /// Optional `dma_mask` for the edu DMA engine.
68    /// The edu default is 28 bits, which clamps DMA addresses to the low
69    /// 256 MiB — too small for aarch64 guest physical addresses, so P2P tests
70    /// must widen it.
71    pub dma_mask: Option<u64>,
72    /// If true, bind the device to vfio-pci after boot, making it available
73    /// for passthrough into the L2 guest.
74    pub vfio: bool,
75}
76
77/// Configuration for a QEMU `ivshmem-plain`.
78#[derive(Debug, Clone)]
79pub struct IvshmemPlainDeviceConfig {
80    /// Name for this device.
81    pub name: String,
82    /// Size of the RAM-backed shared-memory BAR2 in bytes.
83    pub size: u64,
84    /// If true, bind the device to vfio-pci after boot, making it available
85    /// for passthrough into the L2 guest.
86    pub vfio: bool,
87}