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}