// Copyright 2022 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34cfg_if::cfg_if! {5if #[cfg(any(target_os = "android", target_os = "linux"))] {6use base::RawDescriptor;7use devices::virtio::vhost_user_backend::parse_wayland_sock;89use crate::crosvm::sys::config::parse_pmem_ext2_option;10use crate::crosvm::sys::config::VfioOption;11use crate::crosvm::sys::config::SharedDir;12use crate::crosvm::sys::config::PmemExt2Option;13}14}1516use std::collections::BTreeMap;17use std::path::PathBuf;18use std::str::FromStr;19use std::sync::atomic::AtomicUsize;20use std::sync::atomic::Ordering;2122use arch::CpuSet;23#[cfg(all(target_os = "android", target_arch = "aarch64"))]24use arch::DevicePowerManagerConfig;25use arch::FdtPosition;26#[cfg(all(target_os = "android", target_arch = "aarch64"))]27use arch::FfaConfig;28#[cfg(target_arch = "x86_64")]29use arch::MemoryRegionConfig;30use arch::PciConfig;31use arch::Pstore;32#[cfg(target_arch = "x86_64")]33use arch::SmbiosOptions;34use arch::VcpuAffinity;35use argh::FromArgs;36use base::getpid;37use cros_async::ExecutorKind;38use devices::virtio::block::DiskOption;39#[cfg(any(feature = "video-decoder", feature = "video-encoder"))]40use devices::virtio::device_constants::video::VideoDeviceConfig;41use devices::virtio::scsi::ScsiOption;42#[cfg(feature = "audio")]43use devices::virtio::snd::parameters::Parameters as SndParameters;44use devices::virtio::vhost_user_backend;45use devices::virtio::vsock::VsockConfig;46#[cfg(feature = "gpu")]47use devices::virtio::GpuDisplayParameters;48#[cfg(feature = "gpu")]49use devices::virtio::GpuMouseMode;50#[cfg(feature = "gpu")]51use devices::virtio::GpuParameters;52#[cfg(all(unix, feature = "net"))]53use devices::virtio::NetParameters;54#[cfg(all(unix, feature = "net"))]55use devices::virtio::NetParametersMode;56use devices::FwCfgParameters;57use devices::PflashParameters;58use devices::SerialHardware;59use devices::SerialParameters;60use devices::StubPciParameters;61#[cfg(target_arch = "x86_64")]62use hypervisor::CpuHybridType;63use hypervisor::ProtectionType;64use resources::AddressRange;65#[cfg(feature = "gpu")]66use serde::Deserialize;67#[cfg(feature = "gpu")]68use serde_keyvalue::FromKeyValues;69use vm_memory::FileBackedMappingParameters;7071use super::config::PmemOption;72#[cfg(feature = "gpu")]73use super::gpu_config::fixup_gpu_options;74#[cfg(all(unix, feature = "gpu"))]75use super::sys::GpuRenderServerParameters;76use crate::crosvm::config::from_key_values;77use crate::crosvm::config::parse_bus_id_addr;78use crate::crosvm::config::parse_cpu_affinity;79use crate::crosvm::config::parse_cpu_btreemap_u32;80#[cfg(all(81target_arch = "aarch64",82any(target_os = "android", target_os = "linux")83))]84use crate::crosvm::config::parse_cpu_frequencies;85use crate::crosvm::config::parse_mmio_address_range;86use crate::crosvm::config::parse_pflash_parameters;87use crate::crosvm::config::parse_serial_options;88use crate::crosvm::config::parse_touch_device_option;89use crate::crosvm::config::BatteryConfig;90use crate::crosvm::config::CpuOptions;91use crate::crosvm::config::DtboOption;92use crate::crosvm::config::Executable;93use crate::crosvm::config::HypervisorKind;94use crate::crosvm::config::InputDeviceOption;95use crate::crosvm::config::IrqChipKind;96use crate::crosvm::config::MemOptions;97use crate::crosvm::config::TouchDeviceOption;98use crate::crosvm::config::VhostUserFrontendOption;99100#[derive(FromArgs)]101/// crosvm102pub struct CrosvmCmdlineArgs {103#[argh(switch)]104/// use extended exit status105pub extended_status: bool,106#[argh(option, default = r#"String::from("info")"#)]107/// specify log level, eg "off", "error", "debug,disk=off", etc108pub log_level: String,109#[argh(option, arg_name = "TAG")]110/// when logging to syslog, use the provided tag111pub syslog_tag: Option<String>,112#[argh(switch)]113/// disable output to syslog114pub no_syslog: bool,115#[argh(subcommand)]116pub command: Command,117}118119#[allow(clippy::large_enum_variant)]120#[derive(FromArgs)]121#[argh(subcommand)]122pub enum CrossPlatformCommands {123#[cfg(feature = "balloon")]124Balloon(BalloonCommand),125#[cfg(feature = "balloon")]126BalloonStats(BalloonStatsCommand),127#[cfg(feature = "balloon")]128BalloonWs(BalloonWsCommand),129Battery(BatteryCommand),130#[cfg(feature = "composite-disk")]131CreateComposite(CreateCompositeCommand),132#[cfg(feature = "qcow")]133CreateQcow2(CreateQcow2Command),134Device(DeviceCommand),135Disk(DiskCommand),136#[cfg(feature = "gpu")]137Gpu(GpuCommand),138#[cfg(feature = "audio")]139Snd(SndCommand),140MakeRT(MakeRTCommand),141Resume(ResumeCommand),142Run(RunCommand),143Stop(StopCommand),144Suspend(SuspendCommand),145Swap(SwapCommand),146Powerbtn(PowerbtnCommand),147Sleepbtn(SleepCommand),148Gpe(GpeCommand),149Usb(UsbCommand),150Version(VersionCommand),151Vfio(VfioCrosvmCommand),152#[cfg(feature = "pci-hotplug")]153VirtioNet(VirtioNetCommand),154Snapshot(SnapshotCommand),155}156157#[allow(clippy::large_enum_variant)]158#[derive(argh_helpers::FlattenSubcommand)]159pub enum Command {160CrossPlatform(CrossPlatformCommands),161Sys(super::sys::cmdline::Commands),162}163164#[derive(FromArgs)]165#[argh(subcommand, name = "balloon")]166/// Set balloon size of the crosvm instance to `SIZE` bytes167pub struct BalloonCommand {168#[argh(positional, arg_name = "SIZE")]169/// amount of bytes170pub num_bytes: u64,171#[argh(positional, arg_name = "VM_SOCKET")]172/// VM Socket path173pub socket_path: String,174/// wait for response175#[argh(switch)]176pub wait: bool,177}178179#[derive(argh::FromArgs)]180#[argh(subcommand, name = "balloon_stats")]181/// Prints virtio balloon statistics for a `VM_SOCKET`182pub struct BalloonStatsCommand {183#[argh(positional, arg_name = "VM_SOCKET")]184/// VM Socket path185pub socket_path: String,186}187188#[derive(argh::FromArgs)]189#[argh(subcommand, name = "balloon_ws")]190/// Prints virtio balloon working set for a `VM_SOCKET`191pub struct BalloonWsCommand {192#[argh(positional, arg_name = "VM_SOCKET")]193/// VM control socket path.194pub socket_path: String,195}196197#[derive(FromArgs)]198#[argh(subcommand, name = "battery")]199/// Modify battery200pub struct BatteryCommand {201#[argh(positional, arg_name = "BATTERY_TYPE")]202/// battery type203pub battery_type: String,204#[argh(positional)]205/// battery property206/// status | present | health | capacity | aconline207pub property: String,208#[argh(positional)]209/// battery property target210/// STATUS | PRESENT | HEALTH | CAPACITY | ACONLINE211pub target: String,212#[argh(positional, arg_name = "VM_SOCKET")]213/// VM Socket path214pub socket_path: String,215}216217#[cfg(feature = "composite-disk")]218#[derive(FromArgs)]219#[argh(subcommand, name = "create_composite")]220/// Create a new composite disk image file221pub struct CreateCompositeCommand {222#[argh(positional, arg_name = "PATH")]223/// image path224pub path: String,225#[argh(positional, arg_name = "LABEL:PARTITION[:writable][:<GUID>]")]226/// partitions227pub partitions: Vec<String>,228}229230#[cfg(feature = "qcow")]231#[derive(FromArgs)]232#[argh(subcommand, name = "create_qcow2")]233/// Create Qcow2 image given path and size234pub struct CreateQcow2Command {235#[argh(positional, arg_name = "PATH")]236/// path to the new qcow2 file to create237pub file_path: String,238#[argh(positional, arg_name = "SIZE")]239/// desired size of the image in bytes; required if not using --backing-file240pub size: Option<u64>,241#[argh(option)]242/// path to backing file; if specified, the image will be the same size as the backing file,243/// and SIZE may not be specified244pub backing_file: Option<String>,245}246247#[derive(FromArgs)]248#[argh(subcommand)]249pub enum DiskSubcommand {250Resize(ResizeDiskSubcommand),251}252253#[derive(FromArgs)]254/// resize disk255#[argh(subcommand, name = "resize")]256pub struct ResizeDiskSubcommand {257#[argh(positional, arg_name = "DISK_INDEX")]258/// disk index259pub disk_index: usize,260#[argh(positional, arg_name = "NEW_SIZE")]261/// new disk size262pub disk_size: u64,263#[argh(positional, arg_name = "VM_SOCKET")]264/// VM Socket path265pub socket_path: String,266}267268#[derive(FromArgs)]269#[argh(subcommand, name = "disk")]270/// Manage attached virtual disk devices271pub struct DiskCommand {272#[argh(subcommand)]273pub command: DiskSubcommand,274}275276#[derive(FromArgs)]277#[argh(subcommand, name = "make_rt")]278/// Enables real-time vcpu priority for crosvm instances started with `--delay-rt`279pub struct MakeRTCommand {280#[argh(positional, arg_name = "VM_SOCKET")]281/// VM Socket path282pub socket_path: String,283}284285#[derive(FromArgs)]286#[argh(subcommand, name = "resume")]287/// Resumes the crosvm instance. No-op if already running. When starting crosvm with `--restore`,288/// this command can be used to wait until the restore is complete289// Implementation note: All the restore work happens before crosvm becomes able to process incoming290// commands, so really all commands can be used to wait for restore to complete, but few are side291// effect free.292pub struct ResumeCommand {293#[argh(positional, arg_name = "VM_SOCKET")]294/// VM Socket path295pub socket_path: String,296/// suspend VM VCPUs and Devices297#[argh(switch)]298pub full: bool,299}300301#[derive(FromArgs)]302#[argh(subcommand, name = "stop")]303/// Stops crosvm instances via their control sockets304pub struct StopCommand {305#[argh(positional, arg_name = "VM_SOCKET")]306/// VM Socket path307pub socket_path: String,308}309310#[derive(FromArgs)]311#[argh(subcommand, name = "suspend")]312/// Suspends the crosvm instance313pub struct SuspendCommand {314#[argh(positional, arg_name = "VM_SOCKET")]315/// VM Socket path316pub socket_path: String,317/// suspend VM VCPUs and Devices318#[argh(switch)]319pub full: bool,320}321322#[derive(FromArgs)]323#[argh(subcommand, name = "enable")]324/// Enable vmm-swap of a VM. The guest memory is moved to staging memory325pub struct SwapEnableCommand {326#[argh(positional, arg_name = "VM_SOCKET")]327/// VM Socket path328pub socket_path: String,329}330331#[derive(FromArgs)]332#[argh(subcommand, name = "trim")]333/// Trim pages in the staging memory334pub struct SwapTrimCommand {335#[argh(positional, arg_name = "VM_SOCKET")]336/// VM Socket path337pub socket_path: String,338}339340#[derive(FromArgs)]341#[argh(subcommand, name = "out")]342/// Swap out staging memory to swap file343pub struct SwapOutCommand {344#[argh(positional, arg_name = "VM_SOCKET")]345/// VM Socket path346pub socket_path: String,347}348349#[derive(FromArgs)]350#[argh(subcommand, name = "disable")]351/// Disable vmm-swap of a VM352pub struct SwapDisableCommand {353#[argh(positional, arg_name = "VM_SOCKET")]354/// VM Socket path355pub socket_path: String,356#[argh(switch)]357/// clean up the swap file in the background.358pub slow_file_cleanup: bool,359}360361#[derive(FromArgs)]362#[argh(subcommand, name = "status")]363/// Get vmm-swap status of a VM364pub struct SwapStatusCommand {365#[argh(positional, arg_name = "VM_SOCKET")]366/// VM Socket path367pub socket_path: String,368}369370/// Vmm-swap commands371#[derive(FromArgs)]372#[argh(subcommand, name = "swap")]373pub struct SwapCommand {374#[argh(subcommand)]375pub nested: SwapSubcommands,376}377378#[derive(FromArgs)]379#[argh(subcommand)]380pub enum SwapSubcommands {381Enable(SwapEnableCommand),382Trim(SwapTrimCommand),383SwapOut(SwapOutCommand),384Disable(SwapDisableCommand),385Status(SwapStatusCommand),386}387388#[derive(FromArgs)]389#[argh(subcommand, name = "powerbtn")]390/// Triggers a power button event in the crosvm instance391pub struct PowerbtnCommand {392#[argh(positional, arg_name = "VM_SOCKET")]393/// VM Socket path394pub socket_path: String,395}396397#[derive(FromArgs)]398#[argh(subcommand, name = "sleepbtn")]399/// Triggers a sleep button event in the crosvm instance400pub struct SleepCommand {401#[argh(positional, arg_name = "VM_SOCKET")]402/// VM Socket path403pub socket_path: String,404}405406#[derive(FromArgs)]407#[argh(subcommand, name = "gpe")]408/// Injects a general-purpose event into the crosvm instance409pub struct GpeCommand {410#[argh(positional)]411/// GPE #412pub gpe: u32,413#[argh(positional, arg_name = "VM_SOCKET")]414/// VM Socket path415pub socket_path: String,416}417418#[derive(FromArgs)]419#[argh(subcommand, name = "usb")]420/// Manage attached virtual USB devices.421pub struct UsbCommand {422#[argh(subcommand)]423pub command: UsbSubCommand,424}425426#[cfg(feature = "gpu")]427#[derive(FromArgs)]428#[argh(subcommand, name = "gpu")]429/// Manage attached virtual GPU device.430pub struct GpuCommand {431#[argh(subcommand)]432pub command: GpuSubCommand,433}434435#[cfg(feature = "audio")]436#[derive(FromArgs)]437/// Mute or unmute all snd devices.438#[argh(subcommand, name = "mute-all")]439pub struct MuteAllCommand {440#[argh(positional)]441/// muted state. true for mute, and false for unmute442pub muted: bool,443#[argh(positional, arg_name = "VM_SOCKET")]444/// VM Socket path445pub socket_path: String,446}447448#[cfg(feature = "audio")]449#[derive(FromArgs)]450#[argh(subcommand)]451pub enum SndSubCommand {452MuteAll(MuteAllCommand),453}454455#[cfg(feature = "audio")]456#[derive(FromArgs)]457#[argh(subcommand, name = "snd")]458/// Manage virtio-snd device.459pub struct SndCommand {460#[argh(subcommand)]461pub command: SndSubCommand,462}463464#[derive(FromArgs)]465#[argh(subcommand, name = "version")]466/// Show package version.467pub struct VersionCommand {}468469#[derive(FromArgs)]470#[argh(subcommand, name = "add")]471/// ADD472pub struct VfioAddSubCommand {473#[argh(positional)]474/// path to host's vfio sysfs475pub vfio_path: PathBuf,476#[argh(positional, arg_name = "VM_SOCKET")]477/// VM Socket path478pub socket_path: String,479}480481#[derive(FromArgs)]482#[argh(subcommand, name = "remove")]483/// REMOVE484pub struct VfioRemoveSubCommand {485#[argh(positional)]486/// path to host's vfio sysfs487pub vfio_path: PathBuf,488#[argh(positional, arg_name = "VM_SOCKET")]489/// VM Socket path490pub socket_path: String,491}492493#[derive(FromArgs)]494#[argh(subcommand)]495pub enum VfioSubCommand {496Add(VfioAddSubCommand),497Remove(VfioRemoveSubCommand),498}499500#[derive(FromArgs)]501#[argh(subcommand, name = "vfio")]502/// add/remove host vfio pci device into guest503pub struct VfioCrosvmCommand {504#[argh(subcommand)]505pub command: VfioSubCommand,506}507508#[cfg(feature = "pci-hotplug")]509#[derive(FromArgs)]510#[argh(subcommand)]511pub enum VirtioNetSubCommand {512AddTap(VirtioNetAddSubCommand),513RemoveTap(VirtioNetRemoveSubCommand),514}515516#[cfg(feature = "pci-hotplug")]517#[derive(FromArgs)]518#[argh(subcommand, name = "add")]519/// Add by Tap name.520pub struct VirtioNetAddSubCommand {521#[argh(positional)]522/// tap name523pub tap_name: String,524#[argh(positional, arg_name = "VM_SOCKET")]525/// VM Socket path526pub socket_path: String,527}528529#[cfg(feature = "pci-hotplug")]530#[derive(FromArgs)]531#[argh(subcommand, name = "remove")]532/// Remove tap by bus number.533pub struct VirtioNetRemoveSubCommand {534#[argh(positional)]535/// bus number for device to remove536pub bus: u8,537#[argh(positional, arg_name = "VM_SOCKET")]538/// VM socket path539pub socket_path: String,540}541542#[cfg(feature = "pci-hotplug")]543#[derive(FromArgs)]544#[argh(subcommand, name = "virtio-net")]545/// add network device as virtio into guest.546pub struct VirtioNetCommand {547#[argh(subcommand)]548pub command: VirtioNetSubCommand,549}550551#[derive(FromArgs)]552#[argh(subcommand, name = "device")]553/// Start a device process554pub struct DeviceCommand {555/// configure async executor backend; "uring" or "epoll" on Linux, "handle" or "overlapped" on556/// Windows. If this option is omitted on Linux, "epoll" is used by default.557#[argh(option, arg_name = "EXECUTOR")]558pub async_executor: Option<ExecutorKind>,559560#[argh(subcommand)]561pub command: DeviceSubcommand,562}563564#[derive(FromArgs)]565#[argh(subcommand)]566/// Cross-platform Devices567pub enum CrossPlatformDevicesCommands {568Block(vhost_user_backend::BlockOptions),569#[cfg(feature = "gpu")]570Gpu(vhost_user_backend::GpuOptions),571#[cfg(feature = "net")]572Net(vhost_user_backend::NetOptions),573#[cfg(feature = "audio")]574Snd(vhost_user_backend::SndOptions),575}576577#[derive(argh_helpers::FlattenSubcommand)]578pub enum DeviceSubcommand {579CrossPlatform(CrossPlatformDevicesCommands),580Sys(super::sys::cmdline::DeviceSubcommand),581}582583#[cfg(feature = "gpu")]584#[derive(FromArgs)]585#[argh(subcommand)]586pub enum GpuSubCommand {587AddDisplays(GpuAddDisplaysCommand),588ListDisplays(GpuListDisplaysCommand),589RemoveDisplays(GpuRemoveDisplaysCommand),590SetDisplayMouseMode(GpuSetDisplayMouseModeCommand),591}592593#[cfg(feature = "gpu")]594#[derive(FromArgs)]595/// Attach a new display to the GPU device.596#[argh(subcommand, name = "add-displays")]597pub struct GpuAddDisplaysCommand {598#[argh(option)]599/// displays600pub gpu_display: Vec<GpuDisplayParameters>,601602#[argh(positional, arg_name = "VM_SOCKET")]603/// VM Socket path604pub socket_path: String,605}606607#[cfg(feature = "gpu")]608#[derive(FromArgs)]609/// List the displays currently attached to the GPU device.610#[argh(subcommand, name = "list-displays")]611pub struct GpuListDisplaysCommand {612#[argh(positional, arg_name = "VM_SOCKET")]613/// VM Socket path614pub socket_path: String,615}616617#[cfg(feature = "gpu")]618#[derive(FromArgs)]619/// Detach an existing display from the GPU device.620#[argh(subcommand, name = "remove-displays")]621pub struct GpuRemoveDisplaysCommand {622#[argh(option)]623/// display id624pub display_id: Vec<u32>,625#[argh(positional, arg_name = "VM_SOCKET")]626/// VM Socket path627pub socket_path: String,628}629630#[cfg(feature = "gpu")]631#[derive(FromArgs)]632/// Sets the mouse mode of a display attached to the GPU device.633#[argh(subcommand, name = "set-mouse-mode")]634pub struct GpuSetDisplayMouseModeCommand {635#[argh(option)]636/// display id637pub display_id: u32,638#[argh(option)]639/// display mouse mode640pub mouse_mode: GpuMouseMode,641#[argh(positional, arg_name = "VM_SOCKET")]642/// VM Socket path643pub socket_path: String,644}645646#[derive(FromArgs)]647#[argh(subcommand)]648pub enum UsbSubCommand {649Attach(UsbAttachCommand),650SecurityKeyAttach(UsbAttachKeyCommand),651Detach(UsbDetachCommand),652List(UsbListCommand),653}654655#[derive(FromArgs)]656/// Attach usb device657#[argh(subcommand, name = "attach")]658pub struct UsbAttachCommand {659#[argh(660positional,661arg_name = "BUS_ID:ADDR:BUS_NUM:DEV_NUM",662from_str_fn(parse_bus_id_addr)663)]664#[allow(dead_code)]665pub addr: (u8, u8, u16, u16),666#[argh(positional)]667/// usb device path668pub dev_path: String,669#[argh(positional, arg_name = "VM_SOCKET")]670/// VM Socket path671pub socket_path: String,672}673674#[derive(FromArgs)]675/// Attach security key device676#[argh(subcommand, name = "attach_key")]677pub struct UsbAttachKeyCommand {678#[argh(positional)]679/// security key hidraw device path680pub dev_path: String,681#[argh(positional, arg_name = "VM_SOCKET")]682/// VM Socket path683pub socket_path: String,684}685686#[derive(FromArgs)]687/// Detach usb device688#[argh(subcommand, name = "detach")]689pub struct UsbDetachCommand {690#[argh(positional, arg_name = "PORT")]691/// usb port692pub port: u8,693#[argh(positional, arg_name = "VM_SOCKET")]694/// VM Socket path695pub socket_path: String,696}697698#[derive(FromArgs)]699/// List currently attached USB devices700#[argh(subcommand, name = "list")]701pub struct UsbListCommand {702#[argh(positional, arg_name = "VM_SOCKET")]703/// VM Socket path704pub socket_path: String,705}706707/// Structure containing the parameters for a single disk as well as a unique counter increasing708/// each time a new disk parameter is parsed.709///710/// This allows the letters assigned to each disk to reflect the order of their declaration, as711/// we have several options for specifying disks (rwroot, root, etc) and order can thus be lost712/// when they are aggregated.713#[derive(Clone, Debug)]714struct DiskOptionWithId {715disk_option: DiskOption,716index: usize,717}718719/// FromStr implementation for argh.720impl FromStr for DiskOptionWithId {721type Err = String;722723fn from_str(s: &str) -> Result<Self, Self::Err> {724let disk_option: DiskOption = from_key_values(s)?;725Ok(Self::from(disk_option))726}727}728729/// Assign the next id to `disk_option`.730impl From<DiskOption> for DiskOptionWithId {731fn from(disk_option: DiskOption) -> Self {732static DISK_COUNTER: AtomicUsize = AtomicUsize::new(0);733Self {734disk_option,735index: DISK_COUNTER.fetch_add(1, Ordering::Relaxed),736}737}738}739740impl From<DiskOptionWithId> for DiskOption {741fn from(disk_option_with_id: DiskOptionWithId) -> Self {742disk_option_with_id.disk_option743}744}745746#[derive(FromArgs)]747#[argh(subcommand, name = "snapshot", description = "Snapshot commands")]748/// Snapshot commands749pub struct SnapshotCommand {750#[argh(subcommand)]751pub snapshot_command: SnapshotSubCommands,752}753754#[derive(FromArgs)]755#[argh(subcommand, name = "take")]756/// Take a snapshot of the VM757pub struct SnapshotTakeCommand {758#[argh(positional, arg_name = "snapshot_path")]759/// VM Image path760pub snapshot_path: PathBuf,761#[argh(positional, arg_name = "VM_SOCKET")]762/// VM Socket path763pub socket_path: String,764#[argh(switch)]765/// compress the ram snapshot.766pub compress_memory: bool,767#[argh(switch, arg_name = "encrypt")]768/// whether the snapshot should be encrypted769pub encrypt: bool,770}771772#[derive(FromArgs)]773#[argh(subcommand)]774/// Snapshot commands775pub enum SnapshotSubCommands {776Take(SnapshotTakeCommand),777}778779/// Container for GpuParameters that have been fixed after parsing using serde.780///781/// This deserializes as a regular `GpuParameters` and applies validation.782#[cfg(feature = "gpu")]783#[derive(Debug, Deserialize, FromKeyValues)]784#[serde(try_from = "GpuParameters")]785pub struct FixedGpuParameters(pub GpuParameters);786787#[cfg(feature = "gpu")]788impl TryFrom<GpuParameters> for FixedGpuParameters {789type Error = String;790791fn try_from(gpu_params: GpuParameters) -> Result<Self, Self::Error> {792fixup_gpu_options(gpu_params)793}794}795796/// User-specified configuration for the `crosvm run` command.797#[remain::sorted]798#[argh_helpers::pad_description_for_argh]799#[derive(FromArgs, Default)]800#[argh(subcommand, name = "run", description = "Start a new crosvm instance")]801pub struct RunCommand {802#[cfg(all(target_arch = "x86_64", unix))]803#[argh(switch)]804/// enable AC adapter device805/// It purpose is to emulate ACPI ACPI0003 device, replicate and propagate the806/// ac adapter status from the host to the guest.807pub ac_adapter: Option<bool>,808809#[argh(option, arg_name = "PATH")]810/// path to user provided ACPI table811pub acpi_table: Vec<PathBuf>,812813#[cfg(feature = "android_display")]814#[argh(option, arg_name = "NAME")]815/// name that the Android display backend will be registered to the service manager.816pub android_display_service: Option<String>,817818#[argh(option)]819/// path to Android fstab820pub android_fstab: Option<PathBuf>,821822/// configure async executor backend; "uring" or "epoll" on Linux, "handle" or "overlapped" on823/// Windows. If this option is omitted on Linux, "epoll" is used by default.824#[argh(option, arg_name = "EXECUTOR")]825pub async_executor: Option<ExecutorKind>,826827#[cfg(feature = "balloon")]828#[argh(option, arg_name = "N")]829/// amount to bias balance of memory between host and guest as the balloon inflates, in mib.830pub balloon_bias_mib: Option<i64>,831832#[cfg(feature = "balloon")]833#[argh(option, arg_name = "PATH")]834/// path for balloon controller socket.835pub balloon_control: Option<PathBuf>,836837#[cfg(feature = "balloon")]838#[argh(switch)]839/// enable page reporting in balloon.840pub balloon_page_reporting: Option<bool>,841842#[cfg(feature = "balloon")]843#[argh(option)]844/// set number of WS bins to use (default = 4).845pub balloon_ws_num_bins: Option<u8>,846847#[cfg(feature = "balloon")]848#[argh(switch)]849/// enable working set reporting in balloon.850pub balloon_ws_reporting: Option<bool>,851852#[argh(option)]853/// comma separated key=value pairs for setting up battery854/// device855/// Possible key values:856/// type=goldfish - type of battery emulation, defaults to857/// goldfish858pub battery: Option<BatteryConfig>,859860#[argh(option)]861/// path to BIOS/firmware ROM862pub bios: Option<PathBuf>,863864#[argh(option, short = 'b', arg_name = "PATH[,key=value[,key=value[,...]]]")]865/// parameters for setting up a block device.866/// Valid keys:867/// path=PATH - Path to the disk image. Can be specified868/// without the key as the first argument.869/// ro=BOOL - Whether the block should be read-only.870/// (default: false)871/// root=BOOL - Whether the block device should be mounted872/// as the root filesystem. This will add the required873/// parameters to the kernel command-line. Can only be874/// specified once. (default: false)875/// sparse=BOOL - Indicates whether the disk should support876/// the discard operation. (default: true)877/// block-size=BYTES - Set the reported block size of the878/// disk. (default: 512)879/// id=STRING - Set the block device identifier to an ASCII880/// string, up to 20 characters. (default: no ID)881/// direct=BOOL - Use O_DIRECT mode to bypass page cache.882/// (default: false)883/// async-executor=epoll|uring - set the async executor kind884/// to simulate the block device with. This takes885/// precedence over the global --async-executor option.886/// multiple-workers=BOOL - (Experimental) run multiple887/// worker threads in parallel. this option is not888/// effective for vhost-user blk device.889/// (default: false)890/// packed-queue=BOOL - Use packed virtqueue891/// in block device. If false, use split virtqueue.892/// (default: false)893/// bootindex=NUM - An index dictating the order that the894/// firmware will consider devices to boot from.895/// For example, if bootindex=2, then the BIOS896/// will attempt to boot from the current device897/// after failing to boot from the device with898/// bootindex=1.899/// pci-address=ADDR - Preferred PCI address, e.g. "00:01.0".900block: Vec<DiskOptionWithId>,901902#[cfg(any(target_os = "android", target_os = "linux"))]903#[argh(switch)]904/// set a minimum utilization for vCPU threads which will hint to the host scheduler905/// to ramp up higher frequencies or place vCPU threads on larger cores.906pub boost_uclamp: Option<bool>,907908#[cfg(target_arch = "x86_64")]909#[argh(switch)]910/// break linux PCI configuration space io probing, to force the use of911/// mmio access to PCIe ECAM.912pub break_linux_pci_config_io: Option<bool>,913914/// ratelimit enforced on detected bus locks in guest.915/// The default value of the bus_lock_ratelimit is 0 per second,916/// which means no limitation on the guest's bus locks.917#[cfg(target_arch = "x86_64")]918#[argh(option)]919pub bus_lock_ratelimit: Option<u64>,920921#[argh(option, arg_name = "CID")]922/// (DEPRECATED): Use --vsock.923/// context ID for virtual sockets.924pub cid: Option<u64>,925926#[cfg(any(target_os = "android", target_os = "linux"))]927#[argh(928option,929arg_name = "unpin_policy=POLICY,unpin_interval=NUM,unpin_limit=NUM,unpin_gen_threshold=NUM"930)]931/// comma separated key=value pairs for setting up coiommu932/// devices.933/// Possible key values:934/// unpin_policy=lru - LRU unpin policy.935/// unpin_interval=NUM - Unpin interval time in seconds.936/// unpin_limit=NUM - Unpin limit for each unpin cycle, in937/// unit of page count. 0 is invalid.938/// unpin_gen_threshold=NUM - Number of unpin intervals a939/// pinned page must be busy for to be aged into the940/// older which is less frequently checked generation.941pub coiommu: Option<devices::CoIommuParameters>,942943#[argh(option, default = "true")]944/// protect VM threads from hyperthreading-based attacks by scheduling them on different cores.945/// Enabled by default, and required for per_vm_core_scheduling.946pub core_scheduling: bool,947948#[argh(option, arg_name = "CPUSET", from_str_fn(parse_cpu_affinity))]949/// comma-separated list of CPUs or CPU ranges to run VCPUs on (e.g. 0,1-3,5)950/// or colon-separated list of assignments of guest to host CPU assignments (e.g. 0=0:1=1:2=2)951/// (default: no mask)952pub cpu_affinity: Option<VcpuAffinity>,953954#[argh(955option,956arg_name = "CPU=CAP[,CPU=CAP[,...]]",957from_str_fn(parse_cpu_btreemap_u32)958)]959/// set the relative capacity of the given CPU (default: no capacity)960pub cpu_capacity: Option<BTreeMap<usize, u32>>, // CPU index -> capacity961962#[argh(option, arg_name = "CPUSET")]963/// (DEPRECATED): Use "--cpu clusters=[...]".964/// group the given CPUs into a cluster (default: no clusters)965pub cpu_cluster: Vec<CpuSet>,966967#[cfg(all(968target_arch = "aarch64",969any(target_os = "android", target_os = "linux")970))]971#[argh(972option,973arg_name = "CPU=FREQS[,CPU=FREQS[,...]]",974from_str_fn(parse_cpu_frequencies)975)]976/// set the list of frequencies in KHz for the given CPU (default: no frequencies).977/// In the event that the user specifies a frequency (after normalizing for cpu_capacity)978/// that results in a performance point that goes below the lowest frequency that the pCPU can979/// support, the virtual cpufreq device will actively throttle the vCPU to deliberately slow980/// its performance to match the guest's request.981pub cpu_frequencies_khz: Option<BTreeMap<usize, Vec<u32>>>, // CPU index -> frequencies982983#[cfg(all(984target_arch = "aarch64",985any(target_os = "android", target_os = "linux")986))]987#[argh(988option,989arg_name = "CPU=RATIO[,CPU=RATIO[,...]]",990from_str_fn(parse_cpu_btreemap_u32)991)]992/// set the instructions per cycle (IPC) performance of the vCPU relative to the pCPU it is993/// affined to normalized to 1024. Defaults to 1024 which represents the baseline performance994/// of the pCPU, setting the vCPU to 1024 means it will match the per cycle performance of the995/// pCPU. This ratio determines how quickly the same workload will complete on the vCPU996/// compared to the pCPU. Ex. Setting the ratio to 512 will result in the task taking twice as997/// long if it were set to 1024 given the same frequency. Conversely, using a value > 1024 will998/// result in faster per cycle perf relative to the pCPU with some important limitations. In999/// combination with virtual frequencies defined with "cpu_frequencies_khz", performance points1000/// with vCPU frequencies * vCPU IPC > pCPU@FMax * 1024 will not be properly supported.1001pub cpu_ipc_ratio: Option<BTreeMap<usize, u32>>, // CPU index -> ipc_ratio10021003#[argh(option, short = 'c')]1004/// cpu parameters.1005/// Possible key values:1006/// num-cores=NUM - number of VCPUs. (default: 1)1007/// clusters=[[CLUSTER],...] - CPU clusters (default: None)1008/// Each CLUSTER is a set containing a list of CPUs1009/// that should belong to the same cluster. Individual1010/// CPU ids or ranges can be specified, comma-separated.1011/// Examples:1012/// clusters=[[0],[1],[2],[3]] - creates 4 clusters, one1013/// for each specified core.1014/// clusters=[[0-3]] - creates a cluster for cores 0 to 31015/// included.1016/// clusters=[[0,2],[1,3],[4-7,12]] - creates one cluster1017/// for cores 0 and 2, another one for cores 1 and 3,1018/// and one last for cores 4, 5, 6, 7 and 12.1019/// core-types=[atom=[CPUSET],core=[CPUSET]] - Hybrid core1020/// types. (default: None)1021/// Set the type of virtual hybrid CPUs. Currently1022/// supports Intel Atom and Intel Core cpu types.1023/// Examples:1024/// core-types=[atom=[0,1],core=[2,3]] - set vCPU 0 and1025/// vCPU 1 as intel Atom type, also set vCPU 2 and vCPU 31026/// as intel Core type.1027/// boot-cpu=NUM - Select vCPU to boot from. (default: 0) (aarch64 only)1028/// freq_domains=[[FREQ_DOMAIN],...] - CPU freq_domains (default: None) (aarch64 only)1029/// Usage is identical to clusters, each FREQ_DOMAIN is a set containing a1030/// list of CPUs that should belong to the same freq_domain. Individual1031/// CPU ids or ranges can be specified, comma-separated.1032/// Examples:1033/// freq_domains=[[0],[1],[2],[3]] - creates 4 freq_domains, one1034/// for each specified core.1035/// freq_domains=[[0-3]] - creates a freq_domain for cores 0 to 31036/// included.1037/// freq_domains=[[0,2],[1,3],[4-7,12]] - creates one freq_domain1038/// for cores 0 and 2, another one for cores 1 and 3,1039/// and one last for cores 4, 5, 6, 7 and 12.1040/// sve=[auto=bool] - SVE Config. (aarch64 only)1041/// Examples:1042/// sve=[auto=true] - Enables SVE on device if supported. Not enable if unsupported.1043/// default: auto=true.1044pub cpus: Option<CpuOptions>,10451046#[cfg(all(windows, feature = "crash-report"))]1047#[argh(option, arg_name = "\\\\.\\pipe\\PIPE_NAME")]1048/// the crash handler ipc pipe name.1049pub crash_pipe_name: Option<String>,10501051#[argh(switch)]1052/// don't set VCPUs real-time until make-rt command is run1053pub delay_rt: Option<bool>,10541055// Currently, only pKVM is supported so limit this option to Android kernel.1056#[cfg(all(target_os = "android", target_arch = "aarch64"))]1057#[argh(option)]1058/// selects the interface for guest-controlled power management of assigned devices.1059pub dev_pm: Option<DevicePowerManagerConfig>,10601061#[argh(option, arg_name = "PATH[,filter]")]1062/// path to device tree overlay binary which will be applied to the base guest device tree1063/// Parameters:1064/// filter - only apply device tree nodes which belong to a VFIO device1065pub device_tree_overlay: Vec<DtboOption>,10661067#[argh(switch)]1068/// run all devices in one, non-sandboxed process1069pub disable_sandbox: Option<bool>,10701071#[argh(switch)]1072/// disable INTx in virtio devices1073pub disable_virtio_intx: Option<bool>,10741075#[argh(option, short = 'd', arg_name = "PATH[,key=value[,key=value[,...]]]")]1076/// (DEPRECATED): Use --block.1077/// path to a disk image followed by optional comma-separated1078/// options.1079/// Valid keys:1080/// sparse=BOOL - Indicates whether the disk should support1081/// the discard operation (default: true)1082/// block_size=BYTES - Set the reported block size of the1083/// disk (default: 512)1084/// id=STRING - Set the block device identifier to an ASCII1085/// string, up to 20 characters (default: no ID)1086/// o_direct=BOOL - Use O_DIRECT mode to bypass page cache"1087disk: Vec<DiskOptionWithId>,10881089#[argh(switch)]1090/// capture keyboard input from the display window1091pub display_window_keyboard: Option<bool>,10921093#[argh(switch)]1094/// capture keyboard input from the display window1095pub display_window_mouse: Option<bool>,10961097#[argh(option, long = "dump-device-tree-blob", arg_name = "FILE")]1098/// dump generated device tree as a DTB file1099pub dump_device_tree_blob: Option<PathBuf>,11001101#[argh(1102option,1103arg_name = "CPU=DYN_PWR[,CPU=DYN_PWR[,...]]",1104from_str_fn(parse_cpu_btreemap_u32)1105)]1106/// pass power modeling param from to guest OS; scalar coefficient used in conjuction with1107/// voltage and frequency for calculating power; in units of uW/MHz/^21108pub dynamic_power_coefficient: Option<BTreeMap<usize, u32>>,11091110#[argh(switch)]1111/// enable the fw_cfg device. If enabled, fw_cfg will automatically produce firmware1112/// configuration files containing such information as bootorder and the memory location of1113/// rsdp. If --fw-cfg is specified (see below), there is no need for this argument.1114pub enable_fw_cfg: Option<bool>,11151116#[cfg(target_arch = "x86_64")]1117#[argh(switch)]1118/// expose HWP feature to the guest1119pub enable_hwp: Option<bool>,11201121#[argh(option, arg_name = "PATH")]1122/// path to an event device node. The device will be grabbed (unusable from the host) and made1123/// available to the guest with the same configuration it shows on the host1124pub evdev: Vec<PathBuf>,11251126#[cfg(windows)]1127#[argh(switch)]1128/// gather and display statistics on Vm Exits and Bus Reads/Writes.1129pub exit_stats: Option<bool>,11301131#[argh(option)]1132/// where the FDT is placed in memory.1133///1134/// On x86_64, no effect.1135///1136/// On aarch64, defaults to `end` for kernel payloads and to `start` for BIOS payloads.1137///1138/// On riscv64, defaults to `after-payload`.1139pub fdt_position: Option<FdtPosition>,11401141#[cfg(all(target_os = "android", target_arch = "aarch64"))]1142#[argh(option)]1143/// allow FF-A protocol for this vm. Currently only supported option is --guest-ffa=auto1144pub ffa: Option<FfaConfig>,11451146#[argh(1147option,1148arg_name = "addr=NUM,size=SIZE,path=PATH[,offset=NUM][,rw][,sync]"1149)]1150/// map the given file into guest memory at the specified1151/// address.1152/// Parameters (addr, size, path are required):1153/// addr=NUM - guest physical address to map at1154/// size=NUM - amount of memory to map1155/// path=PATH - path to backing file/device to map1156/// offset=NUM - offset in backing file (default 0)1157/// rw - make the mapping writable (default readonly)1158/// sync - open backing file with O_SYNC1159/// align - whether to adjust addr and size to page1160/// boundaries implicitly1161/// ram - whether mapping to a RAM or MMIO region. defaults to MMIO1162pub file_backed_mapping: Vec<FileBackedMappingParameters>,11631164#[cfg(target_arch = "x86_64")]1165#[argh(switch)]1166/// force use of a calibrated TSC cpuid leaf (0x15) even if the hypervisor1167/// doesn't require one.1168pub force_calibrated_tsc_leaf: Option<bool>,11691170#[argh(switch)]1171/// force off use of readonly memslots1172///1173/// Workaround for hypervisors that incorrectly advertise readonly memslot support (e.g. early1174/// versions of pKVM). Currently only affects KVM.1175pub force_disable_readonly_mem: bool,11761177#[argh(option, arg_name = "name=NAME,(path=PATH|string=STRING)")]1178/// comma separated key=value pairs to specify data to pass to1179/// fw_cfg.1180/// Possible key values:1181/// name - Name of the file in fw_cfg that will1182/// be associated with provided data1183/// path - Path to data that will be included in1184/// fw_cfg under name1185/// string - Alternative to path, data to be1186/// included in fw_cfg under name1187pub fw_cfg: Vec<FwCfgParameters>,11881189#[cfg(feature = "gdb")]1190#[argh(option, arg_name = "PORT")]1191/// (EXPERIMENTAL) gdb on the given port1192pub gdb: Option<u32>,11931194#[cfg(feature = "gpu")]1195#[argh(option)]1196// Although `gpu` is a vector, we are currently limited to a single GPU device due to the1197// resource bridge and interaction with other video devices. We do use a vector so the GPU1198// device can be specified like other device classes in the configuration file, and because we1199// hope to lift this limitation eventually.1200/// (EXPERIMENTAL) Comma separated key=value pairs for setting1201/// up a virtio-gpu device1202/// Possible key values:1203/// backend=(2d|virglrenderer|gfxstream) - Which backend to1204/// use for virtio-gpu (determining rendering protocol)1205/// max-num-displays=INT - The maximum number of concurrent1206/// virtual displays in this VM. This must not exceed1207/// VIRTIO_GPU_MAX_SCANOUTS (i.e. 16).1208/// displays=[[GpuDisplayParameters]] - The list of virtual1209/// displays to create when booting this VM. Displays may1210/// be hotplugged after booting. See the possible key1211/// values for GpuDisplayParameters in the section below.1212/// context-types=LIST - The list of supported context1213/// types, separated by ':' (default: no contexts enabled)1214/// width=INT - The width of the virtual display connected1215/// to the virtio-gpu.1216/// Deprecated - use `displays` instead.1217/// height=INT - The height of the virtual display1218/// connected to the virtio-gpu.1219/// Deprecated - use `displays` instead.1220/// egl[=true|=false] - If the backend should use a EGL1221/// context for rendering.1222/// glx[=true|=false] - If the backend should use a GLX1223/// context for rendering.1224/// surfaceless[=true|=false] - If the backend should use a1225/// surfaceless context for rendering.1226/// vulkan[=true|=false] - If the backend should support1227/// vulkan1228/// wsi=vk - If the gfxstream backend should use the Vulkan1229/// swapchain to draw on a window1230/// cache-path=PATH - The path to the virtio-gpu device1231/// shader cache.1232/// cache-size=SIZE - The maximum size of the shader cache.1233/// pci-address=ADDR - The PCI bus, device, and function1234/// numbers, e.g. "00:01.0"1235/// pci-bar-size=SIZE - The size for the PCI BAR in bytes1236/// (default 8gb).1237/// implicit-render-server[=true|=false] - If the render1238/// server process should be allowed to autostart1239/// (ignored when sandboxing is enabled)1240/// fixed-blob-mapping[=true|=false] - if gpu memory blobs1241/// should use fixed address mapping.1242///1243/// Possible key values for GpuDisplayParameters:1244/// mode=(borderless_full_screen|windowed[width,height]) -1245/// Whether to show the window on the host in full1246/// screen or windowed mode. If not specified, windowed1247/// mode is used by default. "windowed" can also be1248/// specified explicitly to use a window size different1249/// from the default one.1250/// hidden[=true|=false] - If the display window is1251/// initially hidden (default: false).1252/// refresh-rate=INT - Force a specific vsync generation1253/// rate in hertz on the guest (default: 60)1254/// dpi=[INT,INT] - The horizontal and vertical DPI of the1255/// display (default: [320,320])1256/// horizontal-dpi=INT - The horizontal DPI of the display1257/// (default: 320)1258/// Deprecated - use `dpi` instead.1259/// vertical-dpi=INT - The vertical DPI of the display1260/// (default: 320)1261/// Deprecated - use `dpi` instead.1262pub gpu: Vec<FixedGpuParameters>,12631264#[cfg(all(unix, feature = "gpu"))]1265#[argh(option, arg_name = "PATH")]1266/// move all vGPU threads to this Cgroup (default: nothing moves)1267pub gpu_cgroup_path: Option<PathBuf>,12681269#[cfg(feature = "gpu")]1270#[argh(option)]1271/// (DEPRECATED): Use --gpu.1272/// (EXPERIMENTAL) Comma separated key=value pairs for setting1273/// up a display on the virtio-gpu device. See comments for `gpu`1274/// for possible key values of GpuDisplayParameters.1275pub gpu_display: Vec<GpuDisplayParameters>,12761277#[cfg(all(unix, feature = "gpu"))]1278#[argh(option)]1279/// (EXPERIMENTAL) Comma separated key=value pairs for setting1280/// up a render server for the virtio-gpu device1281/// Possible key values:1282/// path=PATH - The path to the render server executable.1283/// cache-path=PATH - The path to the render server shader1284/// cache.1285/// cache-size=SIZE - The maximum size of the shader cache1286/// foz-db-list-path=PATH - The path to GPU foz db list1287/// file for dynamically loading RO caches.1288pub gpu_render_server: Option<GpuRenderServerParameters>,12891290#[cfg(all(unix, feature = "gpu"))]1291#[argh(option, arg_name = "PATH")]1292/// move all vGPU server threads to this Cgroup (default: nothing moves)1293pub gpu_server_cgroup_path: Option<PathBuf>,12941295#[argh(switch)]1296/// use mirror cpu topology of Host for Guest VM, also copy some cpu feature to Guest VM1297pub host_cpu_topology: Option<bool>,12981299#[cfg(windows)]1300#[argh(option, arg_name = "PATH")]1301/// string representation of the host guid in registry format, for namespacing vsock1302/// connections.1303pub host_guid: Option<String>,13041305#[cfg(all(unix, feature = "net"))]1306#[argh(option, arg_name = "IP")]1307/// (DEPRECATED): Use --net.1308/// IP address to assign to host tap interface1309pub host_ip: Option<std::net::Ipv4Addr>,13101311#[argh(switch)]1312/// advise the kernel to use Huge Pages for guest memory mappings1313pub hugepages: Option<bool>,13141315/// hypervisor backend1316#[argh(option)]1317pub hypervisor: Option<HypervisorKind>,13181319#[cfg(feature = "balloon")]1320#[argh(option, arg_name = "N")]1321/// amount of guest memory outside the balloon at boot in MiB. (default: --mem)1322pub init_mem: Option<u64>,13231324#[argh(option, short = 'i', arg_name = "PATH")]1325/// initial ramdisk to load1326pub initrd: Option<PathBuf>,13271328#[argh(option, arg_name = "TYPE[OPTIONS]")]1329/// virtio-input device1330/// TYPE is an input device type, and OPTIONS are key=value1331/// pairs specific to the device type:1332/// evdev[path=PATH]1333/// keyboard[path=PATH]1334/// mouse[path=PATH]1335/// multi-touch[path=PATH,width=W,height=H,name=N]1336/// rotary[path=PATH]1337/// single-touch[path=PATH,width=W,height=H,name=N]1338/// switches[path=PATH]1339/// trackpad[path=PATH,width=W,height=H,name=N]1340/// multi-touch-trackpad[path=PATH,width=W,height=H,name=N]1341/// See <https://crosvm.dev/book/devices/input.html> for more1342/// information.1343pub input: Vec<InputDeviceOption>,13441345#[argh(option, arg_name = "kernel|split|userspace")]1346/// type of interrupt controller emulation. "split" is only available for x86 KVM.1347pub irqchip: Option<IrqChipKind>,13481349#[argh(switch)]1350/// allow to enable ITMT scheduling feature in VM. The success of enabling depends on HWP and1351/// ACPI CPPC support on hardware1352pub itmt: Option<bool>,13531354#[argh(positional, arg_name = "KERNEL")]1355/// bzImage of kernel to run1356pub kernel: Option<PathBuf>,13571358#[cfg(windows)]1359#[argh(option, arg_name = "PATH")]1360/// forward hypervisor kernel driver logs for this VM to a file.1361pub kernel_log_file: Option<String>,13621363#[argh(option, arg_name = "PATH")]1364/// path to a socket from where to read keyboard input events and write status updates to1365pub keyboard: Vec<PathBuf>,13661367#[cfg(any(target_os = "android", target_os = "linux"))]1368#[argh(option, arg_name = "PATH")]1369/// (DEPRECATED): Use --hypervisor.1370/// path to the KVM device. (default /dev/kvm)1371pub kvm_device: Option<PathBuf>,13721373#[cfg(any(target_os = "android", target_os = "linux"))]1374#[argh(switch)]1375/// disable host swap on guest VM pages1376pub lock_guest_memory: Option<bool>,13771378#[cfg(windows)]1379#[argh(option, arg_name = "PATH")]1380/// redirect logs to the supplied log file at PATH rather than stderr. For multi-process mode,1381/// use --logs-directory instead1382pub log_file: Option<String>,13831384#[cfg(windows)]1385#[argh(option, arg_name = "PATH")]1386/// path to the logs directory used for crosvm processes. Logs will be sent to stderr if unset,1387/// and stderr/stdout will be uncaptured1388pub logs_directory: Option<String>,13891390#[cfg(all(unix, feature = "net"))]1391#[argh(option, arg_name = "MAC", long = "mac")]1392/// (DEPRECATED): Use --net.1393/// MAC address for VM1394pub mac_address: Option<net_util::MacAddress>,13951396#[cfg(all(unix, feature = "media", feature = "video-decoder"))]1397#[argh(option, arg_name = "[backend]")]1398/// add a virtio-media adapter device.1399pub media_decoder: Vec<VideoDeviceConfig>,14001401#[argh(option, short = 'm', arg_name = "N")]1402/// memory parameters.1403/// Possible key values:1404/// size=NUM - amount of guest memory in MiB. (default: 256)1405pub mem: Option<MemOptions>,14061407#[allow(dead_code)] // Unused. Consider deleting it + the Config field of the same name.1408#[argh(option, from_str_fn(parse_mmio_address_range))]1409/// MMIO address ranges1410pub mmio_address_range: Option<Vec<AddressRange>>,14111412#[argh(option, arg_name = "PATH")]1413/// path to a socket from where to read mouse input events and write status updates to1414pub mouse: Vec<PathBuf>,14151416#[cfg(target_arch = "aarch64")]1417#[argh(switch)]1418/// enable the Memory Tagging Extension in the guest1419pub mte: Option<bool>,14201421#[argh(1422option,1423arg_name = "[path=]PATH[,width=WIDTH][,height=HEIGHT][,name=NAME]",1424from_str_fn(parse_touch_device_option)1425)]1426/// path to a socket from where to read multi touch input events (such as those from a1427/// touchscreen) and write status updates to, optionally followed by width and height (defaults1428/// to 800x1280) and a name for the input device1429pub multi_touch: Vec<TouchDeviceOption>,14301431#[argh(option)]1432/// optional name for the VM. This is used as the name of the crosvm1433/// process which is helpful to distinguish multiple crosvm processes.1434/// A name longer than 15 bytes is truncated on Linux-like OSes. This1435/// is no-op on Windows and MacOS at the moment.1436pub name: Option<String>,14371438#[cfg(all(unix, feature = "net"))]1439#[argh(1440option,1441arg_name = "(tap-name=TAP_NAME,mac=MAC_ADDRESS|tap-fd=TAP_FD,mac=MAC_ADDRESS|host-ip=IP,netmask=NETMASK,mac=MAC_ADDRESS),vhost-net=VHOST_NET,vq-pairs=N,pci-address=ADDR"1442)]1443/// comma separated key=value pairs for setting up a network1444/// device.1445/// Possible key values:1446/// (1447/// tap-name=STRING - name of a configured persistent TAP1448/// interface to use for networking.1449/// mac=STRING - MAC address for VM. [Optional]1450/// OR1451/// tap-fd=INT - File descriptor for configured tap1452/// device.1453/// mac=STRING - MAC address for VM. [Optional]1454/// OR1455/// (1456/// host-ip=STRING - IP address to assign to host tap1457/// interface.1458/// AND1459/// netmask=STRING - Netmask for VM subnet.1460/// AND1461/// mac=STRING - MAC address for VM.1462/// )1463/// )1464/// AND1465/// vhost-net1466/// OR1467/// vhost-net=[device=/vhost_net/device] - use vhost_net.1468/// If the device path is not the default1469/// /dev/vhost-net, it can also be1470/// specified.1471/// Default: false. [Optional]1472/// vq-pairs=N - number of rx/tx queue pairs.1473/// Default: 1. [Optional]1474/// packed-queue - use packed queue.1475/// If not set or set to false, it will1476/// use split virtqueue.1477/// Default: false. [Optional]1478/// pci-address - preferred PCI address, e.g. "00:01.0"1479/// Default: automatic PCI address assignment. [Optional]1480/// mrg_rxbuf - enable VIRTIO_NET_F_MRG_RXBUF feature.1481/// If not set or set to false, it will disable this feature.1482/// Default: false. [Optional]1483///1484/// Either one tap_name, one tap_fd or a triplet of host_ip,1485/// netmask and mac must be specified.1486pub net: Vec<NetParameters>,14871488#[cfg(all(unix, feature = "net"))]1489#[argh(option, arg_name = "N")]1490/// (DEPRECATED): Use --net.1491/// virtio net virtual queue pairs. (default: 1)1492pub net_vq_pairs: Option<u16>,14931494#[cfg(all(unix, feature = "net"))]1495#[argh(option, arg_name = "NETMASK")]1496/// (DEPRECATED): Use --net.1497/// netmask for VM subnet1498pub netmask: Option<std::net::Ipv4Addr>,14991500#[cfg(feature = "balloon")]1501#[argh(switch)]1502/// don't use virtio-balloon device in the guest1503pub no_balloon: Option<bool>,15041505#[cfg(target_arch = "x86_64")]1506#[argh(switch)]1507/// don't use legacy KBD devices emulation1508pub no_i8042: Option<bool>,15091510#[cfg(target_arch = "aarch64")]1511#[argh(switch)]1512/// disable Performance Monitor Unit (PMU)1513pub no_pmu: Option<bool>,15141515#[argh(switch)]1516/// don't create RNG device in the guest1517pub no_rng: Option<bool>,15181519#[cfg(target_arch = "x86_64")]1520#[argh(switch)]1521/// don't use legacy RTC devices emulation1522pub no_rtc: Option<bool>,15231524#[argh(switch)]1525/// don't use SMT in the guest1526pub no_smt: Option<bool>,15271528#[argh(switch)]1529/// don't use usb devices in the guest1530pub no_usb: Option<bool>,15311532#[cfg(target_arch = "x86_64")]1533#[argh(option, arg_name = "OEM_STRING")]1534/// (DEPRECATED): Use --smbios.1535/// SMBIOS OEM string values to add to the DMI tables1536pub oem_strings: Vec<String>,15371538#[argh(option, short = 'p', arg_name = "PARAMS")]1539/// extra kernel command line arguments. Can be given more than once1540pub params: Vec<String>,15411542#[argh(option)]1543/// PCI parameters.1544///1545/// Possible key values:1546/// mem=[start=INT,size=INT] - region for non-prefetchable1547/// PCI device memory below 4G1548///1549/// Possible key values (aarch64 only):1550/// cam=[start=INT,size=INT] - region for PCI Configuration1551/// Access Mechanism1552///1553/// Possible key values (x86_64 only):1554/// ecam=[start=INT,size=INT] - region for PCIe Enhanced1555/// Configuration Access Mechanism1556pub pci: Option<PciConfig>,15571558#[cfg(any(target_os = "android", target_os = "linux"))]1559#[cfg(feature = "pci-hotplug")]1560#[argh(option, arg_name = "pci_hotplug_slots")]1561/// number of hotplug slot count (default: None)1562pub pci_hotplug_slots: Option<u8>,15631564#[cfg(target_arch = "x86_64")]1565#[argh(option, arg_name = "pci_low_mmio_start")]1566/// the pci mmio start address below 4G1567pub pci_start: Option<u64>,15681569#[argh(switch)]1570/// enable per-VM core scheduling intead of the default one (per-vCPU core scheduing) by1571/// making all vCPU threads share same cookie for core scheduling.1572/// This option is no-op on devices that have neither MDS nor L1TF vulnerability1573pub per_vm_core_scheduling: Option<bool>,15741575#[argh(1576option,1577arg_name = "path=PATH,[block_size=SIZE]",1578from_str_fn(parse_pflash_parameters)1579)]1580/// comma-seperated key-value pair for setting up the pflash device, which provides space to1581/// store UEFI variables. block_size defaults to 4K.1582/// [--pflash <path=PATH,[block_size=SIZE]>]1583pub pflash: Option<PflashParameters>,15841585#[cfg(any(target_os = "android", target_os = "linux"))]1586#[argh(option, arg_name = "PATH")]1587/// path to empty directory to use for sandbox pivot root1588pub pivot_root: Option<PathBuf>,15891590#[argh(option)]1591/// parameters for setting up a virtio-pmem device.1592/// Valid keys:1593/// path=PATH - Path to the disk image. Can be specified1594/// without the key as the first argument.1595/// ro=BOOL - Whether the pmem device should be read-only.1596/// (default: false)1597/// vma-size=BYTES - (Experimental) Size in bytes1598/// of an anonymous virtual memory area that is1599/// created to back this device. When this1600/// option is specified, the disk image path1601/// is used to name the memory area1602/// swap-interval-ms=NUM - (Experimental) Interval1603/// in milliseconds for periodic swap out of1604/// memory mapping created by this device. 01605/// means the memory mapping won't be swapped1606/// out by crosvm1607pub pmem: Vec<PmemOption>,16081609#[argh(option, arg_name = "PATH")]1610/// (DEPRECATED): Use --pmem.1611/// path to a disk image1612pmem_device: Vec<DiskOption>,16131614#[cfg(any(target_os = "android", target_os = "linux"))]1615#[argh(1616option,1617arg_name = "PATH[,key=value[,key=value[,...]]]",1618from_str_fn(parse_pmem_ext2_option)1619)]1620/// (EXPERIMENTAL): construct an ext2 file system on a pmem1621/// device from the given directory. The argument is the form of1622/// "PATH[,key=value[,key=value[,...]]]".1623/// Valid keys:1624/// blocks_per_group=NUM - Number of blocks in a block1625/// group. (default: 4096)1626/// inodes_per_group=NUM - Number of inodes in a block1627/// group. (default: 1024)1628/// size=BYTES - Size of the memory region allocated by this1629/// device. A file system will be built on the region. If1630/// the filesystem doesn't fit within this size, crosvm1631/// will fail to start with an error.1632/// The number of block groups in the file system is1633/// calculated from this value and other given parameters.1634/// The value of `size` must be larger than (4096 *1635/// blocks_per_group.) (default: 16777216)1636/// uid=UID - uid of the mkfs process in the user1637/// namespace created by minijail. (default: 0)1638/// gid=GID - gid of the mkfs process in the user1639/// namespace created by minijail. (default: 0)1640/// uidmap=UIDMAP - a uid map in the format1641/// "inner outer count[,inner outer count]". This format1642/// is same as one for minijail.1643/// (default: "0 <current euid> 1")1644/// gidmap=GIDMAP - a gid map in the same format as uidmap1645/// (default: "0 <current egid> 1")1646pub pmem_ext2: Vec<PmemExt2Option>,16471648#[cfg(feature = "process-invariants")]1649#[argh(option, arg_name = "PATH")]1650/// shared read-only memory address for a serialized EmulatorProcessInvariants proto1651pub process_invariants_handle: Option<u64>,16521653#[cfg(feature = "process-invariants")]1654#[argh(option, arg_name = "PATH")]1655/// size of the serialized EmulatorProcessInvariants proto pointed at by1656/// process-invariants-handle1657pub process_invariants_size: Option<usize>,16581659#[cfg(windows)]1660#[argh(option)]1661/// product channel1662pub product_channel: Option<String>,16631664#[cfg(windows)]1665#[argh(option)]1666/// the product name for file paths.1667pub product_name: Option<String>,16681669#[cfg(windows)]1670#[argh(option)]1671/// product version1672pub product_version: Option<String>,16731674#[argh(switch)]1675/// prevent host access to guest memory1676pub protected_vm: Option<bool>,16771678#[argh(option, arg_name = "PATH")]1679/// (EXPERIMENTAL/FOR DEBUGGING) Use custom VM firmware to run in protected mode1680pub protected_vm_with_firmware: Option<PathBuf>,16811682#[argh(switch)]1683/// (EXPERIMENTAL) prevent host access to guest memory, but don't use protected VM firmware1684protected_vm_without_firmware: Option<bool>,16851686#[argh(option, arg_name = "path=PATH,size=SIZE")]1687/// path to pstore buffer backend file followed by size1688/// [--pstore <path=PATH,size=SIZE>]1689pub pstore: Option<Pstore>,16901691#[cfg(feature = "pvclock")]1692#[argh(switch)]1693/// enable virtio-pvclock.1694/// Only available when crosvm is built with feature 'pvclock'.1695pub pvclock: Option<bool>,16961697#[argh(option, long = "restore", arg_name = "PATH")]1698/// path of the snapshot that is used to restore the VM on startup.1699pub restore: Option<PathBuf>,17001701#[argh(option, arg_name = "PATH[,key=value[,key=value[,...]]]", short = 'r')]1702/// (DEPRECATED): Use --block.1703/// path to a disk image followed by optional comma-separated1704/// options.1705/// Valid keys:1706/// sparse=BOOL - Indicates whether the disk should support1707/// the discard operation (default: true)1708/// block_size=BYTES - Set the reported block size of the1709/// disk (default: 512)1710/// id=STRING - Set the block device identifier to an ASCII1711/// string, up to 20 characters (default: no ID)1712/// o_direct=BOOL - Use O_DIRECT mode to bypass page cache1713root: Option<DiskOptionWithId>,17141715#[argh(option, arg_name = "PATH")]1716/// path to a socket from where to read rotary input events and write status updates to1717pub rotary: Vec<PathBuf>,17181719#[argh(option, arg_name = "CPUSET")]1720/// comma-separated list of CPUs or CPU ranges to run VCPUs on. (e.g. 0,1-3,5) (default: none)1721pub rt_cpus: Option<CpuSet>,17221723#[argh(option, arg_name = "PATH")]1724/// (DEPRECATED): Use --pmem.1725/// path to a writable disk image1726rw_pmem_device: Vec<DiskOption>,17271728#[argh(option, arg_name = "PATH[,key=value[,key=value[,...]]]")]1729/// (DEPRECATED): Use --block.1730/// path to a read-write disk image followed by optional1731/// comma-separated options.1732/// Valid keys:1733/// sparse=BOOL - Indicates whether the disk should support1734/// the discard operation (default: true)1735/// block_size=BYTES - Set the reported block size of the1736/// disk (default: 512)1737/// id=STRING - Set the block device identifier to an ASCII1738/// string, up to 20 characters (default: no ID)1739/// o_direct=BOOL - Use O_DIRECT mode to bypass page cache1740rwdisk: Vec<DiskOptionWithId>,17411742#[argh(option, arg_name = "PATH[,key=value[,key=value[,...]]]")]1743/// (DEPRECATED): Use --block.1744/// path to a read-write root disk image followed by optional1745/// comma-separated options.1746/// Valid keys:1747/// sparse=BOOL - Indicates whether the disk should support1748/// the discard operation (default: true)1749/// block_size=BYTES - Set the reported block size of the1750/// disk (default: 512)1751/// id=STRING - Set the block device identifier to an ASCII1752/// string, up to 20 characters (default: no ID)1753/// o_direct=BOOL - Use O_DIRECT mode to bypass page cache1754rwroot: Option<DiskOptionWithId>,17551756#[cfg(target_arch = "x86_64")]1757#[argh(switch)]1758/// set Low Power S0 Idle Capable Flag for guest Fixed ACPI1759/// Description Table, additionally use enhanced crosvm suspend and resume1760/// routines to perform full guest suspension/resumption1761pub s2idle: Option<bool>,17621763#[argh(option, arg_name = "PATH[,key=value[,key=value[,...]]]")]1764/// (EXPERIMENTAL) parameters for setting up a SCSI disk.1765/// Valid keys:1766/// path=PATH - Path to the disk image. Can be specified1767/// without the key as the first argument.1768/// block_size=BYTES - Set the reported block size of the1769/// disk (default: 512)1770/// ro=BOOL - Whether the block should be read-only.1771/// (default: false)1772/// root=BOOL - Whether the scsi device should be mounted1773/// as the root filesystem. This will add the required1774/// parameters to the kernel command-line. Can only be1775/// specified once. (default: false)1776// TODO(b/300580119): Add O_DIRECT and sparse file support.1777scsi_block: Vec<ScsiOption>,17781779#[cfg(any(target_os = "android", target_os = "linux"))]1780#[argh(switch)]1781/// instead of seccomp filter failures being fatal, they will be logged instead1782pub seccomp_log_failures: Option<bool>,17831784#[cfg(any(target_os = "android", target_os = "linux"))]1785#[argh(option, arg_name = "PATH")]1786/// path to seccomp .policy files1787pub seccomp_policy_dir: Option<PathBuf>,17881789#[argh(1790option,1791arg_name = "type=TYPE,[hardware=HW,name=NAME,num=NUM,path=PATH,input=PATH,console,earlycon,stdin,pci-address=ADDR]",1792from_str_fn(parse_serial_options)1793)]1794/// comma separated key=value pairs for setting up serial1795/// devices. Can be given more than once.1796/// Possible key values:1797/// type=(stdout,syslog,sink,file) - Where to route the1798/// serial device.1799/// Platform-specific options:1800/// On Unix: 'unix' (datagram) and 'unix-stream' (stream)1801/// On Windows: 'namedpipe'1802/// hardware=(serial,virtio-console,debugcon) - Which type of1803/// serial hardware to emulate. Defaults to 8250 UART1804/// (serial).1805/// name=NAME - Console Port Name, used for virtio-console1806/// as a tag for identification within the guest.1807/// num=(1,2,3,4) - Serial Device Number. If not provided,1808/// num will default to 1.1809/// debugcon_port=PORT - Port for the debugcon device to1810/// listen to. Defaults to 0x402, which is what OVMF1811/// expects.1812/// path=PATH - The path to the file to write to when1813/// type=file1814/// input=PATH - The path to the file to read from when not1815/// stdin1816/// input-unix-stream - (Unix-only) Whether to use the given1817/// Unix stream socket for input as well as output.1818/// This flag is only valid when type=unix-stream and1819/// the socket path is specified with path=.1820/// Can't be passed when input is specified.1821/// console - Use this serial device as the guest console.1822/// Will default to first serial port if not provided.1823/// earlycon - Use this serial device as the early console.1824/// Can only be given once.1825/// stdin - Direct standard input to this serial device.1826/// Can only be given once. Will default to first serial1827/// port if not provided.1828/// pci-address - Preferred PCI address, e.g. "00:01.0".1829/// max-queue-sizes=[uint,uint] - Max size of each virtio1830/// queue. Only applicable when hardware=virtio-console.1831pub serial: Vec<SerialParameters>,18321833#[cfg(windows)]1834#[argh(option, arg_name = "PIPE_NAME")]1835/// the service ipc pipe name. (Prefix \\\\.\\pipe\\ not needed.1836pub service_pipe_name: Option<String>,18371838#[cfg(any(target_os = "android", target_os = "linux"))]1839#[argh(1840option,1841arg_name = "PATH:TAG[:type=TYPE:writeback=BOOL:timeout=SECONDS:uidmap=UIDMAP:gidmap=GIDMAP:cache=CACHE:dax=BOOL,posix_acl=BOOL]"1842)]1843/// colon-separated options for configuring a directory to be1844/// shared with the VM. The first field is the directory to be1845/// shared and the second field is the tag that the VM can use1846/// to identify the device. The remaining fields are key=value1847/// pairs that may appear in any order.1848/// Valid keys are:1849/// type=(p9, fs) - Indicates whether the directory should1850/// be shared via virtio-9p or virtio-fs (default: p9).1851/// uidmap=UIDMAP - The uid map to use for the device's1852/// jail in the format "inner outer1853/// count[,inner outer count]"1854/// (default: 0 <current euid> 1).1855/// gidmap=GIDMAP - The gid map to use for the device's1856/// jail in the format "inner outer1857/// count[,inner outer count]"1858/// (default: 0 <current egid> 1).1859/// cache=(never, auto, always) - Indicates whether the VM1860/// can cache the contents of the shared directory1861/// (default: auto). When set to "auto" and the type1862/// is "fs", the VM will use close-to-open consistency1863/// for file contents.1864/// timeout=SECONDS - How long the VM should consider file1865/// attributes and directory entries to be valid1866/// (default: 5). If the VM has exclusive access to the1867/// directory, then this should be a large value. If1868/// the directory can be modified by other processes,1869/// then this should be 0.1870/// writeback=BOOL - Enables writeback caching1871/// (default: false). This is only safe to do when the1872/// VM has exclusive access to the files in a directory.1873/// Additionally, the server should have read1874/// permission for all files as the VM may issue read1875/// requests even for files that are opened write-only.1876/// dax=BOOL - Enables DAX support. Enabling DAX can1877/// improve performance for frequently accessed files1878/// by mapping regions of the file directly into the1879/// VM's memory. There is a cost of slightly increased1880/// latency the first time the file is accessed. Since1881/// the mapping is shared directly from the host kernel's1882/// file cache, enabling DAX can improve performance even1883/// when the guest cache policy is "Never". The default1884/// value for this option is "false".1885/// posix_acl=BOOL - Indicates whether the shared directory1886/// supports POSIX ACLs. This should only be enabled1887/// when the underlying file system supports POSIX ACLs.1888/// The default value for this option is "true".1889/// uid=UID - uid of the device process in the user1890/// namespace created by minijail. (default: 0)1891/// gid=GID - gid of the device process in the user1892/// namespace created by minijail. (default: 0)1893/// max_dynamic_perm=uint - Indicates maximum number of1894/// dynamic permissions that the shared directory allows.1895/// (default: 0). The fuse server will return EPERM1896/// Error when FS_IOC_SETPERMISSION ioctl is called1897/// in the device if current dyamic permission path is1898/// lager or equal to this value.1899/// max_dynamic_xattr=uint - Indicates maximum number of1900/// dynamic xattrs that the shared directory allows.1901/// (default: 0). The fuse server will return EPERM1902/// Error when FS_IOC_SETPATHXATTR ioctl is called1903/// in the device if current dyamic permission path is1904/// lager or equal to this value.1905/// security_ctx=BOOL - Enables FUSE_SECURITY_CONTEXT1906/// feature(default: true). This should be set to false1907/// in case the when the host not allowing write to1908/// /proc/<pid>/attr/fscreate, or guest directory does1909/// not care about the security context.1910/// Options uid and gid are useful when the crosvm process1911/// has no CAP_SETGID/CAP_SETUID but an identity mapping of1912/// the current user/group between the VM and the host is1913/// required. Say the current user and the crosvm process1914/// has uid 5000, a user can use "uid=5000" and1915/// "uidmap=5000 5000 1" such that files owned by user1916/// 5000 still appear to be owned by user 5000 in the VM.1917/// These 2 options are useful only when there is 1 user1918/// in the VM accessing shared files. If multiple users1919/// want to access the shared file, gid/uid options are1920/// useless. It'd be better to create a new user namespace1921/// and give CAP_SETUID/CAP_SETGID to the crosvm.1922pub shared_dir: Vec<SharedDir>,19231924#[cfg(all(unix, feature = "media"))]1925#[argh(switch)]1926/// enable the simple virtio-media device, a virtual capture device generating a fixed pattern1927/// for testing purposes.1928pub simple_media_device: Option<bool>,19291930#[argh(1931option,1932arg_name = "[path=]PATH[,width=WIDTH][,height=HEIGHT][,name=NAME]",1933from_str_fn(parse_touch_device_option)1934)]1935/// path to a socket from where to read single touch input events (such as those from a1936/// touchscreen) and write status updates to, optionally followed by width and height (defaults1937/// to 800x1280) and a name for the input device1938pub single_touch: Vec<TouchDeviceOption>,19391940#[cfg(any(feature = "slirp-ring-capture", feature = "slirp-debug"))]1941#[argh(option, arg_name = "PATH")]1942/// redirects slirp network packets to the supplied log file rather than the current directory1943/// as `slirp_capture_packets.pcap`1944pub slirp_capture_file: Option<String>,19451946#[cfg(target_arch = "x86_64")]1947#[argh(option, arg_name = "key=val,...")]1948/// SMBIOS table configuration (DMI)1949/// The fields are key=value pairs.1950/// Valid keys are:1951/// bios-vendor=STRING - BIOS vendor name.1952/// bios-version=STRING - BIOS version number (free-form string).1953/// manufacturer=STRING - System manufacturer name.1954/// product-name=STRING - System product name.1955/// serial-number=STRING - System serial number.1956/// uuid=UUID - System UUID.1957/// oem-strings=[...] - Free-form OEM strings (SMBIOS type 11).1958pub smbios: Option<SmbiosOptions>,19591960#[cfg(all(1961target_arch = "aarch64",1962any(target_os = "android", target_os = "linux")1963))]1964#[argh(switch)]1965/// expose and emulate support for SMCCC TRNG1966/// (EXPERIMENTAL) entropy generated might not meet ARM DEN0098 nor NIST 800-90B requirements1967pub smccc_trng: Option<bool>,19681969#[argh(option, short = 's', arg_name = "PATH")]1970/// path to put the control socket. If PATH is a directory, a name will be generated1971pub socket: Option<PathBuf>,19721973#[cfg(feature = "audio")]1974#[argh(option, arg_name = "PATH")]1975/// path to the VioS server socket for setting up virtio-snd devices1976pub sound: Option<PathBuf>,19771978#[cfg(target_arch = "x86_64")]1979#[argh(switch)]1980/// (DEPRECATED): Use --irq-chip.1981/// (EXPERIMENTAL) enable split-irqchip support1982pub split_irqchip: Option<bool>,19831984#[argh(1985option,1986arg_name = "DOMAIN:BUS:DEVICE.FUNCTION[,vendor=NUM][,device=NUM][,class=NUM][,subsystem_vendor=NUM][,subsystem_device=NUM][,revision=NUM]"1987)]1988/// comma-separated key=value pairs for setting up a stub PCI1989/// device that just enumerates. The first option in the list1990/// must specify a PCI address to claim.1991/// Optional further parameters1992/// vendor=NUM - PCI vendor ID1993/// device=NUM - PCI device ID1994/// class=NUM - PCI class (including class code, subclass,1995/// and programming interface)1996/// subsystem_vendor=NUM - PCI subsystem vendor ID1997/// subsystem_device=NUM - PCI subsystem device ID1998/// revision=NUM - revision1999pub stub_pci_device: Vec<StubPciParameters>,20002001#[argh(switch)]2002/// start a VM with vCPUs and devices suspended2003pub suspended: Option<bool>,20042005#[argh(option, long = "swap", arg_name = "PATH")]2006/// enable vmm-swap via an unnamed temporary file on the filesystem which contains the2007/// specified directory.2008pub swap_dir: Option<PathBuf>,20092010#[cfg(target_arch = "aarch64")]2011#[argh(option, arg_name = "N")]2012/// (EXPERIMENTAL) Size of virtio swiotlb buffer in MiB (default: 64 if `--protected-vm` or2013/// `--protected-vm-without-firmware` is present)2014pub swiotlb: Option<u64>,20152016#[argh(option, arg_name = "PATH")]2017/// path to a socket from where to read switch input events and write status updates to2018pub switches: Vec<PathBuf>,20192020#[argh(option, arg_name = "TAG")]2021/// (DEPRECATED): Use --syslog-tag before "run".2022/// when logging to syslog, use the provided tag2023pub syslog_tag: Option<String>,20242025#[cfg(any(target_os = "android", target_os = "linux"))]2026#[argh(option)]2027/// (DEPRECATED): Use --net.2028/// file descriptor for configured tap device. A different virtual network card will be added2029/// each time this argument is given2030pub tap_fd: Vec<RawDescriptor>,20312032#[cfg(any(target_os = "android", target_os = "linux"))]2033#[argh(option)]2034/// (DEPRECATED): Use --net.2035/// name of a configured persistent TAP interface to use for networking. A different virtual2036/// network card will be added each time this argument is given2037pub tap_name: Vec<String>,20382039#[cfg(target_os = "android")]2040#[argh(option, arg_name = "NAME[,...]")]2041/// comma-separated names of the task profiles to apply to all threads in crosvm including the2042/// vCPU threads2043pub task_profiles: Vec<String>,20442045#[argh(2046option,2047arg_name = "[path=]PATH[,width=WIDTH][,height=HEIGHT][,name=NAME]",2048from_str_fn(parse_touch_device_option)2049)]2050/// path to a socket from where to read trackpad input events and write status updates to,2051/// optionally followed by screen width and height (defaults to 800x1280) and a name for the2052/// input device2053pub trackpad: Vec<TouchDeviceOption>,20542055#[cfg(any(target_os = "android", target_os = "linux"))]2056#[argh(switch)]2057/// set MADV_DONTFORK on guest memory2058///2059/// Intended for use in combination with --protected-vm, where the guest memory can be2060/// dangerous to access. Some systems, e.g. Android, have tools that fork processes and examine2061/// their memory. This flag effectively hides the guest memory from those tools.2062///2063/// Not compatible with sandboxing.2064pub unmap_guest_memory_on_fork: Option<bool>,20652066// Must be `Some` iff `protection_type == ProtectionType::UnprotectedWithFirmware`.2067#[argh(option, arg_name = "PATH")]2068/// (EXPERIMENTAL/FOR DEBUGGING) Use VM firmware, but allow host access to guest memory2069pub unprotected_vm_with_firmware: Option<PathBuf>,20702071#[cfg(any(target_os = "android", target_os = "linux"))]2072#[cfg(all(unix, feature = "media"))]2073#[argh(option, arg_name = "[device]")]2074/// path to a V4L2 device to expose to the guest using the virtio-media protocol.2075pub v4l2_proxy: Vec<PathBuf>,20762077#[argh(option, arg_name = "PATH")]2078/// move all vCPU threads to this CGroup (default: nothing moves)2079pub vcpu_cgroup_path: Option<PathBuf>,20802081#[cfg(any(target_os = "android", target_os = "linux"))]2082#[argh(2083option,2084arg_name = "PATH[,guest-address=<BUS:DEVICE.FUNCTION>][,iommu=viommu|coiommu|pkvm-iommu|off][,dt-symbol=<SYMBOL>]"2085)]2086/// path to sysfs of VFIO device.2087/// guest-address=<BUS:DEVICE.FUNCTION> - PCI address2088/// that the device will be assigned in the guest.2089/// If not specified, the device will be assigned an2090/// address that mirrors its address in the host.2091/// Only valid for PCI devices.2092/// iommu=viommu|coiommu|pkvm-iommu|off - indicates which type of IOMMU2093/// to use for this device.2094/// dt-symbol=<SYMBOL> - the symbol that labels the device tree2095/// node in the device tree overlay file.2096pub vfio: Vec<VfioOption>,20972098#[cfg(any(target_os = "android", target_os = "linux"))]2099#[argh(switch)]2100/// isolate all hotplugged passthrough vfio device behind virtio-iommu2101pub vfio_isolate_hotplug: Option<bool>,21022103#[cfg(any(target_os = "android", target_os = "linux"))]2104#[argh(option, arg_name = "PATH")]2105/// (DEPRECATED): Use --vfio.2106/// path to sysfs of platform pass through2107pub vfio_platform: Vec<VfioOption>,21082109#[cfg(all(2110target_arch = "aarch64",2111any(target_os = "android", target_os = "linux")2112))]2113#[argh(switch)]2114/// expose the LOW_POWER_ENTRY/EXIT feature of VFIO platform devices to guests, if available2115/// (EXPERIMENTAL) The host kernel may not support the API used by CrosVM2116pub vfio_platform_pm: Option<bool>,21172118#[cfg(any(target_os = "android", target_os = "linux"))]2119#[argh(switch)]2120/// (DEPRECATED): Use --net.2121/// use vhost for networking2122pub vhost_net: Option<bool>,21232124#[cfg(any(target_os = "android", target_os = "linux"))]2125#[argh(option, arg_name = "PATH")]2126/// path to the vhost-net device. (default /dev/vhost-net)2127pub vhost_net_device: Option<PathBuf>,21282129#[cfg(any(target_os = "android", target_os = "linux"))]2130#[cfg(target_arch = "aarch64")]2131#[argh(switch)]2132/// use vhost for scmi2133pub vhost_scmi: Option<bool>,21342135#[argh(2136option,2137arg_name = "[type=]TYPE,socket=SOCKET_PATH[,max-queue-size=NUM][,pci-address=ADDR]"2138)]2139/// comma separated key=value pairs for connecting to a2140/// vhost-user backend.2141/// Possible key values:2142/// type=TYPE - Virtio device type (net, block, etc.)2143/// socket=SOCKET_PATH - Path to vhost-user socket.2144/// max-queue-size=NUM - Limit maximum queue size (must be a power of two).2145/// pci-address=ADDR - Preferred PCI address, e.g. "00:01.0".2146pub vhost_user: Vec<VhostUserFrontendOption>,21472148#[argh(option)]2149/// number of milliseconds to retry if the socket path is missing or has no listener. Defaults2150/// to no retries.2151pub vhost_user_connect_timeout_ms: Option<u64>,21522153#[cfg(any(target_os = "android", target_os = "linux"))]2154#[argh(option, arg_name = "SOCKET_PATH")]2155/// (DEPRECATED): Use --vsock.2156/// path to the vhost-vsock device. (default /dev/vhost-vsock)2157pub vhost_vsock_device: Option<PathBuf>,21582159#[cfg(any(target_os = "android", target_os = "linux"))]2160#[argh(option, arg_name = "FD")]2161/// (DEPRECATED): Use --vsock.2162/// open FD to the vhost-vsock device, mutually exclusive with vhost-vsock-device2163pub vhost_vsock_fd: Option<RawDescriptor>,21642165#[cfg(feature = "video-decoder")]2166#[argh(option, arg_name = "[backend]")]2167/// (EXPERIMENTAL) enable virtio-video decoder device2168/// Possible backend values: libvda, ffmpeg, vaapi2169pub video_decoder: Vec<VideoDeviceConfig>,21702171#[cfg(feature = "video-encoder")]2172#[argh(option, arg_name = "[backend]")]2173/// (EXPERIMENTAL) enable virtio-video encoder device2174/// Possible backend values: libvda2175pub video_encoder: Vec<VideoDeviceConfig>,21762177#[cfg(all(2178target_arch = "aarch64",2179any(target_os = "android", target_os = "linux")2180))]2181#[argh(switch)]2182/// enable a virtual cpu freq device2183pub virt_cpufreq: Option<bool>,21842185#[cfg(all(2186target_arch = "aarch64",2187any(target_os = "android", target_os = "linux")2188))]2189#[argh(switch)]2190/// enable version of the virtual cpu freq device compatible2191/// with the driver in upstream linux2192pub virt_cpufreq_upstream: Option<bool>,21932194#[cfg(feature = "audio")]2195#[argh(2196option,2197arg_name = "[capture=true,backend=BACKEND,num_output_devices=1,\2198num_input_devices=1,num_output_streams=1,num_input_streams=1]"2199)]2200/// comma separated key=value pairs for setting up virtio snd2201/// devices.2202/// Possible key values:2203/// capture=(false,true) - Disable/enable audio capture.2204/// Default is false.2205/// backend=(null,file,[cras]) - Which backend to use for2206/// virtio-snd.2207/// client_type=(crosvm,arcvm,borealis) - Set specific2208/// client type for cras backend. Default is crosvm.2209/// socket_type=(legacy,unified) Set specific socket type2210/// for cras backend. Default is unified.2211/// playback_path=STR - Set directory of output streams2212/// for file backend.2213/// playback_size=INT - Set size of the output streams2214/// from file backend.2215/// num_output_devices=INT - Set number of output PCM2216/// devices.2217/// num_input_devices=INT - Set number of input PCM devices.2218/// num_output_streams=INT - Set number of output PCM2219/// streams per device.2220/// num_input_streams=INT - Set number of input PCM streams2221/// per device.2222pub virtio_snd: Vec<SndParameters>,22232224#[argh(option, arg_name = "cid=CID[,device=VHOST_DEVICE]")]2225/// add a vsock device. Since a guest can only have one CID,2226/// this option can only be specified once.2227/// cid=CID - CID to use for the device.2228/// device=VHOST_DEVICE - path to the vhost-vsock device to2229/// use (Linux only). Defaults to /dev/vhost-vsock.2230/// max-queue-sizes=[uint,uint,uint] - Max size of each2231/// virtio queue.2232pub vsock: Option<VsockConfig>,22332234#[cfg(feature = "vtpm")]2235#[argh(switch)]2236/// enable the virtio-tpm connection to vtpm daemon2237pub vtpm_proxy: Option<bool>,22382239#[cfg(any(target_os = "android", target_os = "linux"))]2240#[argh(option, arg_name = "PATH[,name=NAME]", from_str_fn(parse_wayland_sock))]2241/// path to the Wayland socket to use. The unnamed one is used for displaying virtual screens.2242/// Named ones are only for IPC2243pub wayland_sock: Vec<(String, PathBuf)>,22442245#[cfg(any(target_os = "android", target_os = "linux"))]2246#[argh(option, arg_name = "DISPLAY")]2247/// X11 display name to use2248pub x_display: Option<String>,2249}22502251impl TryFrom<RunCommand> for super::config::Config {2252type Error = String;22532254fn try_from(cmd: RunCommand) -> Result<Self, Self::Error> {2255let mut cfg = Self::default();2256// TODO: we need to factor out some(?) of the checks into config::validate_config22572258// Process arguments2259if let Some(p) = cmd.kernel {2260cfg.executable_path = Some(Executable::Kernel(p));2261}22622263#[cfg(any(target_os = "android", target_os = "linux"))]2264if let Some(p) = cmd.kvm_device {2265log::warn!(2266"`--kvm-device <PATH>` is deprecated; use `--hypervisor kvm[device=<PATH>]` instead"2267);22682269if cmd.hypervisor.is_some() {2270return Err("cannot specify both --hypervisor and --kvm-device".to_string());2271}22722273cfg.hypervisor = Some(crate::crosvm::config::HypervisorKind::Kvm { device: Some(p) });2274}22752276cfg.android_fstab = cmd.android_fstab;22772278cfg.async_executor = cmd.async_executor;22792280#[cfg(target_arch = "x86_64")]2281if let Some(p) = cmd.bus_lock_ratelimit {2282cfg.bus_lock_ratelimit = p;2283}22842285cfg.params.extend(cmd.params);22862287cfg.core_scheduling = cmd.core_scheduling;2288cfg.per_vm_core_scheduling = cmd.per_vm_core_scheduling.unwrap_or_default();22892290// `--cpu` parameters.2291{2292let cpus = cmd.cpus.unwrap_or_default();2293cfg.vcpu_count = cpus.num_cores;2294cfg.boot_cpu = cpus.boot_cpu.unwrap_or_default();2295cfg.cpu_freq_domains = cpus.freq_domains;22962297// Only allow deprecated `--cpu-cluster` option only if `--cpu clusters=[...]` is not2298// used.2299cfg.cpu_clusters = match (&cpus.clusters.is_empty(), &cmd.cpu_cluster.is_empty()) {2300(_, true) => cpus.clusters,2301(true, false) => cmd.cpu_cluster,2302(false, false) => {2303return Err(2304"cannot specify both --cpu clusters=[...] and --cpu_cluster".to_string()2305)2306}2307};23082309#[cfg(target_arch = "x86_64")]2310if let Some(cpu_types) = cpus.core_types {2311for cpu in cpu_types.atom {2312if cfg2313.vcpu_hybrid_type2314.insert(cpu, CpuHybridType::Atom)2315.is_some()2316{2317return Err(format!("vCPU index must be unique {cpu}"));2318}2319}2320for cpu in cpu_types.core {2321if cfg2322.vcpu_hybrid_type2323.insert(cpu, CpuHybridType::Core)2324.is_some()2325{2326return Err(format!("vCPU index must be unique {cpu}"));2327}2328}2329}2330#[cfg(target_arch = "aarch64")]2331{2332cfg.sve = cpus.sve;2333}2334}23352336cfg.vcpu_affinity = cmd.cpu_affinity;23372338if let Some(dynamic_power_coefficient) = cmd.dynamic_power_coefficient {2339cfg.dynamic_power_coefficient = dynamic_power_coefficient;2340}23412342if let Some(capacity) = cmd.cpu_capacity {2343cfg.cpu_capacity = capacity;2344}23452346#[cfg(all(2347target_arch = "aarch64",2348any(target_os = "android", target_os = "linux")2349))]2350{2351cfg.smccc_trng = cmd.smccc_trng.unwrap_or_default();2352cfg.vfio_platform_pm = cmd.vfio_platform_pm.unwrap_or_default();2353cfg.virt_cpufreq = cmd.virt_cpufreq.unwrap_or_default();2354cfg.virt_cpufreq_v2 = cmd.virt_cpufreq_upstream.unwrap_or_default();2355if cfg.virt_cpufreq && cfg.virt_cpufreq_v2 {2356return Err("Only one version of virt-cpufreq can be used!".to_string());2357}2358if let Some(frequencies) = cmd.cpu_frequencies_khz {2359cfg.cpu_frequencies_khz = frequencies;2360}2361if let Some(ipc_ratio) = cmd.cpu_ipc_ratio {2362cfg.cpu_ipc_ratio = ipc_ratio;2363}2364}23652366cfg.vcpu_cgroup_path = cmd.vcpu_cgroup_path;23672368cfg.no_smt = cmd.no_smt.unwrap_or_default();23692370if let Some(rt_cpus) = cmd.rt_cpus {2371cfg.rt_cpus = rt_cpus;2372}23732374cfg.delay_rt = cmd.delay_rt.unwrap_or_default();23752376let mem = cmd.mem.unwrap_or_default();2377cfg.memory = mem.size;23782379#[cfg(target_arch = "aarch64")]2380{2381if cmd.mte.unwrap_or_default()2382&& !(cmd.pmem.is_empty()2383&& cmd.pmem_device.is_empty()2384&& cmd.pstore.is_none()2385&& cmd.rw_pmem_device.is_empty())2386{2387return Err(2388"--mte cannot be specified together with --pstore or pmem flags".to_string(),2389);2390}2391cfg.mte = cmd.mte.unwrap_or_default();2392cfg.no_pmu = cmd.no_pmu.unwrap_or_default();2393cfg.swiotlb = cmd.swiotlb;2394}23952396#[cfg(all(target_os = "android", target_arch = "aarch64"))]2397{2398cfg.ffa = cmd.ffa;2399cfg.dev_pm = cmd.dev_pm;2400}24012402cfg.hugepages = cmd.hugepages.unwrap_or_default();24032404// `cfg.hypervisor` may have been set by the deprecated `--kvm-device` option above.2405// TODO(b/274817652): remove this workaround when `--kvm-device` is removed.2406if cfg.hypervisor.is_none() {2407cfg.hypervisor = cmd.hypervisor;2408}24092410#[cfg(any(target_os = "android", target_os = "linux"))]2411{2412cfg.lock_guest_memory = cmd.lock_guest_memory.unwrap_or_default();2413cfg.boost_uclamp = cmd.boost_uclamp.unwrap_or_default();2414}24152416#[cfg(feature = "audio")]2417{2418cfg.sound = cmd.sound;2419}24202421for serial_params in cmd.serial {2422super::sys::config::check_serial_params(&serial_params)?;24232424let num = serial_params.num;2425let key = (serial_params.hardware, num);24262427if cfg.serial_parameters.contains_key(&key) {2428return Err(format!(2429"serial hardware {} num {}",2430serial_params.hardware, num,2431));2432}24332434if serial_params.earlycon {2435// Only SerialHardware::Serial supports earlycon= currently.2436match serial_params.hardware {2437SerialHardware::Serial => {}2438_ => {2439return Err(super::config::invalid_value_err(2440serial_params.hardware.to_string(),2441String::from("earlycon not supported for hardware"),2442));2443}2444}2445for params in cfg.serial_parameters.values() {2446if params.earlycon {2447return Err(format!(2448"{} device {} already set as earlycon",2449params.hardware, params.num,2450));2451}2452}2453}24542455if serial_params.stdin {2456if let Some(previous_stdin) = cfg.serial_parameters.values().find(|sp| sp.stdin) {2457return Err(format!(2458"{} device {} already connected to standard input",2459previous_stdin.hardware, previous_stdin.num,2460));2461}2462}24632464cfg.serial_parameters.insert(key, serial_params);2465}24662467if !(cmd.root.is_none()2468&& cmd.rwroot.is_none()2469&& cmd.disk.is_empty()2470&& cmd.rwdisk.is_empty())2471{2472log::warn!("Deprecated disk flags such as --[rw]disk or --[rw]root are passed. Use --block instead.");2473}2474// Aggregate all the disks with the expected read-only and root values according to the2475// option they have been passed with.2476let mut disks = cmd2477.root2478.into_iter()2479.map(|mut d| {2480d.disk_option.read_only = true;2481d.disk_option.root = true;2482d2483})2484.chain(cmd.rwroot.into_iter().map(|mut d| {2485d.disk_option.read_only = false;2486d.disk_option.root = true;2487d2488}))2489.chain(cmd.disk.into_iter().map(|mut d| {2490d.disk_option.read_only = true;2491d.disk_option.root = false;2492d2493}))2494.chain(cmd.rwdisk.into_iter().map(|mut d| {2495d.disk_option.read_only = false;2496d.disk_option.root = false;2497d2498}))2499.chain(cmd.block)2500.collect::<Vec<_>>();25012502// Sort all our disks by index.2503disks.sort_by_key(|d| d.index);2504cfg.disks = disks.into_iter().map(|d| d.disk_option).collect();25052506cfg.scsis = cmd.scsi_block;25072508cfg.pmems = cmd.pmem;25092510if !cmd.pmem_device.is_empty() || !cmd.rw_pmem_device.is_empty() {2511log::warn!(2512"--pmem-device and --rw-pmem-device are deprecated. Please use --pmem instead."2513);2514}25152516// Convert the deprecated `pmem_device` and `rw_pmem_device` into `pmem_devices`.2517for disk_option in cmd.pmem_device.into_iter() {2518cfg.pmems.push(PmemOption {2519path: disk_option.path,2520ro: true, // read-only2521..PmemOption::default()2522});2523}2524for disk_option in cmd.rw_pmem_device.into_iter() {2525cfg.pmems.push(PmemOption {2526path: disk_option.path,2527ro: false, // writable2528..PmemOption::default()2529});2530}25312532// Find the device to use as the kernel `root=` parameter. There can only be one.2533let virtio_blk_root_devs = cfg2534.disks2535.iter()2536.enumerate()2537.filter(|(_, d)| d.root)2538.map(|(i, d)| (format_disk_letter("/dev/vd", i), d.read_only));25392540let virtio_scsi_root_devs = cfg2541.scsis2542.iter()2543.enumerate()2544.filter(|(_, s)| s.root)2545.map(|(i, s)| (format_disk_letter("/dev/sd", i), s.read_only));25462547let virtio_pmem_root_devs = cfg2548.pmems2549.iter()2550.enumerate()2551.filter(|(_, p)| p.root)2552.map(|(i, p)| (format!("/dev/pmem{i}"), p.ro));25532554let mut root_devs = virtio_blk_root_devs2555.chain(virtio_scsi_root_devs)2556.chain(virtio_pmem_root_devs);2557if let Some((root_dev, read_only)) = root_devs.next() {2558cfg.params.push(format!(2559"root={} {}",2560root_dev,2561if read_only { "ro" } else { "rw" }2562));25632564// If the iterator is not exhausted, the user specified `root=true` on more than one2565// device, which is an error.2566if root_devs.next().is_some() {2567return Err("only one root disk can be specified".to_string());2568}2569}25702571#[cfg(any(target_os = "android", target_os = "linux"))]2572{2573cfg.pmem_ext2 = cmd.pmem_ext2;2574}25752576#[cfg(feature = "pvclock")]2577{2578cfg.pvclock = cmd.pvclock.unwrap_or_default();2579}25802581#[cfg(windows)]2582{2583#[cfg(feature = "crash-report")]2584{2585cfg.crash_pipe_name = cmd.crash_pipe_name;2586}2587cfg.product_name = cmd.product_name;2588cfg.exit_stats = cmd.exit_stats.unwrap_or_default();2589cfg.host_guid = cmd.host_guid;2590cfg.kernel_log_file = cmd.kernel_log_file;2591cfg.log_file = cmd.log_file;2592cfg.logs_directory = cmd.logs_directory;2593#[cfg(feature = "process-invariants")]2594{2595cfg.process_invariants_data_handle = cmd.process_invariants_handle;25962597cfg.process_invariants_data_size = cmd.process_invariants_size;2598}2599#[cfg(windows)]2600{2601cfg.service_pipe_name = cmd.service_pipe_name;2602}2603#[cfg(any(feature = "slirp-ring-capture", feature = "slirp-debug"))]2604{2605cfg.slirp_capture_file = cmd.slirp_capture_file;2606}2607cfg.product_channel = cmd.product_channel;2608cfg.product_version = cmd.product_version;2609}2610cfg.pstore = cmd.pstore;26112612cfg.enable_fw_cfg = cmd.enable_fw_cfg.unwrap_or_default();2613cfg.fw_cfg_parameters = cmd.fw_cfg;26142615#[cfg(any(target_os = "android", target_os = "linux"))]2616for (name, params) in cmd.wayland_sock {2617if cfg.wayland_socket_paths.contains_key(&name) {2618return Err(format!("wayland socket name already used: '{name}'"));2619}2620cfg.wayland_socket_paths.insert(name, params);2621}26222623#[cfg(any(target_os = "android", target_os = "linux"))]2624{2625cfg.x_display = cmd.x_display;2626}26272628cfg.display_window_keyboard = cmd.display_window_keyboard.unwrap_or_default();2629cfg.display_window_mouse = cmd.display_window_mouse.unwrap_or_default();26302631cfg.swap_dir = cmd.swap_dir;2632cfg.restore_path = cmd.restore;2633cfg.suspended = cmd.suspended.unwrap_or_default();26342635if let Some(mut socket_path) = cmd.socket {2636if socket_path.is_dir() {2637socket_path.push(format!("crosvm-{}.sock", getpid()));2638}2639cfg.socket_path = Some(socket_path);2640}26412642cfg.vsock = cmd.vsock;26432644// Legacy vsock options.2645if let Some(cid) = cmd.cid {2646if cfg.vsock.is_some() {2647return Err(2648"`cid` and `vsock` cannot be specified together. Use `vsock` only.".to_string(),2649);2650}26512652let legacy_vsock_config = VsockConfig::new(2653cid,2654#[cfg(any(target_os = "android", target_os = "linux"))]2655match (cmd.vhost_vsock_device, cmd.vhost_vsock_fd) {2656(Some(_), Some(_)) => {2657return Err(2658"Only one of vhost-vsock-device vhost-vsock-fd has to be specified"2659.to_string(),2660)2661}2662(Some(path), None) => Some(path),2663(None, Some(fd)) => Some(PathBuf::from(format!("/proc/self/fd/{fd}"))),2664(None, None) => None,2665},2666);26672668cfg.vsock = Some(legacy_vsock_config);2669}26702671#[cfg(any(target_os = "android", target_os = "linux"))]2672#[cfg(target_arch = "aarch64")]2673{2674cfg.vhost_scmi = cmd.vhost_scmi.unwrap_or_default();2675}26762677#[cfg(feature = "vtpm")]2678{2679cfg.vtpm_proxy = cmd.vtpm_proxy.unwrap_or_default();2680}26812682cfg.virtio_input = cmd.input;26832684if !cmd.single_touch.is_empty() {2685log::warn!("`--single-touch` is deprecated; please use `--input single-touch[...]`");2686cfg.virtio_input2687.extend(2688cmd.single_touch2689.into_iter()2690.map(|touch| InputDeviceOption::SingleTouch {2691path: touch.path,2692width: touch.width,2693height: touch.height,2694name: touch.name,2695}),2696);2697}26982699if !cmd.multi_touch.is_empty() {2700log::warn!("`--multi-touch` is deprecated; please use `--input multi-touch[...]`");2701cfg.virtio_input2702.extend(2703cmd.multi_touch2704.into_iter()2705.map(|touch| InputDeviceOption::MultiTouch {2706path: touch.path,2707width: touch.width,2708height: touch.height,2709name: touch.name,2710}),2711);2712}27132714if !cmd.trackpad.is_empty() {2715log::warn!("`--trackpad` is deprecated; please use `--input trackpad[...]`");2716cfg.virtio_input2717.extend(2718cmd.trackpad2719.into_iter()2720.map(|trackpad| InputDeviceOption::Trackpad {2721path: trackpad.path,2722width: trackpad.width,2723height: trackpad.height,2724name: trackpad.name,2725}),2726);2727}27282729if !cmd.mouse.is_empty() {2730log::warn!("`--mouse` is deprecated; please use `--input mouse[...]`");2731cfg.virtio_input.extend(2732cmd.mouse2733.into_iter()2734.map(|path| InputDeviceOption::Mouse { path }),2735);2736}27372738if !cmd.keyboard.is_empty() {2739log::warn!("`--keyboard` is deprecated; please use `--input keyboard[...]`");2740cfg.virtio_input.extend(2741cmd.keyboard2742.into_iter()2743.map(|path| InputDeviceOption::Keyboard { path }),2744)2745}27462747if !cmd.switches.is_empty() {2748log::warn!("`--switches` is deprecated; please use `--input switches[...]`");2749cfg.virtio_input.extend(2750cmd.switches2751.into_iter()2752.map(|path| InputDeviceOption::Switches { path }),2753);2754}27552756if !cmd.rotary.is_empty() {2757log::warn!("`--rotary` is deprecated; please use `--input rotary[...]`");2758cfg.virtio_input.extend(2759cmd.rotary2760.into_iter()2761.map(|path| InputDeviceOption::Rotary { path }),2762);2763}27642765if !cmd.evdev.is_empty() {2766log::warn!("`--evdev` is deprecated; please use `--input evdev[...]`");2767cfg.virtio_input.extend(2768cmd.evdev2769.into_iter()2770.map(|path| InputDeviceOption::Evdev { path }),2771);2772}27732774cfg.irq_chip = cmd.irqchip;27752776#[cfg(target_arch = "x86_64")]2777if cmd.split_irqchip.unwrap_or_default() {2778if cmd.irqchip.is_some() {2779return Err("cannot use `--irqchip` and `--split-irqchip` together".to_string());2780}27812782log::warn!("`--split-irqchip` is deprecated; please use `--irqchip=split`");2783cfg.irq_chip = Some(IrqChipKind::Split);2784}27852786cfg.initrd_path = cmd.initrd;27872788if let Some(p) = cmd.bios {2789if cfg.executable_path.is_some() {2790return Err(format!(2791"A VM executable was already specified: {:?}",2792cfg.executable_path2793));2794}2795cfg.executable_path = Some(Executable::Bios(p));2796}2797cfg.pflash_parameters = cmd.pflash;27982799#[cfg(feature = "video-decoder")]2800{2801cfg.video_dec = cmd.video_decoder;2802}2803#[cfg(feature = "video-encoder")]2804{2805cfg.video_enc = cmd.video_encoder;2806}28072808cfg.acpi_tables = cmd.acpi_table;28092810cfg.usb = !cmd.no_usb.unwrap_or_default();2811cfg.rng = !cmd.no_rng.unwrap_or_default();28122813#[cfg(feature = "balloon")]2814{2815cfg.balloon = !cmd.no_balloon.unwrap_or_default();28162817// cfg.balloon_bias is in bytes.2818if let Some(b) = cmd.balloon_bias_mib {2819cfg.balloon_bias = b * 1024 * 1024;2820}28212822cfg.balloon_control = cmd.balloon_control;2823cfg.balloon_page_reporting = cmd.balloon_page_reporting.unwrap_or_default();2824cfg.balloon_ws_num_bins = cmd.balloon_ws_num_bins.unwrap_or(4);2825cfg.balloon_ws_reporting = cmd.balloon_ws_reporting.unwrap_or_default();2826cfg.init_memory = cmd.init_mem;2827}28282829#[cfg(feature = "audio")]2830{2831cfg.virtio_snds = cmd.virtio_snd;2832}28332834#[cfg(feature = "gpu")]2835{2836// Due to the resource bridge, we can only create a single GPU device at the moment.2837if cmd.gpu.len() > 1 {2838return Err("at most one GPU device can currently be created".to_string());2839}2840cfg.gpu_parameters = cmd.gpu.into_iter().map(|p| p.0).take(1).next();2841if !cmd.gpu_display.is_empty() {2842log::warn!("'--gpu-display' is deprecated; please use `--gpu displays=[...]`");2843cfg.gpu_parameters2844.get_or_insert_with(Default::default)2845.display_params2846.extend(cmd.gpu_display);2847}28482849#[cfg(feature = "android_display")]2850{2851if let Some(gpu_parameters) = &cfg.gpu_parameters {2852if !gpu_parameters.display_params.is_empty() {2853cfg.android_display_service = cmd.android_display_service;2854}2855}2856}28572858#[cfg(windows)]2859if let Some(gpu_parameters) = &cfg.gpu_parameters {2860let num_displays = gpu_parameters.display_params.len();2861if num_displays > 1 {2862return Err(format!(2863"Only one display is supported (supplied {num_displays})"2864));2865}2866}28672868#[cfg(any(target_os = "android", target_os = "linux"))]2869{2870cfg.gpu_cgroup_path = cmd.gpu_cgroup_path;2871cfg.gpu_server_cgroup_path = cmd.gpu_server_cgroup_path;2872}2873}28742875#[cfg(all(unix, feature = "net"))]2876{2877use devices::virtio::VhostNetParameters;2878use devices::virtio::VHOST_NET_DEFAULT_PATH;28792880cfg.net = cmd.net;28812882if let Some(vhost_net_device) = &cmd.vhost_net_device {2883let vhost_net_path = vhost_net_device.to_string_lossy();2884log::warn!(2885"`--vhost-net-device` is deprecated; please use \2886`--net ...,vhost-net=[device={vhost_net_path}]`"2887);2888}28892890let vhost_net_config = if cmd.vhost_net.unwrap_or_default() {2891Some(VhostNetParameters {2892device: cmd2893.vhost_net_device2894.unwrap_or_else(|| PathBuf::from(VHOST_NET_DEFAULT_PATH)),2895})2896} else {2897None2898};28992900let vhost_net_msg = match cmd.vhost_net.unwrap_or_default() {2901true => ",vhost-net=true",2902false => "",2903};2904let vq_pairs_msg = match cmd.net_vq_pairs {2905Some(n) => format!(",vq-pairs={n}"),2906None => "".to_string(),2907};29082909for tap_name in cmd.tap_name {2910log::warn!(2911"`--tap-name` is deprecated; please use \2912`--net tap-name={tap_name}{vhost_net_msg}{vq_pairs_msg}`"2913);2914cfg.net.push(NetParameters {2915mode: NetParametersMode::TapName {2916tap_name,2917mac: None,2918},2919vhost_net: vhost_net_config.clone(),2920vq_pairs: cmd.net_vq_pairs,2921packed_queue: false,2922pci_address: None,2923mrg_rxbuf: false,2924});2925}29262927for tap_fd in cmd.tap_fd {2928log::warn!(2929"`--tap-fd` is deprecated; please use \2930`--net tap-fd={tap_fd}{vhost_net_msg}{vq_pairs_msg}`"2931);2932cfg.net.push(NetParameters {2933mode: NetParametersMode::TapFd { tap_fd, mac: None },2934vhost_net: vhost_net_config.clone(),2935vq_pairs: cmd.net_vq_pairs,2936packed_queue: false,2937pci_address: None,2938mrg_rxbuf: false,2939});2940}29412942if cmd.host_ip.is_some() || cmd.netmask.is_some() || cmd.mac_address.is_some() {2943let host_ip = match cmd.host_ip {2944Some(host_ip) => host_ip,2945None => return Err("`host-ip` missing from network config".to_string()),2946};2947let netmask = match cmd.netmask {2948Some(netmask) => netmask,2949None => return Err("`netmask` missing from network config".to_string()),2950};2951let mac = match cmd.mac_address {2952Some(mac) => mac,2953None => return Err("`mac` missing from network config".to_string()),2954};29552956log::warn!(2957"`--host-ip`, `--netmask`, and `--mac` are deprecated; please use \2958`--net host-ip={host_ip},netmask={netmask},mac={mac}{vhost_net_msg}{vq_pairs_msg}`"2959);29602961cfg.net.push(NetParameters {2962mode: NetParametersMode::RawConfig {2963host_ip,2964netmask,2965mac,2966},2967vhost_net: vhost_net_config,2968vq_pairs: cmd.net_vq_pairs,2969packed_queue: false,2970pci_address: None,2971mrg_rxbuf: false,2972});2973}29742975// The number of vq pairs on a network device shall never exceed the number of vcpu2976// cores. Fix that up if needed.2977for net in &mut cfg.net {2978if let Some(vq_pairs) = net.vq_pairs {2979if vq_pairs as usize > cfg.vcpu_count.unwrap_or(1) {2980log::warn!("the number of net vq pairs must not exceed the vcpu count, falling back to single queue mode");2981net.vq_pairs = None;2982}2983}2984if net.mrg_rxbuf && net.packed_queue {2985return Err("mrg_rxbuf and packed_queue together is unsupported".to_string());2986}2987}2988}29892990#[cfg(any(target_os = "android", target_os = "linux"))]2991{2992cfg.shared_dirs = cmd.shared_dir;29932994cfg.coiommu_param = cmd.coiommu;29952996#[cfg(feature = "gpu")]2997{2998cfg.gpu_render_server_parameters = cmd.gpu_render_server;2999}30003001if let Some(d) = cmd.seccomp_policy_dir {3002cfg.jail_config3003.get_or_insert_with(Default::default)3004.seccomp_policy_dir = Some(d);3005}30063007if cmd.seccomp_log_failures.unwrap_or_default() {3008cfg.jail_config3009.get_or_insert_with(Default::default)3010.seccomp_log_failures = true;3011}30123013if let Some(p) = cmd.pivot_root {3014cfg.jail_config3015.get_or_insert_with(Default::default)3016.pivot_root = p;3017}3018}30193020let protection_flags = [3021cmd.protected_vm.unwrap_or_default(),3022cmd.protected_vm_with_firmware.is_some(),3023cmd.protected_vm_without_firmware.unwrap_or_default(),3024cmd.unprotected_vm_with_firmware.is_some(),3025];30263027if protection_flags.into_iter().filter(|b| *b).count() > 1 {3028return Err("Only one protection mode has to be specified".to_string());3029}30303031cfg.protection_type = if cmd.protected_vm.unwrap_or_default() {3032ProtectionType::Protected3033} else if cmd.protected_vm_without_firmware.unwrap_or_default() {3034ProtectionType::ProtectedWithoutFirmware3035} else if let Some(p) = cmd.protected_vm_with_firmware {3036if !p.exists() || !p.is_file() {3037return Err(3038"protected-vm-with-firmware path should be an existing file".to_string()3039);3040}3041cfg.pvm_fw = Some(p);3042ProtectionType::ProtectedWithCustomFirmware3043} else if let Some(p) = cmd.unprotected_vm_with_firmware {3044if !p.exists() || !p.is_file() {3045return Err(3046"unprotected-vm-with-firmware path should be an existing file".to_string(),3047);3048}3049cfg.pvm_fw = Some(p);3050ProtectionType::UnprotectedWithFirmware3051} else {3052ProtectionType::Unprotected3053};30543055if !matches!(cfg.protection_type, ProtectionType::Unprotected) {3056// USB devices only work for unprotected VMs.3057cfg.usb = false;3058// Protected VMs can't trust the RNG device, so don't provide it.3059cfg.rng = false;3060}30613062cfg.battery_config = cmd.battery;3063#[cfg(all(target_arch = "x86_64", unix))]3064{3065cfg.ac_adapter = cmd.ac_adapter.unwrap_or_default();3066}30673068#[cfg(feature = "gdb")]3069{3070if cfg.suspended && cmd.gdb.is_some() {3071return Err("suspended mode not supported with GDB".to_string());3072}3073cfg.gdb = cmd.gdb;3074}30753076cfg.host_cpu_topology = cmd.host_cpu_topology.unwrap_or_default();30773078cfg.pci_config = cmd.pci.unwrap_or_default();30793080#[cfg(target_arch = "x86_64")]3081{3082cfg.break_linux_pci_config_io = cmd.break_linux_pci_config_io.unwrap_or_default();3083cfg.enable_hwp = cmd.enable_hwp.unwrap_or_default();3084cfg.force_s2idle = cmd.s2idle.unwrap_or_default();3085cfg.no_i8042 = cmd.no_i8042.unwrap_or_default();3086cfg.no_rtc = cmd.no_rtc.unwrap_or_default();3087cfg.smbios = cmd.smbios.unwrap_or_default();30883089if let Some(pci_start) = cmd.pci_start {3090if cfg.pci_config.mem.is_some() {3091return Err("--pci-start cannot be used with --pci mem=[...]".to_string());3092}3093log::warn!("`--pci-start` is deprecated; use `--pci mem=[start={pci_start:#?}]");3094cfg.pci_config.mem = Some(MemoryRegionConfig {3095start: pci_start,3096size: None,3097});3098}30993100if !cmd.oem_strings.is_empty() {3101log::warn!(3102"`--oem-strings` is deprecated; use `--smbios oem-strings=[...]` instead."3103);3104cfg.smbios.oem_strings.extend_from_slice(&cmd.oem_strings);3105}3106}31073108#[cfg(feature = "pci-hotplug")]3109{3110cfg.pci_hotplug_slots = cmd.pci_hotplug_slots;3111}31123113cfg.vhost_user = cmd.vhost_user;31143115cfg.vhost_user_connect_timeout_ms = cmd.vhost_user_connect_timeout_ms;31163117cfg.disable_virtio_intx = cmd.disable_virtio_intx.unwrap_or_default();31183119cfg.dump_device_tree_blob = cmd.dump_device_tree_blob;31203121cfg.itmt = cmd.itmt.unwrap_or_default();31223123#[cfg(target_arch = "x86_64")]3124{3125cfg.force_calibrated_tsc_leaf = cmd.force_calibrated_tsc_leaf.unwrap_or_default();3126}31273128cfg.force_disable_readonly_mem = cmd.force_disable_readonly_mem;31293130cfg.stub_pci_devices = cmd.stub_pci_device;31313132cfg.fdt_position = cmd.fdt_position;31333134#[cfg(any(target_os = "android", target_os = "linux"))]3135#[cfg(all(unix, feature = "media"))]3136{3137cfg.v4l2_proxy = cmd.v4l2_proxy;3138cfg.simple_media_device = cmd.simple_media_device.unwrap_or_default();3139}31403141#[cfg(all(unix, feature = "media", feature = "video-decoder"))]3142{3143cfg.media_decoder = cmd.media_decoder;3144}31453146(cfg.file_backed_mappings_ram, cfg.file_backed_mappings_mmio) =3147cmd.file_backed_mapping.into_iter().partition(|x| x.ram);31483149#[cfg(target_os = "android")]3150{3151cfg.task_profiles = cmd.task_profiles;3152}31533154#[cfg(any(target_os = "android", target_os = "linux"))]3155{3156if cmd.unmap_guest_memory_on_fork.unwrap_or_default()3157&& !cmd.disable_sandbox.unwrap_or_default()3158{3159return Err("--unmap-guest-memory-on-fork requires --disable-sandbox".to_string());3160}3161cfg.unmap_guest_memory_on_fork = cmd.unmap_guest_memory_on_fork.unwrap_or_default();3162}31633164#[cfg(any(target_os = "android", target_os = "linux"))]3165{3166cfg.vfio.extend(cmd.vfio);3167cfg.vfio.extend(cmd.vfio_platform);3168cfg.vfio_isolate_hotplug = cmd.vfio_isolate_hotplug.unwrap_or_default();3169}31703171cfg.device_tree_overlay = cmd.device_tree_overlay;3172#[cfg(any(target_os = "android", target_os = "linux"))]3173{3174if cfg.device_tree_overlay.iter().any(|o| o.filter_devs)3175&& cfg.vfio.iter().all(|o| o.dt_symbol.is_none())3176{3177return Err("expected at least one VFIO device with a defined dt_symbol".into());3178}3179}31803181// `--disable-sandbox` has the effect of disabling sandboxing altogether, so make sure3182// to handle it after other sandboxing options since they implicitly enable it.3183if cmd.disable_sandbox.unwrap_or_default() {3184cfg.jail_config = None;3185}31863187cfg.name = cmd.name;31883189// Now do validation of constructed config3190super::config::validate_config(&mut cfg)?;31913192Ok(cfg)3193}3194}31953196// Produce a block device path as used by Linux block devices.3197//3198// Examples for "/dev/vdX":3199// /dev/vda, /dev/vdb, ..., /dev/vdz, /dev/vdaa, /dev/vdab, ...3200fn format_disk_letter(dev_prefix: &str, mut i: usize) -> String {3201const ALPHABET_LEN: usize = 26; // a to z3202let mut s = dev_prefix.to_string();3203let insert_idx = dev_prefix.len();3204loop {3205s.insert(insert_idx, char::from(b'a' + (i % ALPHABET_LEN) as u8));3206i /= ALPHABET_LEN;3207if i == 0 {3208break;3209}3210i -= 1;3211}3212s3213}32143215#[cfg(test)]3216mod tests {3217use super::*;32183219#[test]3220fn disk_letter() {3221assert_eq!(format_disk_letter("/dev/sd", 0), "/dev/sda");3222assert_eq!(format_disk_letter("/dev/sd", 1), "/dev/sdb");3223assert_eq!(format_disk_letter("/dev/sd", 25), "/dev/sdz");3224assert_eq!(format_disk_letter("/dev/sd", 26), "/dev/sdaa");3225assert_eq!(format_disk_letter("/dev/sd", 27), "/dev/sdab");3226assert_eq!(format_disk_letter("/dev/sd", 51), "/dev/sdaz");3227assert_eq!(format_disk_letter("/dev/sd", 52), "/dev/sdba");3228assert_eq!(format_disk_letter("/dev/sd", 53), "/dev/sdbb");3229assert_eq!(format_disk_letter("/dev/sd", 78), "/dev/sdca");3230assert_eq!(format_disk_letter("/dev/sd", 701), "/dev/sdzz");3231assert_eq!(format_disk_letter("/dev/sd", 702), "/dev/sdaaa");3232assert_eq!(format_disk_letter("/dev/sd", 703), "/dev/sdaab");3233}3234}323532363237