// Copyright © 2022 Intel Corporation // // SPDX-License-Identifier: Apache-2.0 // use net_util::MacAddr; use serde::{Deserialize, Serialize}; use std::{net::Ipv4Addr, path::PathBuf}; use virtio_devices::RateLimiterConfig; #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct CpuAffinity { pub vcpu: u8, pub host_cpus: Vec, } #[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] pub struct CpuFeatures { #[cfg(target_arch = "x86_64")] #[serde(default)] pub amx: bool, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct CpuTopology { pub threads_per_core: u8, pub cores_per_die: u8, pub dies_per_package: u8, pub packages: u8, } // When booting with PVH boot the maximum physical addressable size // is a 46 bit address space even when the host supports with 5-level // paging. pub const DEFAULT_MAX_PHYS_BITS: u8 = 46; pub fn default_cpuconfig_max_phys_bits() -> u8 { DEFAULT_MAX_PHYS_BITS } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct CpusConfig { pub boot_vcpus: u8, pub max_vcpus: u8, #[serde(default)] pub topology: Option, #[serde(default)] pub kvm_hyperv: bool, #[serde(default = "default_cpuconfig_max_phys_bits")] pub max_phys_bits: u8, #[serde(default)] pub affinity: Option>, #[serde(default)] pub features: CpuFeatures, } pub const DEFAULT_NUM_PCI_SEGMENTS: u16 = 1; pub fn default_platformconfig_num_pci_segments() -> u16 { DEFAULT_NUM_PCI_SEGMENTS } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct PlatformConfig { #[serde(default = "default_platformconfig_num_pci_segments")] pub num_pci_segments: u16, #[serde(default)] pub iommu_segments: Option>, #[serde(default)] pub serial_number: Option, #[serde(default)] pub uuid: Option, #[serde(default)] pub oem_strings: Option>, #[cfg(feature = "tdx")] #[serde(default)] pub tdx: bool, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct MemoryZoneConfig { pub id: String, pub size: u64, #[serde(default)] pub file: Option, #[serde(default)] pub shared: bool, #[serde(default)] pub hugepages: bool, #[serde(default)] pub hugepage_size: Option, #[serde(default)] pub host_numa_node: Option, #[serde(default)] pub hotplug_size: Option, #[serde(default)] pub hotplugged_size: Option, #[serde(default)] pub prefault: bool, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum HotplugMethod { Acpi, VirtioMem, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct MemoryConfig { pub size: u64, #[serde(default)] pub mergeable: bool, #[serde(default)] pub hotplug_method: HotplugMethod, #[serde(default)] pub hotplug_size: Option, #[serde(default)] pub hotplugged_size: Option, #[serde(default)] pub shared: bool, #[serde(default)] pub hugepages: bool, #[serde(default)] pub hugepage_size: Option, #[serde(default)] pub prefault: bool, #[serde(default)] pub zones: Option>, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum VhostMode { Client, Server, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct KernelConfig { pub path: PathBuf, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct InitramfsConfig { pub path: PathBuf, } #[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] pub struct CmdlineConfig { pub args: String, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct DiskConfig { pub path: Option, #[serde(default)] pub readonly: bool, #[serde(default)] pub direct: bool, #[serde(default)] pub iommu: bool, #[serde(default = "default_diskconfig_num_queues")] pub num_queues: usize, #[serde(default = "default_diskconfig_queue_size")] pub queue_size: u16, #[serde(default)] pub vhost_user: bool, pub vhost_socket: Option, #[serde(default)] pub rate_limiter_config: Option, #[serde(default)] pub id: Option, // For testing use only. Not exposed in API. #[serde(default)] pub disable_io_uring: bool, #[serde(default)] pub pci_segment: u16, } pub const DEFAULT_NUM_QUEUES_VUBLK: usize = 1; pub fn default_diskconfig_num_queues() -> usize { DEFAULT_NUM_QUEUES_VUBLK } pub const DEFAULT_QUEUE_SIZE_VUBLK: u16 = 128; pub fn default_diskconfig_queue_size() -> u16 { DEFAULT_QUEUE_SIZE_VUBLK } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct NetConfig { #[serde(default = "default_netconfig_tap")] pub tap: Option, #[serde(default = "default_netconfig_ip")] pub ip: Ipv4Addr, #[serde(default = "default_netconfig_mask")] pub mask: Ipv4Addr, #[serde(default = "default_netconfig_mac")] pub mac: MacAddr, #[serde(default)] pub host_mac: Option, #[serde(default)] pub mtu: Option, #[serde(default)] pub iommu: bool, #[serde(default = "default_netconfig_num_queues")] pub num_queues: usize, #[serde(default = "default_netconfig_queue_size")] pub queue_size: u16, #[serde(default)] pub vhost_user: bool, pub vhost_socket: Option, #[serde(default)] pub vhost_mode: VhostMode, #[serde(default)] pub id: Option, #[serde(default)] pub fds: Option>, #[serde(default)] pub rate_limiter_config: Option, #[serde(default)] pub pci_segment: u16, } pub fn default_netconfig_tap() -> Option { None } pub fn default_netconfig_ip() -> Ipv4Addr { Ipv4Addr::new(192, 168, 249, 1) } pub fn default_netconfig_mask() -> Ipv4Addr { Ipv4Addr::new(255, 255, 255, 0) } pub fn default_netconfig_mac() -> MacAddr { MacAddr::local_random() } pub const DEFAULT_NUM_QUEUES_VUNET: usize = 2; pub fn default_netconfig_num_queues() -> usize { DEFAULT_NUM_QUEUES_VUNET } pub const DEFAULT_QUEUE_SIZE_VUNET: u16 = 256; pub fn default_netconfig_queue_size() -> u16 { DEFAULT_QUEUE_SIZE_VUNET } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct RngConfig { pub src: PathBuf, #[serde(default)] pub iommu: bool, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct BalloonConfig { pub size: u64, /// Option to deflate the balloon in case the guest is out of memory. #[serde(default)] pub deflate_on_oom: bool, /// Option to enable free page reporting from the guest. #[serde(default)] pub free_page_reporting: bool, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct FsConfig { pub tag: String, pub socket: PathBuf, #[serde(default = "default_fsconfig_num_queues")] pub num_queues: usize, #[serde(default = "default_fsconfig_queue_size")] pub queue_size: u16, #[serde(default)] pub id: Option, #[serde(default)] pub pci_segment: u16, } pub fn default_fsconfig_num_queues() -> usize { 1 } pub fn default_fsconfig_queue_size() -> u16 { 1024 } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct PmemConfig { pub file: PathBuf, #[serde(default)] pub size: Option, #[serde(default)] pub iommu: bool, #[serde(default)] pub discard_writes: bool, #[serde(default)] pub id: Option, #[serde(default)] pub pci_segment: u16, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum ConsoleOutputMode { Off, Pty, Tty, File, Null, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct ConsoleConfig { #[serde(default = "default_consoleconfig_file")] pub file: Option, pub mode: ConsoleOutputMode, #[serde(default)] pub iommu: bool, } pub fn default_consoleconfig_file() -> Option { None } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct DeviceConfig { pub path: PathBuf, #[serde(default)] pub iommu: bool, #[serde(default)] pub id: Option, #[serde(default)] pub pci_segment: u16, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct UserDeviceConfig { pub socket: PathBuf, #[serde(default)] pub id: Option, #[serde(default)] pub pci_segment: u16, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct VdpaConfig { pub path: PathBuf, #[serde(default = "default_vdpaconfig_num_queues")] pub num_queues: usize, #[serde(default)] pub iommu: bool, #[serde(default)] pub id: Option, #[serde(default)] pub pci_segment: u16, } pub fn default_vdpaconfig_num_queues() -> usize { 1 } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct VsockConfig { pub cid: u64, pub socket: PathBuf, #[serde(default)] pub iommu: bool, #[serde(default)] pub id: Option, #[serde(default)] pub pci_segment: u16, } #[cfg(target_arch = "x86_64")] #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct SgxEpcConfig { pub id: String, #[serde(default)] pub size: u64, #[serde(default)] pub prefault: bool, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct NumaDistance { #[serde(default)] pub destination: u32, #[serde(default)] pub distance: u8, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct NumaConfig { #[serde(default)] pub guest_numa_id: u32, #[serde(default)] pub cpus: Option>, #[serde(default)] pub distances: Option>, #[serde(default)] pub memory_zones: Option>, #[cfg(target_arch = "x86_64")] #[serde(default)] pub sgx_epc_sections: Option>, } #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct PayloadConfig { #[serde(default)] pub firmware: Option, #[serde(default)] pub kernel: Option, #[serde(default)] pub cmdline: Option, #[serde(default)] pub initramfs: Option, } #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct VmConfig { #[serde(default)] pub cpus: CpusConfig, #[serde(default)] pub memory: MemoryConfig, pub kernel: Option, #[serde(default)] pub initramfs: Option, #[serde(default)] pub cmdline: CmdlineConfig, #[serde(default)] pub payload: Option, pub disks: Option>, pub net: Option>, #[serde(default)] pub rng: RngConfig, pub balloon: Option, pub fs: Option>, pub pmem: Option>, #[serde(default = "ConsoleConfig::default_serial")] pub serial: ConsoleConfig, #[serde(default = "ConsoleConfig::default_console")] pub console: ConsoleConfig, pub devices: Option>, pub user_devices: Option>, pub vdpa: Option>, pub vsock: Option, #[serde(default)] pub iommu: bool, #[cfg(target_arch = "x86_64")] pub sgx_epc: Option>, pub numa: Option>, #[serde(default)] pub watchdog: bool, #[cfg(feature = "guest_debug")] pub gdb: bool, pub platform: Option, }