1use guid::Guid;
7use hvlite_pcat_locator::RomFileLocation;
8use input_core::InputData;
9use memory_range::MemoryRange;
10use mesh::MeshPayload;
11use mesh::payload::Protobuf;
12use net_backend_resources::mac_address::MacAddress;
13use std::fmt;
14use std::fs::File;
15use vm_resource::Resource;
16use vm_resource::kind::PciDeviceHandleKind;
17use vm_resource::kind::VirtioDeviceHandle;
18use vm_resource::kind::VmbusDeviceHandleKind;
19use vmgs_resources::VmgsResource;
20use vmotherboard::ChipsetDeviceHandle;
21use vmotherboard::options::BaseChipsetManifest;
22
23#[derive(MeshPayload, Debug)]
24pub struct Config {
25 pub load_mode: LoadMode,
26 pub floppy_disks: Vec<floppy_resources::FloppyDiskConfig>,
27 pub ide_disks: Vec<ide_resources::IdeDeviceConfig>,
28 pub pcie_root_complexes: Vec<PcieRootComplexConfig>,
29 pub pcie_devices: Vec<PcieDeviceConfig>,
30 pub pcie_switches: Vec<PcieSwitchConfig>,
31 pub vpci_devices: Vec<VpciDeviceConfig>,
32 pub memory: MemoryConfig,
33 pub processor_topology: ProcessorTopologyConfig,
34 pub hypervisor: HypervisorConfig,
35 pub chipset: BaseChipsetManifest,
36 pub vmbus: Option<VmbusConfig>,
37 pub vtl2_vmbus: Option<VmbusConfig>,
38 #[cfg(windows)]
39 pub kernel_vmnics: Vec<KernelVmNicConfig>,
40 pub input: mesh::Receiver<InputData>,
41 pub framebuffer: Option<framebuffer::Framebuffer>,
42 pub vga_firmware: Option<RomFileLocation>,
43 pub vtl2_gfx: bool,
44 pub virtio_console_pci: bool,
45 pub virtio_serial: Option<SerialPipes>,
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 pub secure_boot_enabled: bool,
51 pub custom_uefi_vars: firmware_uefi_custom_vars::CustomVars,
52 pub firmware_event_send: Option<mesh::Sender<get_resources::ged::FirmwareEvent>>,
54 pub debugger_rpc: Option<mesh::Receiver<vmm_core_defs::debug_rpc::DebugRequest>>,
55 pub vmbus_devices: Vec<(DeviceVtl, Resource<VmbusDeviceHandleKind>)>,
56 pub chipset_devices: Vec<ChipsetDeviceHandle>,
57 pub generation_id_recv: Option<mesh::Receiver<[u8; 16]>>,
58 pub rtc_delta_milliseconds: i64,
60 pub automatic_guest_reset: bool,
62 pub efi_diagnostics_log_level: EfiDiagnosticsLogLevelType,
63}
64
65const DEFAULT_LOW_MMAP_GAP_SIZE_X86: u64 = 1024 * 1024 * 128;
67const DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64: u64 = 1024 * 1024 * 512;
68
69pub const DEFAULT_MMIO_GAPS_X86: [MemoryRange; 2] = [
71 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_X86..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
74
75pub const DEFAULT_MMIO_GAPS_X86_WITH_VTL2: [MemoryRange; 3] = [
77 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_X86..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x20_0000_0000), MemoryRange::new(0x20_0000_0000..0x20_4000_0000), ];
81
82pub const DEFAULT_MMIO_GAPS_AARCH64: [MemoryRange; 2] = [
84 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x10_0000_0000), ];
87
88pub const DEFAULT_MMIO_GAPS_AARCH64_WITH_VTL2: [MemoryRange; 3] = [
90 MemoryRange::new(0x1_0000_0000 - DEFAULT_LOW_MMAP_GAP_SIZE_AARCH64..0x1_0000_0000), MemoryRange::new(0xF_E000_0000..0x20_0000_0000), MemoryRange::new(0x20_0000_0000..0x20_4000_0000), ];
94
95pub const DEFAULT_GIC_DISTRIBUTOR_BASE: u64 = 0xFFFF_0000;
96pub const DEFAULT_GIC_REDISTRIBUTORS_BASE: u64 = if cfg!(target_os = "linux") {
98 0xEFFF_0000
99} else {
100 0xEFFE_E000
101};
102
103pub const DEFAULT_PCIE_ECAM_BASE: u64 = 0x8_0000_0000; #[derive(MeshPayload, Debug)]
106pub enum LoadMode {
107 Linux {
108 kernel: File,
109 initrd: Option<File>,
110 cmdline: String,
111 enable_serial: bool,
112 custom_dsdt: Option<Vec<u8>>,
113 },
114 Uefi {
115 firmware: File,
116 enable_debugging: bool,
117 enable_memory_protections: bool,
118 disable_frontpage: bool,
119 enable_tpm: bool,
120 enable_battery: bool,
121 enable_serial: bool,
122 enable_vpci_boot: bool,
123 uefi_console_mode: Option<UefiConsoleMode>,
124 default_boot_always_attempt: bool,
125 bios_guid: Guid,
126 },
127 Pcat {
128 firmware: RomFileLocation,
129 boot_order: [PcatBootDevice; 4],
130 },
131 Igvm {
132 file: File,
133 cmdline: String,
134 vtl2_base_address: Vtl2BaseAddressType,
135 com_serial: Option<SerialInformation>,
136 },
137 None,
138}
139
140#[derive(Debug, Clone, Copy, MeshPayload)]
141pub struct SerialInformation {
142 pub io_port: u16,
143 pub irq: u32,
144}
145
146#[derive(Debug, Clone, Copy, MeshPayload)]
149pub enum Vtl2BaseAddressType {
150 File,
153 Absolute(u64),
156 MemoryLayout { size: Option<u64> },
164 Vtl2Allocate { size: Option<u64> },
172}
173
174#[derive(Debug, MeshPayload)]
175pub struct PcieRootComplexConfig {
176 pub index: u32,
177 pub name: String,
178 pub segment: u16,
179 pub start_bus: u8,
180 pub end_bus: u8,
181 pub low_mmio_size: u32,
182 pub high_mmio_size: u64,
183 pub ports: Vec<PcieRootPortConfig>,
184}
185
186#[derive(Debug, MeshPayload)]
187pub struct PcieRootPortConfig {
188 pub name: String,
189 pub hotplug: bool,
190}
191
192#[derive(Debug, MeshPayload)]
193pub struct PcieSwitchConfig {
194 pub name: String,
195 pub num_downstream_ports: u8,
196 pub parent_port: String,
197 pub hotplug: bool,
198}
199
200#[derive(Debug, MeshPayload)]
201pub struct PcieDeviceConfig {
202 pub port_name: String,
203 pub resource: Resource<PciDeviceHandleKind>,
204}
205
206#[derive(Debug, MeshPayload)]
207pub struct VpciDeviceConfig {
208 pub vtl: DeviceVtl,
209 pub instance_id: Guid,
212 pub resource: Resource<PciDeviceHandleKind>,
213}
214
215#[derive(Debug, Protobuf)]
216pub struct ProcessorTopologyConfig {
217 pub proc_count: u32,
218 pub vps_per_socket: Option<u32>,
219 pub enable_smt: Option<bool>,
220 pub arch: Option<ArchTopologyConfig>,
221}
222
223#[derive(Debug, Protobuf, Default, Clone)]
224pub struct X86TopologyConfig {
225 pub apic_id_offset: u32,
226 pub x2apic: X2ApicConfig,
227}
228
229#[derive(Debug, Default, Copy, Clone, Protobuf)]
230pub enum X2ApicConfig {
231 #[default]
232 Auto,
235 Supported,
238 Unsupported,
240 Enabled,
242}
243
244#[derive(Debug, Protobuf, Default, Clone)]
245pub enum PmuGsivConfig {
246 #[default]
247 Platform,
249 Gsiv(u32),
251}
252
253#[derive(Debug, Protobuf, Default, Clone)]
254pub struct Aarch64TopologyConfig {
255 pub gic_config: Option<GicConfig>,
256 pub pmu_gsiv: PmuGsivConfig,
257}
258
259#[derive(Debug, Protobuf, Clone)]
260pub struct GicConfig {
261 pub gic_distributor_base: u64,
262 pub gic_redistributors_base: u64,
263}
264
265#[derive(Debug, Protobuf, Clone)]
266pub enum ArchTopologyConfig {
267 X86(X86TopologyConfig),
268 Aarch64(Aarch64TopologyConfig),
269}
270
271#[derive(Debug, MeshPayload)]
272pub struct MemoryConfig {
273 pub mem_size: u64,
274 pub mmio_gaps: Vec<MemoryRange>,
275 pub prefetch_memory: bool,
276 pub pcie_ecam_base: u64,
277}
278
279#[derive(Debug, MeshPayload, Default)]
280pub struct VmbusConfig {
281 pub vsock_listener: Option<unix_socket::UnixListener>,
282 pub vsock_path: Option<String>,
283 pub vmbus_max_version: Option<u32>,
284 #[cfg(windows)]
285 pub vmbusproxy_handle: Option<vmbus_proxy::ProxyHandle>,
286 pub vtl2_redirect: bool,
287}
288
289#[derive(Debug, MeshPayload, Default)]
290pub struct HypervisorConfig {
291 pub with_hv: bool,
292 pub user_mode_hv_enlightenments: bool,
293 pub user_mode_apic: bool,
294 pub with_vtl2: Option<Vtl2Config>,
295 pub with_isolation: Option<IsolationType>,
296}
297
298#[derive(Debug, Copy, Clone, MeshPayload)]
299pub enum Hypervisor {
300 Kvm,
301 MsHv,
302 Whp,
303 Hvf,
304}
305
306impl fmt::Display for Hypervisor {
307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
308 f.pad(match self {
309 Self::Kvm => "kvm",
310 Self::MsHv => "mshv",
311 Self::Whp => "whp",
312 Self::Hvf => "hvf",
313 })
314 }
315}
316
317#[derive(Debug, MeshPayload)]
319pub struct SerialPipes {
320 pub input: Option<File>,
326 pub output: Option<File>,
334}
335
336impl SerialPipes {
337 pub fn try_clone(&self) -> std::io::Result<Self> {
338 Ok(Self {
339 input: self.input.as_ref().map(File::try_clone).transpose()?,
340 output: self.output.as_ref().map(File::try_clone).transpose()?,
341 })
342 }
343}
344
345#[derive(Debug, MeshPayload)]
346pub struct KernelVmNicConfig {
347 pub instance_id: Guid,
348 pub mac_address: MacAddress,
349 pub switch_port_id: SwitchPortId,
350}
351
352#[derive(Clone, Debug, MeshPayload)]
353pub struct SwitchPortId {
354 pub switch: Guid,
355 pub port: Guid,
356}
357
358pub const DEFAULT_PCAT_BOOT_ORDER: [PcatBootDevice; 4] = [
359 PcatBootDevice::Optical,
360 PcatBootDevice::HardDrive,
361 PcatBootDevice::Network,
362 PcatBootDevice::Floppy,
363];
364
365#[derive(MeshPayload, Debug, Clone, Copy, PartialEq)]
366pub enum PcatBootDevice {
367 Floppy,
368 HardDrive,
369 Optical,
370 Network,
371}
372
373#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
374pub enum VirtioBus {
375 Mmio,
376 Pci,
377}
378
379#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
381pub enum LateMapVtl0MemoryPolicy {
382 Halt,
384 Log,
386 InjectException,
388}
389
390impl From<LateMapVtl0MemoryPolicy> for virt::LateMapVtl0MemoryPolicy {
391 fn from(value: LateMapVtl0MemoryPolicy) -> Self {
392 match value {
393 LateMapVtl0MemoryPolicy::Halt => virt::LateMapVtl0MemoryPolicy::Halt,
394 LateMapVtl0MemoryPolicy::Log => virt::LateMapVtl0MemoryPolicy::Log,
395 LateMapVtl0MemoryPolicy::InjectException => {
396 virt::LateMapVtl0MemoryPolicy::InjectException
397 }
398 }
399 }
400}
401
402#[derive(Debug, Clone, MeshPayload)]
408pub struct Vtl2Config {
409 pub vtl0_alias_map: bool,
412 pub late_map_vtl0_memory: Option<LateMapVtl0MemoryPolicy>,
416}
417
418#[derive(Eq, PartialEq, Debug, Copy, Clone, MeshPayload)]
420pub enum IsolationType {
421 Vbs,
422}
423
424impl From<IsolationType> for virt::IsolationType {
425 fn from(value: IsolationType) -> Self {
426 match value {
427 IsolationType::Vbs => Self::Vbs,
428 }
429 }
430}
431
432#[derive(Copy, Clone, Debug, PartialEq, Eq, MeshPayload)]
434pub enum DeviceVtl {
435 Vtl0,
436 Vtl1,
437 Vtl2,
438}
439
440#[derive(Copy, Clone, Debug, MeshPayload)]
441pub enum UefiConsoleMode {
442 Default,
443 Com1,
444 Com2,
445 None,
446}
447
448#[derive(Copy, Clone, Debug, MeshPayload, Default)]
449pub enum EfiDiagnosticsLogLevelType {
450 #[default]
452 Default,
453 Info,
455 Full,
457}