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