Skip to main content

openvmm_defs/
config.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Configuration for the VM worker.
5
6use guid::Guid;
7use input_core::InputData;
8use memory_range::MemoryRange;
9use mesh::MeshPayload;
10use mesh::payload::Protobuf;
11use net_backend_resources::mac_address::MacAddress;
12use openvmm_pcat_locator::RomFileLocation;
13use std::fs::File;
14use vm_resource::Resource;
15use vm_resource::kind::PciDeviceHandleKind;
16use vm_resource::kind::VirtioDeviceHandle;
17use vm_resource::kind::VmbusDeviceHandleKind;
18use vmgs_resources::VmgsResource;
19use vmotherboard::ChipsetDeviceHandle;
20use vmotherboard::LegacyPciChipsetDeviceHandle;
21use vmotherboard::options::BaseChipsetManifest;
22use vmotherboard::options::VmChipsetCapabilities;
23
24#[derive(MeshPayload, Debug)]
25pub struct Config {
26    pub load_mode: LoadMode,
27    pub floppy_disks: Vec<floppy_resources::FloppyDiskConfig>,
28    pub ide_disks: Vec<ide_resources::IdeDeviceConfig>,
29    pub pcie_root_complexes: Vec<PcieRootComplexConfig>,
30    pub pcie_devices: Vec<PcieDeviceConfig>,
31    pub pcie_switches: Vec<PcieSwitchConfig>,
32    pub pcie_generic_initiators: Vec<PcieGenericInitiatorConfig>,
33    pub vpci_devices: Vec<VpciDeviceConfig>,
34    pub numa: NumaTopology,
35    pub processor_topology: ProcessorTopologyConfig,
36    pub hypervisor: HypervisorConfig,
37    pub chipset: BaseChipsetManifest,
38    pub vmbus: Option<VmbusConfig>,
39    pub vtl2_vmbus: Option<VmbusConfig>,
40    #[cfg(windows)]
41    pub kernel_vmnics: Vec<KernelVmNicConfig>,
42    pub input: mesh::Receiver<InputData>,
43    pub framebuffer: Option<framebuffer::Framebuffer>,
44    pub vga_firmware: Option<RomFileLocation>,
45    pub vtl2_gfx: bool,
46    pub virtio_devices: Vec<(VirtioBus, Resource<VirtioDeviceHandle>)>,
47    #[cfg(windows)]
48    pub vpci_resources: Vec<virt_whp::device::DeviceHandle>,
49    pub vmgs: Option<VmgsResource>,
50    // TODO: move FirmwareEvent somewhere not GED-specific.
51    pub firmware_event_send: Option<mesh::Sender<get_resources::ged::FirmwareEvent>>,
52    pub debugger_rpc: Option<mesh::Receiver<vmm_core_defs::debug_rpc::DebugRequest>>,
53    pub vmbus_devices: Vec<(DeviceVtl, Resource<VmbusDeviceHandleKind>)>,
54    pub chipset_devices: Vec<ChipsetDeviceHandle>,
55    pub pci_chipset_devices: Vec<LegacyPciChipsetDeviceHandle>,
56    pub isa_dma_controller: Option<Resource<vm_resource::kind::IsaDmaControllerHandleKind>>,
57    pub chipset_capabilities: VmChipsetCapabilities,
58    /// Memory layout sizing for the layout engine. Determines chipset MMIO
59    /// range sizes; addresses are allocated dynamically by the resolver.
60    pub layout: vmm_core_defs::LayoutConfig,
61    // This is used for testing. TODO: resourcify, and also store this in VMGS.
62    pub rtc_delta_milliseconds: i64,
63}
64
65pub const DEFAULT_GIC_DISTRIBUTOR_BASE: u64 = 0xFFFF_0000;
66// The KVM in-kernel vGICv3 requires the distributor and redistributor bases be 64KiB aligned.
67pub const DEFAULT_GIC_REDISTRIBUTORS_BASE: u64 = if cfg!(target_os = "linux") {
68    0xEFFF_0000
69} else {
70    0xEFFE_E000
71};
72
73/// Base address of the guest-visible GIC v2m MSI frame (exposed via the MADT
74/// and used by the software v2m SETSPI decoder for emulated devices). This is
75/// OpenVMM-emulated MMIO (one 4 KiB page), not shadowed by the hypervisor, so
76/// it stays at the conventional address.
77pub const DEFAULT_GIC_V2M_MSI_FRAME_BASE: u64 = 0xEFFE_8000;
78/// Size of the v2m MSI frame (one 4KB page is the architectural minimum).
79pub const GIC_V2M_MSI_FRAME_SIZE: u64 = 0x1000;
80
81/// Base address of the GIC v2m MSI doorbell used for passthrough on the
82/// MSHV root/arm64 backend. Registered with the hypervisor as
83/// GITS_TRANSLATER_BASE_ADDRESS.
84/// The hypervisor shadows a ~64 KiB region at this base,
85/// so it uses the Hyper-V convention address 0xEFF6_8000.
86pub const DEFAULT_GIC_V2M_DOORBELL_BASE: u64 = 0xEFF6_8000;
87
88/// Base address of the GICv3 ITS MMIO region. Must be 64 KiB aligned,
89/// below the v2m frame address, and not overlap other devices.
90/// The region extends from this base to base + GIC_ITS_SIZE (128 KiB).
91pub const DEFAULT_GIC_ITS_BASE: u64 = 0xEFFC_0000;
92/// Size of the ITS MMIO region (control frame + translation frame, 2×64 KiB).
93pub const GIC_ITS_SIZE: u64 = 0x2_0000;
94
95/// Default virtual timer PPI (GIC INTID). PPI 4 = INTID 16 + 4 = 20.
96/// This is the EL1 virtual timer interrupt used across Hyper-V, KVM, and HVF.
97pub const DEFAULT_VIRT_TIMER_PPI: u32 = 20;
98
99/// Default total number of GIC interrupts (SGIs + PPIs + SPIs).
100/// Must satisfy KVM constraints: 64 <= n <= 1023, multiple of 32.
101/// 992 = 31 × 32 is the largest valid value.
102pub const DEFAULT_GIC_NR_IRQS: u32 = 992;
103
104/// Default VMBus PPI (GIC INTID). PPI 2 = INTID 16 + 2 = 18.
105pub const DEFAULT_VMBUS_PPI: u32 = 18;
106
107/// How firmware tables are presented to the guest in Linux direct boot.
108///
109/// On x86, `DeviceTree` is not supported and will be rejected. On aarch64,
110/// this selects between a full device tree or an ACPI boot path.
111#[derive(MeshPayload, Debug, Clone, Copy, PartialEq, Eq)]
112pub enum LinuxDirectBootMode {
113    /// Full device tree with all devices described in DT nodes (aarch64 only).
114    DeviceTree,
115    /// ACPI tables for device discovery. On aarch64, this also synthesizes
116    /// an EFI system table so the kernel enters its ACPI code path. On x86,
117    /// ACPI tables are always provided via the zero page.
118    Acpi,
119}
120
121#[derive(MeshPayload, Debug)]
122pub enum LoadMode {
123    Linux {
124        kernel: File,
125        initrd: Option<File>,
126        cmdline: String,
127        enable_serial: bool,
128        boot_mode: LinuxDirectBootMode,
129    },
130    Uefi {
131        firmware: File,
132        enable_debugging: bool,
133        enable_memory_protections: bool,
134        disable_frontpage: bool,
135        enable_tpm: bool,
136        enable_battery: bool,
137        enable_serial: bool,
138        enable_vpci_boot: bool,
139        uefi_console_mode: Option<UefiConsoleMode>,
140        default_boot_always_attempt: bool,
141        bios_guid: Guid,
142        enable_vmbus: bool,
143        force_dma_bounce: bool,
144        enable_hv: bool,
145    },
146    Pcat {
147        firmware: RomFileLocation,
148        boot_order: [PcatBootDevice; 4],
149    },
150    Igvm {
151        file: File,
152        cmdline: String,
153        vtl2_base_address: Vtl2BaseAddressType,
154        com_serial: Option<SerialInformation>,
155    },
156    None,
157}
158
159#[derive(Debug, Clone, Copy, MeshPayload)]
160pub struct SerialInformation {
161    pub io_port: u16,
162    pub irq: u32,
163}
164
165/// Different types to specify the base address for the VTL2 region of the IGVM
166/// file.
167#[derive(Debug, Clone, Copy, MeshPayload)]
168pub enum Vtl2BaseAddressType {
169    /// Use the addresses specified in the file. The IGVM file does not need to
170    /// support relocations.
171    File,
172    /// Put VTL2 at the specified address. The IGVM file must support
173    /// relocations.
174    Absolute(u64),
175    /// Use the specified range in the supplied MemoryLayout, as the caller has
176    /// created a specific range for VTL2. The IGVM file must support
177    /// relocations.
178    ///
179    /// An optional size may be specified to override the size describing VTL2
180    /// provided in the IGVM file. It must be larger than the IGVM file provided
181    /// size.
182    MemoryLayout { size: Option<u64> },
183    /// Tell VTL2 to allocate out it's own memory. This will load the file at
184    /// the base address specified in the file, and the host will tell VTL2 the
185    /// size of memory to allocate for itself.
186    ///
187    /// An optional size may be specified to override the size describing VTL2
188    /// provided in the IGVM file. It must be larger than the IGVM file provided
189    /// size.
190    Vtl2Allocate { size: Option<u64> },
191}
192
193/// Specifies a PCIe MMIO BAR window, either by size (the resolver allocates) or
194/// by a fixed location. Fixed locations exist for assigned-device, IOMMU, and
195/// physical-topology compatibility.
196#[derive(Debug, MeshPayload)]
197pub enum PcieMmioRangeConfig {
198    /// Dynamically allocate a range of the given size.
199    Dynamic {
200        /// Size of the range in bytes.
201        size: u64,
202    },
203    /// Use the specified fixed memory range.
204    Fixed(MemoryRange),
205}
206
207#[derive(Debug, MeshPayload)]
208pub struct RootComplexCxlConfig {
209    /// HDM window size in bytes for this CXL root complex.
210    pub hdm_size: u64,
211    /// CFMWS HDM window restrictions bitmask.
212    pub hdm_window_restrictions: u16,
213}
214
215#[derive(Debug, MeshPayload)]
216pub struct PcieRootComplexConfig {
217    pub index: u32,
218    pub name: String,
219    pub segment: u16,
220    pub start_bus: u8,
221    pub end_bus: u8,
222    pub low_mmio: PcieMmioRangeConfig,
223    pub high_mmio: PcieMmioRangeConfig,
224    pub ports: Vec<PciePortConfig>,
225    /// Optional CXL configuration for root-complex CXL mode.
226    pub cxl: Option<RootComplexCxlConfig>,
227    /// Optional IOMMU for this root complex.
228    pub iommu: Option<PcieIommuConfig>,
229    /// NUMA node affinity for this root complex. Used to generate `_PXM` in
230    /// the ACPI SSDT so the guest OS sees correct NUMA locality for devices
231    /// under this root complex.
232    pub vnode: Option<u32>,
233    /// When true, treat non-zero BAR values found during probing as pinned
234    /// addresses. Used for P2P DMA with GPA = HPA.
235    pub preserve_bars: bool,
236}
237
238/// Configuration for a single PCIe port — either a root-complex root port or a
239/// switch downstream port.
240#[derive(Debug, MeshPayload)]
241pub struct PciePortConfig {
242    /// Port name used for topology wiring and lookup.
243    pub name: String,
244    /// The device/function (`device << 3 | function`) to place this port at on
245    /// its bus.
246    ///
247    /// When `None`, the port is assigned the lowest available devfn. Ports are
248    /// assigned in order, so an explicit devfn that collides with a
249    /// previously-assigned port (including one assigned automatically) is an
250    /// error. Honored for both root-complex root ports and switch downstream
251    /// ports.
252    pub devfn: Option<u8>,
253    /// Enables PCIe hotplug capabilities for this port.
254    pub hotplug: bool,
255    /// Optional ACS capability bitmask to expose on this port.
256    pub acs_capabilities_supported: Option<u16>,
257    /// Marks this port as CXL-capable.
258    ///
259    /// Runtime port construction derives required BAR/subregion layout from
260    /// this flag (currently CXL component registers for BAR0).
261    pub cxl: bool,
262    /// Enables PASID support for functions downstream of this port.
263    pub pasid: bool,
264}
265
266#[derive(Debug, MeshPayload)]
267pub struct PcieSwitchConfig {
268    pub name: String,
269    pub parent_port: String,
270    /// The downstream ports of this switch.
271    pub ports: Vec<PciePortConfig>,
272}
273
274/// Declares that the device directly behind a named PCIe port (a root port or
275/// a switch downstream port) is a generic initiator (GI) for the given NUMA
276/// node. Used to generate an SRAT Generic Initiator Affinity structure so the
277/// guest attaches the device's memory to that (typically CPU-less) proximity
278/// domain.
279///
280/// The port is resolved against the live topology by port name after switch
281/// downstream ports have been enumerated, so it can target devices that sit
282/// behind a switch.
283#[derive(Debug, MeshPayload)]
284pub struct PcieGenericInitiatorConfig {
285    /// Name of the PCIe port (root port or switch downstream port) behind
286    /// which the generic-initiator device resides.
287    pub port_name: String,
288    /// NUMA node the device is a generic initiator for.
289    pub node: u32,
290}
291
292#[derive(Debug, MeshPayload)]
293pub struct PcieDeviceConfig {
294    pub port_name: String,
295    pub resource: Resource<PciDeviceHandleKind>,
296}
297
298#[derive(Debug, MeshPayload)]
299pub struct VpciDeviceConfig {
300    pub vtl: DeviceVtl,
301    /// The ID of the device. Vpci devices are identified by a portion of `data2` and `data3` of the
302    /// instance ID, which is used to generate the guest-visible device ID.
303    pub instance_id: Guid,
304    pub resource: Resource<PciDeviceHandleKind>,
305    /// NUMA node affinity for this VPCI device.
306    pub vnode: Option<u32>,
307}
308
309#[derive(Debug, Protobuf)]
310pub struct ProcessorTopologyConfig {
311    pub proc_count: u32,
312    pub vps_per_socket: Option<u32>,
313    pub enable_smt: Option<bool>,
314    pub arch: Option<ArchTopologyConfig>,
315}
316
317#[derive(Debug, Protobuf, Default, Clone)]
318pub struct X86TopologyConfig {
319    pub apic_id_offset: u32,
320    pub x2apic: X2ApicConfig,
321}
322
323#[derive(Debug, Default, Copy, Clone, Protobuf)]
324pub enum X2ApicConfig {
325    #[default]
326    /// Support the X2APIC if recommended by the hypervisor or if needed by the
327    /// topology configuration.
328    Auto,
329    /// Support the X2APIC, and automatically enable it if needed to address all
330    /// processors.
331    Supported,
332    /// Do not support the X2APIC.
333    Unsupported,
334    /// Support and enable the X2APIC.
335    Enabled,
336}
337
338#[derive(Debug, Protobuf, Default, Clone)]
339pub enum PmuGsivConfig {
340    #[default]
341    /// Use the hypervisor's platform GSIV value for the PMU.
342    Platform,
343    /// Use the specified GSIV value for the PMU.
344    Gsiv(u32),
345    /// Disable the PMU.
346    Disabled,
347}
348
349/// MSI controller selection for aarch64 PCIe interrupt delivery.
350#[derive(Debug, Protobuf, Default, Clone)]
351pub enum GicMsiConfig {
352    /// Automatically select the best available MSI controller:
353    /// ITS when the hypervisor supports it, otherwise GICv2m.
354    #[default]
355    Auto,
356    /// Force GICv3 ITS for MSI delivery via LPIs.
357    Its,
358    /// Force GICv2m for MSI delivery via SPIs.
359    V2m {
360        /// Number of SPIs to reserve for PCIe MSIs. Defaults to a
361        /// platform-specific value when `None`.
362        spi_count: Option<u32>,
363    },
364}
365
366/// IOMMU configuration for a single PCIe root complex.
367#[derive(Debug, MeshPayload, Clone)]
368pub enum PcieIommuConfig {
369    /// AMD IOMMU (AMD-Vi) for x86_64 guests.
370    AmdVi,
371    /// Arm SMMUv3 for aarch64 guests.
372    Smmu {
373        /// Enable HW-accelerated nested translation (iommufd). Requires VFIO
374        /// devices with `iommu=` behind this SMMU.
375        accel: bool,
376        /// Output address size (OAS) resolution policy.
377        oas: SmmuOas,
378    },
379    /// Intel VT-d for x86_64 guests.
380    IntelVtd,
381}
382
383/// Output address size (OAS) policy for an emulated SMMUv3.
384#[derive(Debug, MeshPayload, Clone, Copy)]
385pub enum SmmuOas {
386    /// Advertise a fixed default OAS. See `DEFAULT_AUTO_OAS_BITS` for the
387    /// sizing policy and its limits.
388    Auto,
389    /// Use a fixed OAS in bits (one of 32, 36, 40, 42, 44, 48, 52).
390    Fixed(u8),
391}
392
393#[derive(Debug, Protobuf, Default, Clone)]
394pub struct Aarch64TopologyConfig {
395    pub gic_config: Option<GicConfig>,
396    pub pmu_gsiv: PmuGsivConfig,
397    pub gic_msi: GicMsiConfig,
398}
399
400/// GIC configuration for the virtual machine.
401///
402/// The variant selects the GIC version. `None` inner config means use
403/// defaults for that version's addresses.
404#[derive(Debug, Protobuf, Clone)]
405pub enum GicConfig {
406    /// GICv2 with optional address overrides.
407    V2(Option<GicV2Config>),
408    /// GICv3 with optional address overrides.
409    V3(Option<GicV3Config>),
410}
411
412/// GICv2-specific address configuration.
413#[derive(Debug, Protobuf, Clone)]
414pub struct GicV2Config {
415    pub gic_distributor_base: u64,
416    pub cpu_interface_base: u64,
417}
418
419/// GICv3-specific address configuration.
420#[derive(Debug, Protobuf, Clone)]
421pub struct GicV3Config {
422    pub gic_distributor_base: u64,
423    pub gic_redistributors_base: u64,
424}
425
426#[derive(Debug, Protobuf, Clone)]
427pub enum ArchTopologyConfig {
428    X86(X86TopologyConfig),
429    Aarch64(Aarch64TopologyConfig),
430}
431
432/// Per-node memory allocation configuration.
433#[derive(Debug, Clone, Copy, MeshPayload)]
434pub struct MemoryConfig {
435    pub mem_size: u64,
436    pub prefetch_memory: bool,
437    pub private_memory: bool,
438    pub transparent_hugepages: bool,
439    pub hugepages: bool,
440    pub hugepage_size: Option<u64>,
441    /// Host physical NUMA node to bind this allocation to (Linux:
442    /// `mbind(MPOL_BIND)`). `None` means OS default placement.
443    pub host_numa_node: Option<u32>,
444}
445
446/// Virtual NUMA topology for the VM.
447#[derive(Debug, MeshPayload)]
448pub struct NumaTopology {
449    /// NUMA nodes. The vnode ID is the index into this vector.
450    pub nodes: Vec<NumaNode>,
451    /// Inter-node distances for the SLIT. If empty, defaults are used
452    /// (10 for self, 20 for cross-node).
453    pub distances: Vec<NumaDistance>,
454}
455
456/// A single virtual NUMA node.
457#[derive(Debug, MeshPayload)]
458pub struct NumaNode {
459    /// Memory allocation for this node. `None` means a CPU-only or
460    /// device-only node.
461    pub mem: Option<MemoryConfig>,
462    /// VP assignment for this node.
463    pub vps: VpAssignment,
464}
465
466/// How VPs are assigned to a NUMA node.
467#[derive(Debug, MeshPayload)]
468pub enum VpAssignment {
469    /// Assign VPs to nodes by round-robining sockets over the CPU-bearing
470    /// nodes only: a VP with socket ID `vp_index / vps_per_socket` belongs to
471    /// the `(vp_index / vps_per_socket) % num_cpu_nodes`-th `FromTopology`
472    /// node. `vps_per_socket` comes from `ProcessorTopologyConfig`;
473    /// `num_cpu_nodes` is the number of `FromTopology` nodes, so `Empty`
474    /// (CPU-less) nodes are skipped and do not affect the distribution.
475    FromTopology,
476    /// Explicit VP indices assigned to this node.
477    Explicit(Vec<u32>),
478    /// A CPU-less node: no VPs are assigned to it. Unlike `Explicit`, this
479    /// may be combined with `FromTopology` nodes, so a memory- or
480    /// device-only node can be declared without forcing every other node to
481    /// spell out its VP set.
482    Empty,
483}
484
485/// An inter-node distance entry for the ACPI SLIT.
486#[derive(Debug, MeshPayload)]
487pub struct NumaDistance {
488    /// Source node index.
489    pub src: u32,
490    /// Destination node index.
491    pub dst: u32,
492    /// Distance value (10 = local, 20 = default cross-node, 255 = unreachable).
493    pub distance: u8,
494}
495
496#[derive(Debug, MeshPayload, Default)]
497pub struct VmbusConfig {
498    pub vsock_listener: Option<unix_socket::UnixListener>,
499    pub vsock_path: Option<String>,
500    pub vmbus_max_version: Option<u32>,
501    #[cfg(windows)]
502    pub vmbusproxy_handle: Option<vmbus_proxy::ProxyHandle>,
503    pub vtl2_redirect: bool,
504}
505
506#[derive(Debug, MeshPayload, Default)]
507pub struct HypervisorConfig {
508    pub with_hv: bool,
509    pub with_vtl2: Option<Vtl2Config>,
510    pub with_isolation: Option<IsolationType>,
511    /// Expose hardware virtualization (VMX/SVM) to the guest so that it can run
512    /// its own hypervisor. A backend that does not recognize this request
513    /// rejects it rather than silently ignoring it (see
514    /// `virt::Hypervisor::recognizes_nested_virt`).
515    pub nested_virt: bool,
516}
517
518#[derive(Debug, MeshPayload)]
519pub struct KernelVmNicConfig {
520    pub instance_id: Guid,
521    pub mac_address: MacAddress,
522    pub switch_port_id: SwitchPortId,
523}
524
525#[derive(Clone, Debug, MeshPayload)]
526pub struct SwitchPortId {
527    pub switch: Guid,
528    pub port: Guid,
529}
530
531pub const DEFAULT_PCAT_BOOT_ORDER: [PcatBootDevice; 4] = [
532    PcatBootDevice::Optical,
533    PcatBootDevice::HardDrive,
534    PcatBootDevice::Network,
535    PcatBootDevice::Floppy,
536];
537
538#[derive(MeshPayload, Debug, Clone, Copy, PartialEq)]
539pub enum PcatBootDevice {
540    Floppy,
541    HardDrive,
542    Optical,
543    Network,
544}
545
546#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
547pub enum VirtioBus {
548    Mmio,
549    Pci,
550}
551
552/// Policy for the partition when mapping VTL0 memory late.
553#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
554pub enum LateMapVtl0MemoryPolicy {
555    /// Halt execution of the VP if VTL0 memory is accessed.
556    Halt,
557    /// Log the error but emulate the access with the instruction emulator.
558    Log,
559    /// Inject an exception into the guest.
560    InjectException,
561}
562
563impl From<LateMapVtl0MemoryPolicy> for virt::LateMapVtl0MemoryPolicy {
564    fn from(value: LateMapVtl0MemoryPolicy) -> Self {
565        match value {
566            LateMapVtl0MemoryPolicy::Halt => virt::LateMapVtl0MemoryPolicy::Halt,
567            LateMapVtl0MemoryPolicy::Log => virt::LateMapVtl0MemoryPolicy::Log,
568            LateMapVtl0MemoryPolicy::InjectException => {
569                virt::LateMapVtl0MemoryPolicy::InjectException
570            }
571        }
572    }
573}
574
575/// Configuration for VTL2.
576///
577/// NOTE: This is distinct from `virt::Vtl2Config` to keep an abstraction
578/// between the virt crate and this crate. Users should not be specifying
579/// virt crate configuration directly.
580#[derive(Debug, Clone, MeshPayload)]
581pub struct Vtl2Config {
582    /// Enable the VTL0 alias map. This maps VTL0's view of memory in VTL2 at
583    /// the highest legal physical address bit.
584    pub vtl0_alias_map: bool,
585    /// If set, map VTL0 memory late after VTL2 has started. The current
586    /// heuristic is to defer mapping VTL0 memory until the first
587    /// `HvModifyVtlProtectionMask` hypercall is made.
588    pub late_map_vtl0_memory: Option<LateMapVtl0MemoryPolicy>,
589}
590
591// Isolation type for a partition.
592#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
593pub enum IsolationType {
594    Vbs,
595    Snp,
596    Cca,
597}
598
599impl From<IsolationType> for virt::IsolationType {
600    fn from(value: IsolationType) -> Self {
601        match value {
602            IsolationType::Vbs => Self::Vbs,
603            IsolationType::Snp => Self::Snp,
604            IsolationType::Cca => Self::Cca,
605        }
606    }
607}
608
609/// Which VTL to assign a particular device to.
610#[derive(Copy, Clone, Debug, PartialEq, Eq, MeshPayload)]
611pub enum DeviceVtl {
612    Vtl0,
613    Vtl1,
614    Vtl2,
615}
616
617#[derive(Copy, Clone, Debug, MeshPayload)]
618pub enum UefiConsoleMode {
619    Default,
620    Com1,
621    Com2,
622    None,
623}