From 025e782e506bab066f020ad013a8b9f5c630a6b4 Mon Sep 17 00:00:00 2001 From: Henry Hrvoje Tonkovac Date: Mon, 22 Jun 2026 14:43:08 +0200 Subject: [PATCH] vmm: trim qualified paths Import the modules used in the crate instead of spelling the full paths at every use site, and drop the now-unnecessary crate-level Signed-off-by: Henry Hrvoje Tonkovac Assisted-by: Claude:Opus-4.8 --- vmm/src/acpi.rs | 39 ++++--- vmm/src/api/dbus/mod.rs | 22 ++-- vmm/src/api/http/http_endpoint.rs | 24 ++-- vmm/src/api/http/mod.rs | 12 +- vmm/src/api/mod.rs | 4 +- vmm/src/config.rs | 22 ++-- vmm/src/console_devices.rs | 19 +-- vmm/src/coredump.rs | 43 +++---- vmm/src/cpu.rs | 109 ++++++++--------- vmm/src/device_manager.rs | 165 +++++++++++++------------- vmm/src/device_tree.rs | 4 +- vmm/src/gdb.rs | 54 +++++---- vmm/src/igvm/igvm_loader.rs | 24 ++-- vmm/src/igvm/mod.rs | 3 +- vmm/src/interrupt.rs | 8 +- vmm/src/lib.rs | 45 ++++---- vmm/src/memory_manager.rs | 76 ++++++------ vmm/src/migration/mod.rs | 11 +- vmm/src/migration/worker.rs | 12 +- vmm/src/pci_segment.rs | 3 +- vmm/src/seccomp_filters.rs | 6 +- vmm/src/serial_manager.rs | 15 +-- vmm/src/sev.rs | 8 +- vmm/src/sigwinch_listener.rs | 2 +- vmm/src/sparse.rs | 25 ++-- vmm/src/vm.rs | 186 +++++++++++++++--------------- vmm/src/vm_config.rs | 26 +++-- 27 files changed, 484 insertions(+), 483 deletions(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index ebbc14eca..8fa74994d 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -11,9 +11,11 @@ use acpi_tables::sdt::GenericAddress; use acpi_tables::sdt::Sdt; #[cfg(target_arch = "aarch64")] use arch::DeviceType; -use arch::NumaNodes; #[cfg(target_arch = "aarch64")] use arch::aarch64::DeviceInfoForFdt; +#[cfg(target_arch = "x86_64")] +use arch::x86_64; +use arch::{NumaNodes, layout}; use bitflags::bitflags; use log::{info, warn}; use pci::PciBdf; @@ -25,6 +27,8 @@ use crate::cpu::CpuManager; use crate::device_manager::DeviceManager; use crate::memory_manager::MemoryManager; use crate::pci_segment::PciSegment; +#[cfg(feature = "fw_cfg")] +use crate::vm; use crate::{GuestMemoryMmap, GuestRegionMmap}; /* Values for Type in APIC sub-headers */ @@ -371,9 +375,9 @@ fn create_srat_table( // Check the MemoryAffinity structure is the right size as expected by // the ACPI specification. - assert_eq!(std::mem::size_of::(), 40); + assert_eq!(size_of::(), 40); // Confirm struct size matches ACPI 6.6 spec - assert_eq!(std::mem::size_of::(), 32); + assert_eq!(size_of::(), 32); for (node_id, node) in numa_nodes.iter() { let proximity_domain = *node_id; @@ -395,7 +399,7 @@ fn create_srat_table( for cpu in &node.cpus { #[cfg(target_arch = "x86_64")] - let x2apic_id = arch::x86_64::get_x2apic_id(*cpu, topology); + let x2apic_id = x86_64::get_x2apic_id(*cpu, topology); #[cfg(target_arch = "aarch64")] let x2apic_id = *cpu; @@ -698,7 +702,7 @@ fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt { // - N x PCI Root Complex Node (N = number of pci segments) let num_nodes = (1 + pci_segments.len()) as u32; // First node is the ITS Group Node located right after the IORT Body Base - let offset_its_node = iort.len() + std::mem::size_of::(); + let offset_its_node = iort.len() + size_of::(); assert!(align_to_8_bytes(offset_its_node) == 0); // Ensure the ITS node is 8-byte aligned iort.append(IortBodyBase { num_nodes, @@ -714,8 +718,7 @@ fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt { // `translation_id` field of the `GisIts`` structure in the MADT table. let its_id_array = [0u32; 1]; let its_count = its_id_array.len(); - let its_group_node_size = - std::mem::size_of::() + its_count * std::mem::size_of::(); + let its_group_node_size = size_of::() + its_count * size_of::(); let padding = align_to_8_bytes(iort.len() + its_group_node_size); iort.append(IortItsGroupBase { common: IortNodeCommon { @@ -741,8 +744,8 @@ fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt { // Currently contains a single mapping that maps all device IDs // in the segment to the ITS Group Node. let num_id_mappings = 1; - let node_size = std::mem::size_of::() - + num_id_mappings * std::mem::size_of::(); + let node_size = + size_of::() + num_id_mappings * size_of::(); let padding = align_to_8_bytes(iort.len() + node_size); iort.append(IortPciRootComplexBase { common: IortNodeCommon { @@ -752,7 +755,7 @@ fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt { node_id: segment.id as u32, // todo to avoid conflict with ITS node IDs num_id_mappings: num_id_mappings as u32, // ID mapping array starts right after `IortPciRootComplexBase` - id_mappings_array_offset: std::mem::size_of::() as u32, + id_mappings_array_offset: size_of::() as u32, }, mem_access_props: IortMemoryAccessProperties { cca: 1, // Fully coherent device @@ -915,7 +918,7 @@ fn create_acpi_tables_internal( .get_device_info() .clone() .contains_key(&(DeviceType::Serial, DeviceType::Serial.to_string())); - let serial_device_addr = arch::layout::LEGACY_SERIAL_MAPPED_IO_START.raw_value(); + let serial_device_addr = layout::LEGACY_SERIAL_MAPPED_IO_START.raw_value(); let serial_device_irq = if is_serial_on { device_manager .get_device_info() @@ -1024,7 +1027,7 @@ pub fn create_acpi_tables_for_fw_cfg( memory_manager: &MemoryManager, numa_nodes: &NumaNodes, tpm_enabled: bool, -) -> Result<(), crate::vm::Error> { +) -> Result<(), vm::Error> { let dsdt_offset = GuestAddress(0); let (rsdp, table_bytes, xsdt_table_pointers) = create_acpi_tables_internal( dsdt_offset, @@ -1071,7 +1074,7 @@ pub fn create_acpi_tables_for_fw_cfg( .lock() .unwrap() .add_acpi(rsdp, table_bytes, checksums, pointer_offsets) - .map_err(crate::vm::Error::CreatingAcpiTables) + .map_err(vm::Error::CreatingAcpiTables) } pub fn create_acpi_tables( @@ -1085,7 +1088,7 @@ pub fn create_acpi_tables( trace_scoped!("create_acpi_tables"); let start_time = Instant::now(); - let rsdp_addr = arch::layout::RSDP_POINTER; + let rsdp_addr = layout::RSDP_POINTER; let dsdt_addr = rsdp_addr.checked_add(Rsdp::len() as u64).unwrap(); let (rsdp, tables_bytes, _xsdt_table_pointers) = create_acpi_tables_internal( @@ -1165,13 +1168,15 @@ pub fn create_acpi_tables_tdx( #[cfg(test)] mod tests { + use std::slice; + use super::*; #[test] fn test_generic_initiator_affinity_size() { // ACPI spec requires Generic Initiator Affinity Structure to be exactly 32 bytes assert_eq!( - std::mem::size_of::(), + size_of::(), 32, "GenericInitiatorAffinity must be exactly 32 bytes per ACPI 6.6 spec" ); @@ -1266,9 +1271,9 @@ mod tests { // there is no internal padding, making every byte within it // safe to read. Casting to `u8` satisfies alignment requirements. let bytes = unsafe { - std::slice::from_raw_parts( + slice::from_raw_parts( (&raw const gi).cast::(), - std::mem::size_of::(), + size_of::(), ) }; diff --git a/vmm/src/api/dbus/mod.rs b/vmm/src/api/dbus/mod.rs index 5f84b8025..d216fc8e1 100644 --- a/vmm/src/api/dbus/mod.rs +++ b/vmm/src/api/dbus/mod.rs @@ -5,17 +5,17 @@ use std::panic::AssertUnwindSafe; use std::sync::Arc; use std::sync::mpsc::Sender; -use std::thread; +use std::{fmt, panic, thread}; use futures::channel::oneshot; -use futures::{FutureExt, executor}; +use futures::{FutureExt, executor, future, lock}; use log::{error, warn}; use seccompiler::{SeccompAction, apply_filter}; use vmm_sys_util::eventfd::EventFd; use zbus::connection::Builder; use zbus::fdo::{self, Result}; -use zbus::interface; use zbus::zvariant::Optional; +use zbus::{interface, object_server}; use super::{ApiAction, ApiRequest}; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] @@ -40,10 +40,10 @@ pub struct DBusApiOptions { pub struct DBusApi { api_notifier: EventFd, - api_sender: futures::lock::Mutex>, + api_sender: lock::Mutex>, } -fn api_error(error: impl std::fmt::Debug + std::fmt::Display) -> fdo::Error { +fn api_error(error: impl fmt::Debug + fmt::Display) -> fdo::Error { fdo::Error::Failed(format!("{error}")) } @@ -71,7 +71,7 @@ impl DBusApi { pub fn new(api_notifier: EventFd, api_sender: Sender) -> Self { Self { api_notifier, - api_sender: futures::lock::Mutex::new(api_sender), + api_sender: lock::Mutex::new(api_sender), } } @@ -313,10 +313,8 @@ impl DBusApi { // implementation of this function is provided by the `#[zbus(signal)]` macro call #[zbus(signal)] - async fn event( - ctxt: &zbus::object_server::SignalEmitter<'_>, - event: Arc, - ) -> zbus::Result<()>; + async fn event(ctxt: &object_server::SignalEmitter<'_>, event: Arc) + -> zbus::Result<()>; } pub fn start_dbus_thread( @@ -371,10 +369,10 @@ pub fn start_dbus_thread( })?; } - std::panic::catch_unwind(AssertUnwindSafe(move || { + panic::catch_unwind(AssertUnwindSafe(move || { executor::block_on(async move { let recv_shutdown = recv_shutdown.fuse(); - let executor_tick = futures::future::Fuse::terminated(); + let executor_tick = future::Fuse::terminated(); futures::pin_mut!(recv_shutdown, executor_tick); executor_tick.set(connection.executor().tick().fuse()); diff --git a/vmm/src/api/http/http_endpoint.rs b/vmm/src/api/http/http_endpoint.rs index b652dfe99..a4dd94e63 100644 --- a/vmm/src/api/http/http_endpoint.rs +++ b/vmm/src/api/http/http_endpoint.rs @@ -35,11 +35,13 @@ //! [special HTTP library]: https://github.com/firecracker-microvm/micro-http use std::fs::File; +use std::result; use std::sync::mpsc::Sender; use micro_http::{Body, Method, Request, Response, StatusCode, Version}; use vmm_sys_util::eventfd::EventFd; +use crate::api; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use crate::api::VmCoredump; use crate::api::http::http_endpoint::fds_helper::{attach_fds_to_cfg, attach_fds_to_cfgs}; @@ -327,7 +329,7 @@ impl EndpointHandler for VmCreate { } } - match crate::api::VmCreate + match api::VmCreate .send(api_notifier, api_sender, vm_config) .map_err(HttpError::ApiError) { @@ -350,7 +352,7 @@ pub trait GetHandler { &'static self, _api_notifier: EventFd, _api_sender: Sender, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { Err(HttpError::BadRequest) } } @@ -362,7 +364,7 @@ pub trait PutHandler { _api_sender: Sender, _body: &Option, _files: Vec, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { Err(HttpError::BadRequest) } } @@ -503,7 +505,7 @@ impl PutHandler for VmAddNet { api_sender: Sender, body: &Option, files: Vec, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { if let Some(body) = body { let mut net_cfg: NetConfig = serde_json::from_slice(body.raw())?; attach_fds_to_cfg(files, &mut net_cfg)?; @@ -525,7 +527,7 @@ impl PutHandler for VmResize { api_sender: Sender, body: &Option, _files: Vec, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { if let Some(body) = body { self.send( api_notifier, @@ -555,7 +557,7 @@ impl PutHandler for VmRestore { api_sender: Sender, body: &Option, files: Vec, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { if let Some(body) = body { let mut restore_cfg: RestoreConfig = serde_json::from_slice(body.raw())?; @@ -593,7 +595,7 @@ impl EndpointHandler for VmActionHandler { api_sender: Sender, body: &Option, files: Vec, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { PutHandler::handle_request(self.action, api_notifier, api_sender, body, files) } @@ -602,7 +604,7 @@ impl EndpointHandler for VmActionHandler { api_notifier: EventFd, api_sender: Sender, _body: &Option, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { GetHandler::handle_request(self.action, api_notifier, api_sender) } } @@ -618,7 +620,7 @@ impl EndpointHandler for VmInfo { api_sender: Sender, ) -> Response { match req.method() { - Method::Get => match crate::api::VmInfo + Method::Get => match api::VmInfo .send(api_notifier, api_sender, ()) .map_err(HttpError::ApiError) { @@ -647,7 +649,7 @@ impl EndpointHandler for VmmPing { api_sender: Sender, ) -> Response { match req.method() { - Method::Get => match crate::api::VmmPing + Method::Get => match api::VmmPing .send(api_notifier, api_sender, ()) .map_err(HttpError::ApiError) { @@ -678,7 +680,7 @@ impl EndpointHandler for VmmShutdown { ) -> Response { match req.method() { Method::Put => { - match crate::api::VmmShutdown + match api::VmmShutdown .send(api_notifier, api_sender, ()) .map_err(HttpError::ApiError) { diff --git a/vmm/src/api/http/mod.rs b/vmm/src/api/http/mod.rs index 5a06e1d76..61b993169 100644 --- a/vmm/src/api/http/mod.rs +++ b/vmm/src/api/http/mod.rs @@ -12,7 +12,7 @@ use std::panic::AssertUnwindSafe; use std::path::{Path, PathBuf}; use std::sync::LazyLock; use std::sync::mpsc::Sender; -use std::thread; +use std::{fs, iter, panic, result, thread}; use block::fcntl::{LockError, LockGranularity, LockType, try_acquire_lock}; use log::{error, info}; @@ -104,7 +104,7 @@ pub fn error_response(error: HttpError) -> Response { let error: &dyn Error = &error; // Write the Display::display() output all errors (from top to root). - let error_messages = std::iter::successors(Some(error), |sub_error| { + let error_messages = iter::successors(Some(error), |sub_error| { // Dereference necessary to mitigate rustc compiler bug. // See (*sub_error).source() @@ -167,7 +167,7 @@ pub trait EndpointHandler { _api_sender: Sender, _body: &Option, _files: Vec, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { Err(HttpError::BadRequest) } @@ -176,7 +176,7 @@ pub trait EndpointHandler { _api_notifier: EventFd, _api_sender: Sender, _body: &Option, - ) -> std::result::Result, HttpError> { + ) -> result::Result, HttpError> { Err(HttpError::BadRequest) } } @@ -385,7 +385,7 @@ fn start_http_thread( })?; } - std::panic::catch_unwind(AssertUnwindSafe(move || { + panic::catch_unwind(AssertUnwindSafe(move || { server.start_server().unwrap(); loop { match server.requests() { @@ -456,7 +456,7 @@ pub fn start_http_path_thread( let lock = acquire_api_socket_lock(&socket_path)?; // We hold the lock, so any socket at this path is stale from a crashed // run: remove it before bind. Ignore errors (it is usually not present). - let _ = std::fs::remove_file(&socket_path); + let _ = fs::remove_file(&socket_path); let socket_fd = UnixListener::bind(socket_path).map_err(VmmError::CreateApiServerSocket)?; // SAFETY: Valid FD just opened diff --git a/vmm/src/api/mod.rs b/vmm/src/api/mod.rs index bbfe43af5..66e52879a 100644 --- a/vmm/src/api/mod.rs +++ b/vmm/src/api/mod.rs @@ -1925,7 +1925,7 @@ impl ApiAction for VmNmi { mod unit_tests { use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; - use std::{fs, process}; + use std::{env, fs, process}; use super::*; @@ -1939,7 +1939,7 @@ mod unit_tests { .duration_since(UNIX_EPOCH) .unwrap() .as_nanos(); - let path = std::env::temp_dir().join(format!( + let path = env::temp_dir().join(format!( "cloud-hypervisor-api-{name}-{}-{unique}", process::id() )); diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 6b659b4eb..0c6769e3f 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -25,7 +25,7 @@ use virtio_bindings::virtio_blk::VIRTIO_BLK_ID_BYTES; use virtio_bindings::virtio_ids::*; use virtio_devices::block::MINIMUM_BLOCK_QUEUE_SIZE; use virtio_devices::vhost_user::VIRTIO_FS_TAG_LEN; -use virtio_devices::{RateLimiterConfig, TokenBucketConfig}; +use virtio_devices::{RateLimiterConfig, TokenBucketConfig, net, vhost_user}; use crate::landlock::LandlockAccess; use crate::vm_config::*; @@ -432,7 +432,7 @@ pub enum ValidationError { InvalidSharedMemoryWithMergeable, } -type ValidationResult = std::result::Result; +type ValidationResult = result::Result; pub fn add_to_config(items: &mut Option>, item: T) { if let Some(items) = items { @@ -637,7 +637,7 @@ pub enum ParseHotplugMethodError { impl FromStr for HotplugMethod { type Err = ParseHotplugMethodError; - fn from_str(s: &str) -> std::result::Result { + fn from_str(s: &str) -> result::Result { match s.to_lowercase().as_str() { "acpi" => Ok(HotplugMethod::Acpi), "virtio-mem" => Ok(HotplugMethod::VirtioMem), @@ -653,7 +653,7 @@ pub enum ParseCoreSchedulingError { impl FromStr for CoreScheduling { type Err = ParseCoreSchedulingError; - fn from_str(s: &str) -> std::result::Result { + fn from_str(s: &str) -> result::Result { match s.to_lowercase().as_str() { "vm" => Ok(CoreScheduling::Vm), "vcpu" => Ok(CoreScheduling::Vcpu), @@ -670,7 +670,7 @@ pub enum CpuTopologyParseError { impl FromStr for CpuTopology { type Err = CpuTopologyParseError; - fn from_str(s: &str) -> std::result::Result { + fn from_str(s: &str) -> result::Result { let parts: Vec<&str> = s.split(':').collect(); if parts.len() != 4 { @@ -1655,7 +1655,7 @@ pub enum ParseVhostModeError { impl FromStr for VhostMode { type Err = ParseVhostModeError; - fn from_str(s: &str) -> std::result::Result { + fn from_str(s: &str) -> result::Result { match s.to_lowercase().as_str() { "client" => Ok(VhostMode::Client), "server" => Ok(VhostMode::Server), @@ -1863,7 +1863,7 @@ impl NetConfig { } if let Some(mtu) = self.mtu - && mtu < virtio_devices::net::MIN_MTU + && mtu < net::MIN_MTU { return Err(ValidationError::InvalidMtu(mtu)); } @@ -2122,7 +2122,7 @@ impl FsConfig { parser.parse(fs).map_err(Error::ParseFileSystem)?; let tag = parser.get("tag").ok_or(Error::ParseFsTagMissing)?; - if tag.len() > virtio_devices::vhost_user::VIRTIO_FS_TAG_LEN { + if tag.len() > vhost_user::VIRTIO_FS_TAG_LEN { return Err(Error::ParseFsTagTooLong); } let socket = PathBuf::from(parser.get("socket").ok_or(Error::ParseFsSockMissing)?); @@ -2223,7 +2223,7 @@ impl FwCfgConfig { items, }) } - pub fn validate(&self, payload: &PayloadConfig) -> std::result::Result<(), PayloadConfigError> { + pub fn validate(&self, payload: &PayloadConfig) -> result::Result<(), PayloadConfigError> { if self.kernel && payload.kernel.is_none() { return Err(PayloadConfigError::FwCfgMissingKernel); } else if self.cmdline && payload.cmdline.is_none() { @@ -2736,9 +2736,7 @@ pub struct RestoredNetConfig { pub fds: Option>, } -fn deserialize_restorednetconfig_fds<'de, D>( - d: D, -) -> std::result::Result>, D::Error> +fn deserialize_restorednetconfig_fds<'de, D>(d: D) -> result::Result>, D::Error> where D: serde::Deserializer<'de>, { diff --git a/vmm/src/console_devices.rs b/vmm/src/console_devices.rs index a7222cefe..0f33821d8 100644 --- a/vmm/src/console_devices.rs +++ b/vmm/src/console_devices.rs @@ -21,6 +21,7 @@ use std::{io, result}; use libc::{TCSANOW, cfmakeraw, isatty, tcgetattr, tcsetattr, termios}; use thiserror::Error; +use vmm_sys_util::errno; use crate::Vmm; use crate::sigwinch_listener::listen_for_sigwinch_on_tty; @@ -42,15 +43,15 @@ pub enum ConsoleDeviceError { /// Error setting pty raw mode #[error("Error setting pty raw mode")] - SetPtyRaw(#[source] vmm_sys_util::errno::Error), + SetPtyRaw(#[source] errno::Error), /// Cannot duplicate file descriptor #[error("Cannot duplicate file descriptor")] - DupFd(#[source] vmm_sys_util::errno::Error), + DupFd(#[source] errno::Error), /// Error starting sigwinch listener #[error("Error starting sigwinch listener")] - StartSigwinchListener(#[source] std::io::Error), + StartSigwinchListener(#[source] io::Error), } type ConsoleDeviceResult = result::Result; @@ -77,7 +78,7 @@ fn modify_mode( fd: RawFd, f: F, original_termios_opt: &mut Option, -) -> vmm_sys_util::errno::Result<()> { +) -> errno::Result<()> { // SAFETY: safe because we check the return value of isatty. if unsafe { isatty(fd) } != 1 { return Ok(()); @@ -89,7 +90,7 @@ fn modify_mode( // SAFETY: see above let ret = unsafe { tcgetattr(fd, &raw mut termios) }; if ret < 0 { - return vmm_sys_util::errno::errno_result(); + return errno::errno_result(); } if original_termios_opt.is_none() { original_termios_opt.replace(termios); @@ -100,7 +101,7 @@ fn modify_mode( // the return result. let ret = unsafe { tcsetattr(fd, TCSANOW, &raw const termios) }; if ret < 0 { - return vmm_sys_util::errno::errno_result(); + return errno::errno_result(); } Ok(()) @@ -155,7 +156,7 @@ fn create_pty() -> io::Result<(File, File, PathBuf)> { ) }; if sub_fd == -1 { - return vmm_sys_util::errno::errno_result().map_err(|e| e.into()); + return errno::errno_result().map_err(|e| e.into()); } let proc_path = PathBuf::from(format!("/proc/self/fd/{sub_fd}")); @@ -165,11 +166,11 @@ fn create_pty() -> io::Result<(File, File, PathBuf)> { Ok((main, unsafe { File::from_raw_fd(sub_fd) }, path)) } -fn dup_stdout() -> vmm_sys_util::errno::Result { +fn dup_stdout() -> errno::Result { // SAFETY: FFI call to dup. Trivially safe. let stdout = unsafe { libc::dup(libc::STDOUT_FILENO) }; if stdout == -1 { - return vmm_sys_util::errno::errno_result(); + return errno::errno_result(); } // SAFETY: stdout is valid and owned solely by us. Ok(unsafe { File::from_raw_fd(stdout) }) diff --git a/vmm/src/coredump.rs b/vmm/src/coredump.rs index 711fda289..cefc64c61 100644 --- a/vmm/src/coredump.rs +++ b/vmm/src/coredump.rs @@ -5,6 +5,7 @@ use std::fs::File; use std::io::Write; +use std::{collections, io, result}; #[cfg(target_arch = "x86_64")] use hypervisor::arch::x86::{DescriptorTable, SegmentRegister}; @@ -20,7 +21,7 @@ pub struct CoredumpMemoryRegion { #[derive(Clone)] pub struct CoredumpMemoryRegions { - pub ram_maps: std::collections::BTreeMap, + pub ram_maps: collections::BTreeMap, } /// Platform information @@ -39,7 +40,7 @@ pub enum GuestDebuggableError { #[error("coredump")] Coredump(#[source] anyhow::Error), #[error("coredump file")] - CoredumpFile(#[source] std::io::Error), + CoredumpFile(#[source] io::Error), #[error("Failed to pause")] Pause(#[source] vm_migration::MigratableError), #[error("Failed to resume")] @@ -47,10 +48,7 @@ pub enum GuestDebuggableError { } pub trait GuestDebuggable: vm_migration::Pausable { - fn coredump( - &mut self, - _destination_url: &str, - ) -> std::result::Result<(), GuestDebuggableError> { + fn coredump(&mut self, _destination_url: &str) -> result::Result<(), GuestDebuggableError> { Ok(()) } } @@ -194,10 +192,7 @@ const EV_CURRENT: u8 = 1; const EM_X86_64: u16 = 62; pub trait Elf64Writable { - fn write_header( - &mut self, - dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + fn write_header(&mut self, dump_state: &DumpState) -> result::Result<(), GuestDebuggableError> { let e_ident = [ elf::ELFMAG0 as u8, // magic elf::ELFMAG1, @@ -216,8 +211,8 @@ pub trait Elf64Writable { 0, 0, ]; - let elf64_ehdr_size = std::mem::size_of::(); - let elf64_phdr_size = std::mem::size_of::(); + let elf64_ehdr_size = size_of::(); + let elf64_phdr_size = size_of::(); let mut elf64_ehdr = elf::Elf64_Ehdr { e_ident, e_type: ET_CORE, @@ -234,7 +229,7 @@ pub trait Elf64Writable { e_shnum: 0, e_shstrndx: 0, }; - elf64_ehdr.e_ehsize = std::mem::size_of_val(&elf64_ehdr) as u16; + elf64_ehdr.e_ehsize = size_of_val(&elf64_ehdr) as u16; let mut coredump_file = dump_state.file.as_ref().unwrap(); let bytes: &[u8] = elf64_ehdr.as_slice(); @@ -245,10 +240,7 @@ pub trait Elf64Writable { Ok(()) } - fn write_note( - &mut self, - dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + fn write_note(&mut self, dump_state: &DumpState) -> result::Result<(), GuestDebuggableError> { let begin = dump_state.mem_offset - dump_state.elf_note_size as u64; let elf64_phdr = elf::Elf64_Phdr { p_type: elf::PT_NOTE, @@ -277,7 +269,7 @@ pub trait Elf64Writable { length: u64, virt_addr: u64, dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + ) -> result::Result<(), GuestDebuggableError> { let elf64_load = elf::Elf64_Phdr { p_type: elf::PT_LOAD, p_flags: 0, @@ -298,10 +290,7 @@ pub trait Elf64Writable { Ok(()) } - fn write_loads( - &mut self, - dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + fn write_loads(&mut self, dump_state: &DumpState) -> result::Result<(), GuestDebuggableError> { let mem_info = dump_state.mem_info.as_ref().unwrap(); for (gpa, load) in &mem_info.ram_maps { @@ -316,9 +305,9 @@ pub trait Elf64Writable { } fn get_note_size(&self, desc_type: NoteDescType, nr_cpus: u32) -> u32 { - let note_head_size = std::mem::size_of::() as u32; - let elf_desc_size = std::mem::size_of::() as u32; - let cpu_state_desc_size = std::mem::size_of::() as u32; + let note_head_size = size_of::() as u32; + let elf_desc_size = size_of::() as u32; + let cpu_state_desc_size = size_of::() as u32; let elf_note_size = self.elf_note_size(note_head_size, COREDUMP_NAME_SIZE, elf_desc_size); let vmm_note_size = @@ -336,14 +325,14 @@ pub trait CpuElf64Writable { fn cpu_write_elf64_note( &mut self, _dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + ) -> result::Result<(), GuestDebuggableError> { Ok(()) } fn cpu_write_vmm_note( &mut self, _dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + ) -> result::Result<(), GuestDebuggableError> { Ok(()) } } diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index c8473242b..8f234d19a 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -14,19 +14,20 @@ use std::collections::BTreeMap; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use std::io::Write; -#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] -use std::mem::size_of; +use std::mem::zeroed; use std::os::unix::thread::JoinHandleExt; use std::sync::atomic::{AtomicBool, AtomicI32, Ordering}; use std::sync::{Arc, Barrier, Mutex}; -use std::{cmp, io, result, thread}; +use std::{any, cmp, hint, io, panic, result, thread, time}; use acpi_tables::sdt::Sdt; use acpi_tables::{Aml, aml}; use anyhow::anyhow; #[cfg(target_arch = "x86_64")] +use arch::x86_64; +#[cfg(target_arch = "x86_64")] use arch::x86_64::get_x2apic_id; -use arch::{EntryPoint, NumaNodes}; +use arch::{EntryPoint, NumaNodes, layout}; #[cfg(target_arch = "aarch64")] use devices::gic::Gic; use devices::interrupt_controller::InterruptController; @@ -54,7 +55,11 @@ use hypervisor::arch::x86::SpecialRegisters; use hypervisor::arch::x86::msr_index; #[cfg(feature = "tdx")] use hypervisor::kvm::{TdxExitDetails, TdxExitStatus}; +#[cfg(feature = "mshv")] +use hypervisor::mshv; use hypervisor::{CpuState, HypervisorCpuError, VmExit, VmOps}; +#[cfg(feature = "sev_snp")] +use igvm::snp_defs; use libc::{c_void, siginfo_t}; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use linux_loader::elf::Elf64_Nhdr; @@ -76,6 +81,8 @@ use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::signal::{SIGRTMIN, register_signal_handler}; use zerocopy::{FromBytes, Immutable, IntoBytes}; +#[cfg(target_arch = "x86_64")] +use crate::acpi; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use crate::coredump::{ COREDUMP_NAME_SIZE, CpuElf64Writable, CpuSegment, CpuState as DumpCpusState, DumpState, @@ -84,6 +91,8 @@ use crate::coredump::{ }; #[cfg(feature = "guest_debug")] use crate::gdb::{Debuggable, DebuggableError, get_raw_tid}; +#[cfg(all(feature = "sev_snp", feature = "mshv"))] +use crate::igvm::HV_PAGE_SIZE; use crate::seccomp_filters::{Thread, get_seccomp_filter}; #[cfg(target_arch = "x86_64")] use crate::vm::physical_bits; @@ -156,7 +165,7 @@ pub enum Error { VcpuSetGicrBaseAddr(#[source] hypervisor::HypervisorCpuError), #[error("Failed to join on vCPU threads: {0:?}")] - ThreadCleanup(std::boxed::Box), + ThreadCleanup(Box), #[error("Timeout when waiting for signal to be acknowledged")] SignalAcknowledgeTimeout, @@ -639,7 +648,7 @@ impl Vcpu { /// /// Note that the state of the VCPU and associated VM must be setup first for this to do /// anything useful. - pub fn run(&mut self) -> std::result::Result { + pub fn run(&mut self) -> result::Result { self.vcpu.run() } @@ -656,7 +665,7 @@ impl Vcpu { } #[cfg(feature = "sev_snp")] - pub fn setup_sev_snp_regs(&self, vmsa: igvm::snp_defs::SevVmsa) -> Result<()> { + pub fn setup_sev_snp_regs(&self, vmsa: snp_defs::SevVmsa) -> Result<()> { self.vcpu .setup_sev_snp_regs(vmsa) .map_err(Error::SetupSevSnpRegs) @@ -671,8 +680,8 @@ impl Vcpu { base_redist_addr: u64, redist_size: u64, ) -> Result<()> { - let gicr_base = base_redist_addr + (arch::layout::GIC_V3_REDIST_SIZE * self.id as u64); - assert!(gicr_base + arch::layout::GIC_V3_REDIST_SIZE <= base_redist_addr + redist_size); + let gicr_base = base_redist_addr + (layout::GIC_V3_REDIST_SIZE * self.id as u64); + assert!(gicr_base + layout::GIC_V3_REDIST_SIZE <= base_redist_addr + redist_size); self.vcpu .set_gic_redistributor_addr(gicr_base) .map_err(Error::VcpuSetGicrBaseAddr)?; @@ -686,7 +695,7 @@ impl Snapshottable for Vcpu { self.id.to_string() } - fn snapshot(&mut self) -> std::result::Result { + fn snapshot(&mut self) -> result::Result { let saved_state = self .vcpu .state() @@ -819,7 +828,7 @@ impl VcpuState { } // This is more effective than thread::yield_now() at // avoiding a priority inversion with the vCPU thread - thread::sleep(std::time::Duration::from_millis(1)); + thread::sleep(time::Duration::from_millis(1)); count += 1; if count >= 1000 { return Err(Error::SignalAcknowledgeTimeout); @@ -979,7 +988,7 @@ impl CpuManager { #[cfg(target_arch = "x86_64")] let topology = self.get_vcpu_topology(); #[cfg(target_arch = "x86_64")] - let x2apic_id = arch::x86_64::get_x2apic_id(cpu_id, topology); + let x2apic_id = x86_64::get_x2apic_id(cpu_id, topology); #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] let x2apic_id = cpu_id; @@ -1034,9 +1043,7 @@ impl CpuManager { && self.hypervisor.hypervisor_type() == hypervisor::HypervisorType::Mshv { if let Some((kernel_entry_point, _)) = boot_setup { - vcpu.set_sev_control_register( - kernel_entry_point.entry_addr.0 / crate::igvm::HV_PAGE_SIZE, - )?; + vcpu.set_sev_control_register(kernel_entry_point.entry_addr.0 / HV_PAGE_SIZE)?; } // Traditional way to configure vcpu doesn't work for SEV-SNP guests. @@ -1200,7 +1207,7 @@ impl CpuManager { // Prepare the CPU set the current vCPU is expected to run onto. let cpuset = self.affinity.get(&vcpu_id).map(|host_cpus| { // SAFETY: all zeros is a valid pattern - let mut cpuset: libc::cpu_set_t = unsafe { std::mem::zeroed() }; + let mut cpuset: libc::cpu_set_t = unsafe { zeroed() }; // SAFETY: FFI call, trivially safe unsafe { libc::CPU_ZERO(&mut cpuset) }; for host_cpu in host_cpus { @@ -1237,7 +1244,7 @@ impl CpuManager { let ret = unsafe { libc::sched_setaffinity( 0, - std::mem::size_of::(), + size_of::(), cpuset, ) }; @@ -1290,7 +1297,7 @@ impl CpuManager { match CoreSchedulingLeader::try_from(v) { Ok(CoreSchedulingLeader::Error) => return, Ok(CoreSchedulingLeader::Initial | - CoreSchedulingLeader::Elected) => std::hint::spin_loop(), + CoreSchedulingLeader::Elected) => hint::spin_loop(), Err(()) => break v, } }; @@ -1328,7 +1335,7 @@ impl CpuManager { // Block until all CPUs are ready. vcpu_thread_barrier.wait(); - std::panic::catch_unwind(move || { + panic::catch_unwind(move || { loop { // If we are being told to pause, we park the thread // until the pause boolean is toggled. @@ -1563,7 +1570,7 @@ impl CpuManager { #[cfg(feature = "mshv")] pub fn set_processors_per_socket_property(&self) -> Result<()> { - if let Some(mshv_vm) = self.vm.as_any().downcast_ref::() { + if let Some(mshv_vm) = self.vm.as_any().downcast_ref::() { let threads_per_core = if let Some(ref topology) = self.config.topology { topology.threads_per_core as u64 } else { @@ -1572,7 +1579,7 @@ impl CpuManager { mshv_vm .set_partition_property( - hypervisor::mshv::HV_PARTITION_PROPERTY_PROCESSORS_PER_SOCKET, + mshv::HV_PARTITION_PROPERTY_PROCESSORS_PER_SOCKET, threads_per_core, ) .map_err(Error::SetPartitionProperty)?; @@ -1752,7 +1759,7 @@ impl CpuManager { let mut madt = Sdt::new(*b"APIC", 44, 5, *b"CLOUDH", *b"CHMADT ", 1); #[cfg(target_arch = "x86_64")] { - madt.write(36, arch::layout::APIC_START.0); + madt.write(36, layout::APIC_START.0); for cpu in 0..self.config.max_vcpus { let x2apic_id = get_x2apic_id(cpu, self.get_vcpu_topology()); @@ -1776,7 +1783,7 @@ impl CpuManager { r#type: acpi::ACPI_APIC_IO, length: 12, ioapic_id: 0, - apic_address: arch::layout::IOAPIC_START.0 as u32, + apic_address: layout::IOAPIC_START.0 as u32, gsi_base: 0, ..Default::default() }); @@ -2163,7 +2170,7 @@ impl CpuManager { let pa_range = extract_bits_64_without_offset!(id_aa64mmfr0_el1, 4); // The IPA size in TCR_BL1 and PA Range in ID_AA64MMFR0_EL1 should match. // To be safe, we use the minimum value if they are different. - let pa_range = std::cmp::min(tcr_ips, pa_range); + let pa_range = cmp::min(tcr_ips, pa_range); // PA size in bits let pa_size = match pa_range { 0 => 32, @@ -2320,10 +2327,10 @@ const MADT_CPU_ONLINE_CAPABLE_FLAG: usize = 1; impl Cpu { #[cfg(target_arch = "x86_64")] fn generate_mat(&self) -> Vec { - let x2apic_id = arch::x86_64::get_x2apic_id(self.cpu_id, self.topology); + let x2apic_id = x86_64::get_x2apic_id(self.cpu_id, self.topology); LocalX2Apic { - r#type: crate::acpi::ACPI_X2APIC_PROCESSOR, + r#type: acpi::ACPI_X2APIC_PROCESSOR, length: 16, processor_id: self.cpu_id, apic_id: x2apic_id, @@ -2650,7 +2657,7 @@ impl Aml for CpuManager { } impl Pausable for CpuManager { - fn pause(&mut self) -> std::result::Result<(), MigratableError> { + fn pause(&mut self) -> result::Result<(), MigratableError> { // Tell the vCPUs to pause themselves next time they exit self.vcpus_pause_signalled.store(true, Ordering::SeqCst); @@ -2676,7 +2683,7 @@ impl Pausable for CpuManager { // wait for vCPU to update state while !state.paused.load(Ordering::SeqCst) { // To avoid a priority inversion with the vCPU thread - thread::sleep(std::time::Duration::from_millis(1)); + thread::sleep(time::Duration::from_millis(1)); } } } @@ -2684,7 +2691,7 @@ impl Pausable for CpuManager { Ok(()) } - fn resume(&mut self) -> std::result::Result<(), MigratableError> { + fn resume(&mut self) -> result::Result<(), MigratableError> { // Ensure that vCPUs keep running after being unpark() in // their run vCPU loop. self.vcpus_pause_signalled.store(false, Ordering::SeqCst); @@ -2704,7 +2711,7 @@ impl Pausable for CpuManager { // wait for vCPU to update state while state.paused.load(Ordering::SeqCst) { // To avoid a priority inversion with the vCPU thread - thread::sleep(std::time::Duration::from_millis(1)); + thread::sleep(time::Duration::from_millis(1)); } } } @@ -2717,7 +2724,7 @@ impl Snapshottable for CpuManager { CPU_MANAGER_SNAPSHOT_ID.to_string() } - fn snapshot(&mut self) -> std::result::Result { + fn snapshot(&mut self) -> result::Result { let mut cpu_manager_snapshot = Snapshot::default(); // The CpuManager snapshot is a collection of all vCPUs snapshots. @@ -2741,7 +2748,7 @@ impl Debuggable for CpuManager { cpu_id: usize, addrs: &[GuestAddress], singlestep: bool, - ) -> std::result::Result<(), DebuggableError> { + ) -> result::Result<(), DebuggableError> { self.vcpus[cpu_id] .lock() .unwrap() @@ -2750,16 +2757,16 @@ impl Debuggable for CpuManager { .map_err(DebuggableError::SetDebug) } - fn debug_pause(&mut self) -> std::result::Result<(), DebuggableError> { + fn debug_pause(&mut self) -> result::Result<(), DebuggableError> { Ok(()) } - fn debug_resume(&mut self) -> std::result::Result<(), DebuggableError> { + fn debug_resume(&mut self) -> result::Result<(), DebuggableError> { Ok(()) } #[cfg(target_arch = "x86_64")] - fn read_regs(&self, cpu_id: usize) -> std::result::Result { + fn read_regs(&self, cpu_id: usize) -> result::Result { // General registers: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15 let gregs = self .get_regs(cpu_id as u8) @@ -2813,7 +2820,7 @@ impl Debuggable for CpuManager { } #[cfg(target_arch = "aarch64")] - fn read_regs(&self, cpu_id: usize) -> std::result::Result { + fn read_regs(&self, cpu_id: usize) -> result::Result { let gregs = self .get_regs(cpu_id as u8) .map_err(DebuggableError::ReadRegs)?; @@ -2826,11 +2833,7 @@ impl Debuggable for CpuManager { } #[cfg(target_arch = "x86_64")] - fn write_regs( - &self, - cpu_id: usize, - regs: &CoreRegs, - ) -> std::result::Result<(), DebuggableError> { + fn write_regs(&self, cpu_id: usize, regs: &CoreRegs) -> result::Result<(), DebuggableError> { let orig_gregs = self .get_regs(cpu_id as u8) .map_err(DebuggableError::ReadRegs)?; @@ -2879,11 +2882,7 @@ impl Debuggable for CpuManager { } #[cfg(target_arch = "aarch64")] - fn write_regs( - &self, - cpu_id: usize, - regs: &CoreRegs, - ) -> std::result::Result<(), DebuggableError> { + fn write_regs(&self, cpu_id: usize, regs: &CoreRegs) -> result::Result<(), DebuggableError> { let mut gregs = self .get_regs(cpu_id as u8) .map_err(DebuggableError::ReadRegs)?; @@ -2904,7 +2903,7 @@ impl Debuggable for CpuManager { cpu_id: usize, vaddr: GuestAddress, len: usize, - ) -> std::result::Result, DebuggableError> { + ) -> result::Result, DebuggableError> { let mut buf = vec![0; len]; let mut total_read = 0_u64; @@ -2916,7 +2915,7 @@ impl Debuggable for CpuManager { Err(e) => return Err(DebuggableError::TranslateGva(e)), }; let psize = arch::PAGE_SIZE as u64; - let read_len = std::cmp::min(len as u64 - total_read, psize - (paddr & (psize - 1))); + let read_len = cmp::min(len as u64 - total_read, psize - (paddr & (psize - 1))); guest_memory .memory() .read( @@ -2935,7 +2934,7 @@ impl Debuggable for CpuManager { cpu_id: usize, vaddr: &GuestAddress, data: &[u8], - ) -> std::result::Result<(), DebuggableError> { + ) -> result::Result<(), DebuggableError> { let mut total_written = 0_u64; while total_written < data.len() as u64 { @@ -2946,7 +2945,7 @@ impl Debuggable for CpuManager { Err(e) => return Err(DebuggableError::TranslateGva(e)), }; let psize = arch::PAGE_SIZE as u64; - let write_len = std::cmp::min( + let write_len = cmp::min( data.len() as u64 - total_written, psize - (paddr & (psize - 1)), ); @@ -2975,7 +2974,7 @@ impl CpuElf64Writable for CpuManager { fn cpu_write_elf64_note( &mut self, dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + ) -> result::Result<(), GuestDebuggableError> { let mut coredump_file = dump_state.file.as_ref().unwrap(); for vcpu in &self.vcpus { let note_size = self.get_note_size(NoteDescType::Elf, 1); @@ -3083,7 +3082,7 @@ impl CpuElf64Writable for CpuManager { fn cpu_write_vmm_note( &mut self, dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + ) -> result::Result<(), GuestDebuggableError> { let mut coredump_file = dump_state.file.as_ref().unwrap(); for vcpu in &self.vcpus { let note_size = self.get_note_size(NoteDescType::Vmm, 1); @@ -3349,6 +3348,7 @@ impl BusDevice for AcpiCpuHotplugController { #[cfg(all(feature = "kvm", target_arch = "x86_64"))] #[cfg(test)] mod unit_tests { + use arch::layout; use arch::layout::{BOOT_STACK_POINTER, ZERO_PAGE_START}; use arch::x86_64::interrupts::*; use arch::x86_64::regs::*; @@ -3448,7 +3448,7 @@ mod unit_tests { let mut expected_regs: StandardRegisters = vcpu.create_standard_regs(); expected_regs.set_rflags(0x0000000000000002u64); - expected_regs.set_rbx(arch::layout::PVH_INFO_START.0); + expected_regs.set_rbx(layout::PVH_INFO_START.0); expected_regs.set_rip(1); setup_regs( @@ -3511,6 +3511,7 @@ mod unit_tests { KVM_REG_ARM_CORE, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_SIZE_U64, user_pt_regs, }; use hypervisor::{HypervisorCpuError, HypervisorVmConfig}; + use vmm_sys_util::errno; #[test] fn test_setup_regs() { @@ -3564,7 +3565,7 @@ mod unit_tests { fn hypervisor_cpu_error_to_raw_os_error(error: &anyhow::Error) -> libc::c_int { let cause = error.chain().next().expect("should have root cause"); cause - .downcast_ref::() + .downcast_ref::() .unwrap_or_else(|| panic!("should be io::Error but is: {cause:?}")) .errno() as libc::c_int } diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 2c77f3385..4f592eb13 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -9,7 +9,11 @@ // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause // +#[cfg(target_arch = "x86_64")] +use std::cmp; use std::collections::{BTreeMap, BTreeSet, HashMap}; +#[cfg(feature = "sev_snp")] +use std::fmt; #[cfg(feature = "kvm")] use std::fs; use std::fs::{File, OpenOptions}; @@ -20,10 +24,10 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; #[cfg(not(target_arch = "riscv64"))] use std::path::Path; use std::path::PathBuf; -use std::result; use std::sync::{Arc, Mutex}; #[cfg(not(target_arch = "riscv64"))] use std::time::Instant; +use std::{iter, path, result, sync}; use acpi_tables::sdt::GenericAddress; use acpi_tables::{Aml, aml}; @@ -62,8 +66,8 @@ use devices::legacy::{ fw_cfg::{PORT_FW_CFG_BASE, PORT_FW_CFG_WIDTH}, }; #[cfg(feature = "pvmemcontrol")] -use devices::pvmemcontrol::{PvmemcontrolBusDevice, PvmemcontrolPciDevice}; -use devices::{AcpiNotificationFlags, interrupt_controller}; +use devices::pvmemcontrol::{self, PvmemcontrolBusDevice, PvmemcontrolPciDevice}; +use devices::{AcpiNotificationFlags, acpi, interrupt_controller, legacy, pvpanic, tpm}; use event_monitor::event; use hypervisor::IoEventAddress; #[cfg(target_arch = "aarch64")] @@ -79,6 +83,7 @@ use pci::{ DeviceRelocation, MmioRegion, PciBarConfiguration, PciBarRegionType, PciBdf, PciDevice, VfioDmaMapping, VfioPciDevice, VfioUserDmaMapping, VfioUserPciDevice, VfioUserPciDeviceError, }; +use rate_limiter::group; use rate_limiter::group::RateLimiterGroup; use seccompiler::SeccompAction; use serde::{Deserialize, Serialize}; @@ -87,10 +92,12 @@ use tracer::trace_scoped; #[cfg(feature = "kvm")] use vfio_ioctls::VfioIommufd; use vfio_ioctls::{VfioContainer, VfioDevice, VfioDeviceFd, VfioOps}; +use virtio_devices::block::Error as VirtioBlockError; use virtio_devices::transport::{VirtioPciDevice, VirtioPciDeviceActivator, VirtioTransport}; use virtio_devices::vhost_user::VhostUserConfig; use virtio_devices::{ AccessPlatformMapping, Block, Endpoint, IommuMapping, VdpaDmaMapping, VirtioMemMappingSource, + balloon, mem, net, transport, vdpa, vhost_user, vsock, }; use vm_allocator::{AddressAllocator, InterruptAllocError, SystemAllocator}; use vm_device::dma_mapping::ExternalDmaMapping; @@ -101,7 +108,9 @@ use vm_device::{Bus, BusDevice, BusDeviceSync, Resource, UserspaceMapping}; #[cfg(feature = "ivshmem")] use vm_memory::bitmap::AtomicBitmap; use vm_memory::guest_memory::FileOffset; -use vm_memory::{Address, GuestAddress, GuestMemoryRegion, GuestUsize, MmapRegion, VolatileMemory}; +use vm_memory::{ + Address, GuestAddress, GuestMemoryRegion, GuestUsize, MmapRegion, VolatileMemory, mmap, +}; #[cfg(target_arch = "x86_64")] use vm_memory::{GuestAddressSpace, GuestMemory}; use vm_migration::protocol::MemoryRangeTable; @@ -110,6 +119,7 @@ use vm_migration::{ snapshot_from_id, state_from_id, }; use vm_virtio::{AccessPlatform, VirtioDeviceType}; +use vmm_sys_util::errno; use vmm_sys_util::eventfd::EventFd; use crate::console_devices::{ConsoleDeviceError, ConsoleInfo, ConsoleTransport}; @@ -177,7 +187,7 @@ pub enum DeviceManagerError { /// Cannot create vhost-user-net device #[error("Cannot create vhost-user-net device")] - CreateVhostUserNet(#[source] virtio_devices::vhost_user::Error), + CreateVhostUserNet(#[source] vhost_user::Error), /// Cannot create virtio-blk device #[error("Cannot create virtio-blk device")] @@ -185,7 +195,7 @@ pub enum DeviceManagerError { /// Cannot create virtio-net device #[error("Cannot create virtio-net device")] - CreateVirtioNet(#[source] virtio_devices::net::Error), + CreateVirtioNet(#[source] net::Error), /// Cannot create virtio-console device #[error("Cannot create virtio-console device")] @@ -201,11 +211,11 @@ pub enum DeviceManagerError { /// Cannot create generic vhost-user device #[error("Cannot create generic vhost-user device")] - CreateGenericVhostUser(#[source] virtio_devices::vhost_user::Error), + CreateGenericVhostUser(#[source] vhost_user::Error), /// Cannot create virtio-fs device #[error("Cannot create virtio-fs device")] - CreateVirtioFs(#[source] virtio_devices::vhost_user::Error), + CreateVirtioFs(#[source] vhost_user::Error), /// Virtio-fs device was created without a socket. #[error("Virtio-fs device was created without a socket")] @@ -217,7 +227,7 @@ pub enum DeviceManagerError { /// Cannot create vhost-user-blk device #[error("Cannot create vhost-user-blk device")] - CreateVhostUserBlk(#[source] virtio_devices::vhost_user::Error), + CreateVhostUserBlk(#[source] vhost_user::Error), /// Cannot create virtio-pmem device #[error("Cannot create virtio-pmem device")] @@ -225,7 +235,7 @@ pub enum DeviceManagerError { /// Cannot create vDPA device #[error("Cannot create vdpa device")] - CreateVdpa(#[source] virtio_devices::vdpa::Error), + CreateVdpa(#[source] vdpa::Error), /// Cannot create virtio-vsock device #[error("Cannot create virtio-vsock device")] @@ -245,7 +255,7 @@ pub enum DeviceManagerError { /// Cannot create virtio-vsock backend #[error("Cannot create virtio-vsock backend")] - CreateVsockBackend(#[source] virtio_devices::vsock::VsockUnixError), + CreateVsockBackend(#[source] vsock::VsockUnixError), /// Cannot create virtio-iommu device #[error("Cannot create virtio-iommu device")] @@ -282,7 +292,7 @@ pub enum DeviceManagerError { /// Cannot configure the IRQ. #[error("Cannot configure the IRQ")] - Irq(#[source] vmm_sys_util::errno::Error), + Irq(#[source] errno::Error), /// Cannot allocate PCI BARs #[error("Cannot allocate PCI BARs")] @@ -302,7 +312,7 @@ pub enum DeviceManagerError { /// Cannot create virtio device #[error("Cannot create virtio device")] - VirtioDevice(#[source] virtio_devices::transport::VirtioPciDeviceError), + VirtioDevice(#[source] transport::VirtioPciDeviceError), /// Cannot add PCI device #[error("Cannot add PCI device")] @@ -363,7 +373,7 @@ pub enum DeviceManagerError { /// Error getting pty peer #[error("Error getting pty peer")] - GetPtyPeer(#[source] vmm_sys_util::errno::Error), + GetPtyPeer(#[source] errno::Error), /// Cannot create iommufd #[cfg(feature = "kvm")] @@ -440,7 +450,7 @@ pub enum DeviceManagerError { /// Failed to create a new MmapRegion instance. #[error("Failed to create a new MmapRegion instance")] - NewMmapRegion(#[source] vm_memory::mmap::MmapRegionError), + NewMmapRegion(#[source] mmap::MmapRegionError), /// Failed to clone a File. #[error("Failed to clone a File")] @@ -560,7 +570,7 @@ pub enum DeviceManagerError { /// Failed to resize virtio-balloon #[error("Failed to resize virtio-balloon")] - VirtioBalloonResize(#[source] virtio_devices::balloon::Error), + VirtioBalloonResize(#[source] balloon::Error), /// Missing virtio-balloon, can't proceed as expected. #[error("Missing virtio-balloon, can't proceed as expected")] @@ -577,18 +587,18 @@ pub enum DeviceManagerError { /// Failed to do AArch64 GPIO power button notification #[cfg(target_arch = "aarch64")] #[error("Failed to do AArch64 GPIO power button notification")] - AArch64PowerButtonNotification(#[source] devices::legacy::GpioDeviceError), + AArch64PowerButtonNotification(#[source] legacy::GpioDeviceError), /// Failed to set O_DIRECT flag to file descriptor #[error("Failed to set O_DIRECT flag to file descriptor")] SetDirectIo, /// Failed to add DMA mapping handler to virtio-mem device. #[error("Failed to add DMA mapping handler to virtio-mem device")] - AddDmaMappingHandlerVirtioMem(#[source] virtio_devices::mem::Error), + AddDmaMappingHandlerVirtioMem(#[source] mem::Error), /// Failed to remove DMA mapping handler from virtio-mem device. #[error("Failed to remove DMA mapping handler from virtio-mem device")] - RemoveDmaMappingHandlerVirtioMem(#[source] virtio_devices::mem::Error), + RemoveDmaMappingHandlerVirtioMem(#[source] mem::Error), /// Failed to create vfio-user client #[error("Failed to create vfio-user client")] @@ -616,15 +626,15 @@ pub enum DeviceManagerError { /// Cannot duplicate file descriptor #[error("Cannot duplicate file descriptor")] - DupFd(#[source] vmm_sys_util::errno::Error), + DupFd(#[source] errno::Error), /// Failed to DMA map virtio device. #[error("Failed to DMA map virtio device")] - VirtioDmaMap(#[source] std::io::Error), + VirtioDmaMap(#[source] io::Error), /// Failed to DMA unmap virtio device. #[error("Failed to DMA unmap virtio device")] - VirtioDmaUnmap(#[source] std::io::Error), + VirtioDmaUnmap(#[source] io::Error), /// Cannot hotplug device behind vIOMMU #[error("Cannot hotplug device behind vIOMMU")] @@ -640,7 +650,7 @@ pub enum DeviceManagerError { /// vfio-user socket path already in use by another user device. #[error("vfio-user socket path already in use: {0:?}")] - UserDeviceSocketInUse(std::path::PathBuf), + UserDeviceSocketInUse(path::PathBuf), /// Failed retrieving device state from snapshot #[error("Failed retrieving device state from snapshot")] @@ -648,7 +658,7 @@ pub enum DeviceManagerError { /// Cannot create a PvPanic device #[error("Cannot create a PvPanic device")] - PvPanicCreate(#[source] devices::pvpanic::PvPanicError), + PvPanicCreate(#[source] pvpanic::PvPanicError), #[cfg(feature = "ivshmem")] /// Cannot create a ivshmem device @@ -657,11 +667,11 @@ pub enum DeviceManagerError { /// Cannot create a RateLimiterGroup #[error("Cannot create a RateLimiterGroup")] - RateLimiterGroupCreate(#[source] rate_limiter::group::Error), + RateLimiterGroupCreate(#[source] group::Error), /// Cannot start sigwinch listener #[error("Cannot start sigwinch listener")] - StartSigwinchListener(#[source] std::io::Error), + StartSigwinchListener(#[source] io::Error), // Invalid console info #[error("Invalid console info")] @@ -673,7 +683,7 @@ pub enum DeviceManagerError { /// Cannot lock images of all block devices. #[error("Cannot lock images of all block devices")] - DiskLockError(#[source] virtio_devices::block::Error), + DiskLockError(#[source] VirtioBlockError), #[cfg(feature = "fw_cfg")] /// Error adding fw_cfg to bus. @@ -682,7 +692,7 @@ pub enum DeviceManagerError { /// Disk resizing failed. #[error("Disk resize error")] - DiskResize(#[source] virtio_devices::block::Error), + DiskResize(#[source] VirtioBlockError), /// Disk image type does not match expected type. #[error( @@ -737,7 +747,7 @@ impl DeviceRelocation for AddressManager { len: u64, pci_dev: &mut dyn PciDevice, region_type: PciBarRegionType, - ) -> std::result::Result<(), std::io::Error> { + ) -> result::Result<(), io::Error> { match region_type { PciBarRegionType::IoRegion => { let mut sys_allocator = self.allocator.lock().unwrap(); @@ -974,8 +984,8 @@ struct SevSnpPageAccessProxy { } #[cfg(feature = "sev_snp")] -impl std::fmt::Debug for SevSnpPageAccessProxy { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Debug for SevSnpPageAccessProxy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SNP Page access proxy") } } @@ -989,11 +999,11 @@ impl SevSnpPageAccessProxy { #[cfg(feature = "sev_snp")] impl AccessPlatform for SevSnpPageAccessProxy { - fn translate_gpa(&self, base: u64, _size: u64) -> std::result::Result { + fn translate_gpa(&self, base: u64, _size: u64) -> result::Result { Ok(base) } - fn translate_gva(&self, base: u64, size: u64) -> std::result::Result { + fn translate_gva(&self, base: u64, size: u64) -> result::Result { self.vm .gain_page_access(base, size as u32) .map_err(io::Error::other)?; @@ -1126,7 +1136,7 @@ pub struct DeviceManager { #[cfg(target_arch = "aarch64")] // GPIO device for AArch64 - gpio_device: Option>>, + gpio_device: Option>>, #[cfg(feature = "pvmemcontrol")] pvmemcontrol_devices: Option<( @@ -1251,8 +1261,7 @@ impl DeviceManager { }; let mut mmio32_aperture_weights: Vec = - std::iter::repeat_n(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT, num_pci_segments.into()) - .collect(); + iter::repeat_n(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT, num_pci_segments.into()).collect(); if let Some(pci_segments) = &config.lock().unwrap().pci_segments { for pci_segment in pci_segments.iter() { mmio32_aperture_weights[pci_segment.pci_segment as usize] = @@ -1272,8 +1281,7 @@ impl DeviceManager { ); let mut mmio64_aperture_weights: Vec = - std::iter::repeat_n(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT, num_pci_segments.into()) - .collect(); + iter::repeat_n(DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT, num_pci_segments.into()).collect(); if let Some(pci_segments) = &config.lock().unwrap().pci_segments { for pci_segment in pci_segments.iter() { mmio64_aperture_weights[pci_segment.pci_segment as usize] = @@ -1586,7 +1594,7 @@ impl DeviceManager { #[cfg(feature = "fw_cfg")] pub fn create_fw_cfg_device(&mut self) -> Result<(), DeviceManagerError> { - let fw_cfg = Arc::new(Mutex::new(devices::legacy::FwCfg::new( + let fw_cfg = Arc::new(Mutex::new(legacy::FwCfg::new( self.memory_manager.lock().as_ref().unwrap().guest_memory(), ))); @@ -1986,11 +1994,7 @@ impl DeviceManager { .allocator .lock() .unwrap() - .allocate_platform_mmio_addresses( - None, - devices::acpi::GED_DEVICE_ACPI_SIZE as u64, - None, - ) + .allocate_platform_mmio_addresses(None, acpi::GED_DEVICE_ACPI_SIZE as u64, None) .ok_or(DeviceManagerError::AllocateMmioAddress)?; let ged_device = Arc::new(Mutex::new(devices::AcpiGedDevice::new( interrupt_group, @@ -2002,7 +2006,7 @@ impl DeviceManager { .insert( ged_device.clone(), ged_address.0, - devices::acpi::GED_DEVICE_ACPI_SIZE as u64, + acpi::GED_DEVICE_ACPI_SIZE as u64, ) .map_err(DeviceManagerError::BusError)?; self.bus_devices @@ -2045,7 +2049,7 @@ impl DeviceManager { .vcpus_kill_signalled() .clone(); // Add a shutdown device (i8042) - let i8042 = Arc::new(Mutex::new(devices::legacy::I8042Device::new( + let i8042 = Arc::new(Mutex::new(legacy::I8042Device::new( reset_evt.try_clone().unwrap(), vcpus_kill_signalled.clone(), ))); @@ -2068,10 +2072,10 @@ impl DeviceManager { .last_addr() .0 + 1; - let mem_below_4g = std::cmp::min(arch::layout::MEM_32BIT_RESERVED_START.0, mem_size); - let mem_above_4g = mem_size.saturating_sub(arch::layout::RAM_64BIT_START.0); + let mem_below_4g = cmp::min(layout::MEM_32BIT_RESERVED_START.0, mem_size); + let mem_above_4g = mem_size.saturating_sub(layout::RAM_64BIT_START.0); - let cmos = Arc::new(Mutex::new(devices::legacy::Cmos::new( + let cmos = Arc::new(Mutex::new(legacy::Cmos::new( mem_below_4g, mem_above_4g, reset_evt, @@ -2086,7 +2090,7 @@ impl DeviceManager { .insert(cmos, 0x70, 0x2) .map_err(DeviceManagerError::BusError)?; - let fwdebug = Arc::new(Mutex::new(devices::legacy::FwDebugDevice::new())); + let fwdebug = Arc::new(Mutex::new(legacy::FwDebugDevice::new())); self.bus_devices .push(Arc::clone(&fwdebug) as Arc); @@ -2098,7 +2102,7 @@ impl DeviceManager { } // 0x80 debug port - let debug_port = Arc::new(Mutex::new(devices::legacy::DebugPort::new(self.timestamp))); + let debug_port = Arc::new(Mutex::new(legacy::DebugPort::new(self.timestamp))); self.bus_devices .push(Arc::clone(&debug_port) as Arc); self.address_manager @@ -2124,12 +2128,12 @@ impl DeviceManager { .allocate_irq() .unwrap(); - let rtc_device = Arc::new(Mutex::new(devices::legacy::Rtc::new())); + let rtc_device = Arc::new(Mutex::new(legacy::Rtc::new())); self.bus_devices .push(Arc::clone(&rtc_device) as Arc); - let addr = arch::layout::LEGACY_RTC_MAPPED_IO_START; + let addr = layout::LEGACY_RTC_MAPPED_IO_START; self.address_manager .mmio_bus @@ -2161,7 +2165,7 @@ impl DeviceManager { }) .map_err(DeviceManagerError::CreateInterruptGroup)?; - let gpio_device = Arc::new(Mutex::new(devices::legacy::Gpio::new( + let gpio_device = Arc::new(Mutex::new(legacy::Gpio::new( id.clone(), interrupt_group, state_from_id(snapshot, id.as_str()).map_err(DeviceManagerError::RestoreGetState)?, @@ -2170,7 +2174,7 @@ impl DeviceManager { self.bus_devices .push(Arc::clone(&gpio_device) as Arc); - let addr = arch::layout::LEGACY_GPIO_MAPPED_IO_START; + let addr = layout::LEGACY_GPIO_MAPPED_IO_START; self.address_manager .mmio_bus @@ -2316,7 +2320,7 @@ impl DeviceManager { }) .map_err(DeviceManagerError::CreateInterruptGroup)?; - let serial = Arc::new(Mutex::new(devices::legacy::Pl011::new( + let serial = Arc::new(Mutex::new(legacy::Pl011::new( id.clone(), interrupt_group, serial_writer, @@ -2327,7 +2331,7 @@ impl DeviceManager { self.bus_devices .push(Arc::clone(&serial) as Arc); - let addr = arch::layout::LEGACY_SERIAL_MAPPED_IO_START; + let addr = layout::LEGACY_SERIAL_MAPPED_IO_START; self.address_manager .mmio_bus @@ -2444,8 +2448,7 @@ impl DeviceManager { // SAFETY: FFI call to dup. Trivially safe. let stdin = unsafe { libc::dup(libc::STDIN_FILENO) }; if stdin == -1 { - return vmm_sys_util::errno::errno_result() - .map_err(DeviceManagerError::DupFd); + return errno::errno_result().map_err(DeviceManagerError::DupFd); } // SAFETY: stdin is valid and owned solely by us. let stdin = unsafe { File::from_raw_fd(stdin) }; @@ -2591,12 +2594,9 @@ impl DeviceManager { } #[cfg(not(target_arch = "riscv64"))] - fn add_tpm_device( - &mut self, - tpm_path: &Path, - ) -> DeviceManagerResult>> { + fn add_tpm_device(&mut self, tpm_path: &Path) -> DeviceManagerResult>> { // Create TPM Device - let tpm = devices::tpm::Tpm::new(tpm_path).map_err(|e| { + let tpm = tpm::Tpm::new(tpm_path).map_err(|e| { DeviceManagerError::CreateTpmDevice(anyhow!("Failed to create TPM Device : {e:?}")) })?; let tpm = Arc::new(Mutex::new(tpm)); @@ -2604,11 +2604,7 @@ impl DeviceManager { // Add TPM Device to mmio self.address_manager .mmio_bus - .insert( - tpm.clone(), - arch::layout::TPM_START.0, - arch::layout::TPM_SIZE, - ) + .insert(tpm.clone(), layout::TPM_START.0, layout::TPM_SIZE) .map_err(DeviceManagerError::BusError)?; Ok(tpm) @@ -2715,7 +2711,7 @@ impl DeviceManager { queue_size: disk_cfg.queue_size, }; let vhost_user_block = Arc::new(Mutex::new( - match virtio_devices::vhost_user::Blk::new( + match vhost_user::Blk::new( id.clone(), vu_cfg, self.seccomp_action.clone(), @@ -2945,7 +2941,7 @@ impl DeviceManager { VhostMode::Server => true, }; let vhost_user_net = Arc::new(Mutex::new( - match virtio_devices::vhost_user::Net::new( + match vhost_user::Net::new( id.clone(), net_cfg.mac, net_cfg.mtu, @@ -3204,7 +3200,7 @@ impl DeviceManager { if let Some(generic_vhost_user_socket) = generic_vhost_user_cfg.socket.to_str() { let generic_vhost_user_device = Arc::new(Mutex::new( - virtio_devices::vhost_user::GenericVhostUser::new( + vhost_user::GenericVhostUser::new( id.clone(), generic_vhost_user_socket, generic_vhost_user_cfg.queue_sizes.clone(), @@ -3274,7 +3270,7 @@ impl DeviceManager { if let Some(fs_socket) = fs_cfg.socket.to_str() { let virtio_fs_device = Arc::new(Mutex::new( - virtio_devices::vhost_user::Fs::new( + vhost_user::Fs::new( id.clone(), fs_socket, &fs_cfg.tag, @@ -3527,9 +3523,8 @@ impl DeviceManager { .socket .to_str() .ok_or(DeviceManagerError::CreateVsockConvertPath)?; - let backend = - virtio_devices::vsock::VsockUnixBackend::new(vsock_cfg.cid, socket_path.to_string()) - .map_err(DeviceManagerError::CreateVsockBackend)?; + let backend = vsock::VsockUnixBackend::new(vsock_cfg.cid, socket_path.to_string()) + .map_err(DeviceManagerError::CreateVsockBackend)?; let vsock_device = Arc::new(Mutex::new( virtio_devices::Vsock::new( @@ -3651,7 +3646,7 @@ impl DeviceManager { info!("Creating pvmemcontrol device: id = {id}"); let (pvmemcontrol_pci_device, pvmemcontrol_bus_device) = - devices::pvmemcontrol::PvmemcontrolDevice::make_device( + pvmemcontrol::PvmemcontrolDevice::make_device( id.clone(), self.memory_manager.lock().unwrap().guest_memory(), ); @@ -5843,7 +5838,7 @@ impl Aml for DeviceManager { #[cfg(target_arch = "aarch64")] &aml::Memory32Fixed::new( true, - arch::layout::LEGACY_SERIAL_MAPPED_IO_START.raw_value() as u32, + layout::LEGACY_SERIAL_MAPPED_IO_START.raw_value() as u32, MMIO_LEN as u32, ), ]), @@ -5939,7 +5934,7 @@ impl Snapshottable for DeviceManager { DEVICE_MANAGER_SNAPSHOT_ID.to_string() } - fn snapshot(&mut self) -> std::result::Result { + fn snapshot(&mut self) -> result::Result { let mut snapshot = Snapshot::from_data(SnapshotData::new_from_state(&self.state())?); // We aggregate all devices snapshots. @@ -5957,7 +5952,7 @@ impl Snapshottable for DeviceManager { impl Transportable for DeviceManager {} impl Migratable for DeviceManager { - fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> { + fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> { for (_, device_node) in self.device_tree.lock().unwrap().iter() { if let Some(migratable) = &device_node.migratable { migratable.lock().unwrap().start_dirty_log()?; @@ -5966,7 +5961,7 @@ impl Migratable for DeviceManager { Ok(()) } - fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> { + fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> { for (_, device_node) in self.device_tree.lock().unwrap().iter() { if let Some(migratable) = &device_node.migratable { migratable.lock().unwrap().stop_dirty_log()?; @@ -5975,7 +5970,7 @@ impl Migratable for DeviceManager { Ok(()) } - fn dirty_log(&mut self) -> std::result::Result { + fn dirty_log(&mut self) -> result::Result { let mut tables = Vec::new(); for (_, device_node) in self.device_tree.lock().unwrap().iter() { if let Some(migratable) = &device_node.migratable { @@ -5985,7 +5980,7 @@ impl Migratable for DeviceManager { Ok(MemoryRangeTable::new_from_tables(tables)) } - fn start_migration(&mut self) -> std::result::Result<(), MigratableError> { + fn start_migration(&mut self) -> result::Result<(), MigratableError> { for (_, device_node) in self.device_tree.lock().unwrap().iter() { if let Some(migratable) = &device_node.migratable { migratable.lock().unwrap().start_migration()?; @@ -5994,7 +5989,7 @@ impl Migratable for DeviceManager { Ok(()) } - fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { + fn complete_migration(&mut self) -> result::Result<(), MigratableError> { for (_, device_node) in self.device_tree.lock().unwrap().iter() { if let Some(migratable) = &device_node.migratable { migratable.lock().unwrap().complete_migration()?; @@ -6064,7 +6059,7 @@ impl BusDevice for DeviceManager { debug!("PCI_HP_REG_R: base 0x{base:x}, offset 0x{offset:x}, data {data:?}"); } - fn write(&mut self, base: u64, offset: u64, data: &[u8]) -> Option> { + fn write(&mut self, base: u64, offset: u64, data: &[u8]) -> Option> { match offset { B0EJ_FIELD_OFFSET => { if data.len() != B0EJ_FIELD_SIZE { diff --git a/vmm/src/device_tree.rs b/vmm/src/device_tree.rs index 6116cd55b..2cc0c45b6 100644 --- a/vmm/src/device_tree.rs +++ b/vmm/src/device_tree.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 -use std::collections::HashMap; +use std::collections::{HashMap, hash_map}; use std::sync::{Arc, Mutex}; use pci::PciBdf; @@ -75,7 +75,7 @@ impl DeviceTree { pub fn remove(&mut self, k: &str) -> Option { self.0.remove(k) } - pub fn iter(&self) -> std::collections::hash_map::Iter<'_, String, DeviceNode> { + pub fn iter(&self) -> hash_map::Iter<'_, String, DeviceNode> { self.0.iter() } pub fn breadth_first_traversal(&self) -> BftIter<'_> { diff --git a/vmm/src/gdb.rs b/vmm/src/gdb.rs index 82a5d63a9..2f67f929e 100644 --- a/vmm/src/gdb.rs +++ b/vmm/src/gdb.rs @@ -7,6 +7,7 @@ use std::os::unix::net::UnixListener; use std::sync::mpsc; +use std::{cmp, io, path, result}; use gdbstub::arch::Arch; use gdbstub::common::{Signal, Tid}; @@ -32,8 +33,9 @@ use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs; use log::{error, info}; use thiserror::Error; use vm_memory::{GuestAddress, GuestMemoryAtomic, GuestMemoryError}; +use vmm_sys_util::eventfd; -use crate::GuestMemoryMmap; +use crate::{GuestMemoryMmap, cpu, vm}; type ArchUsize = u64; @@ -46,15 +48,15 @@ pub enum DebuggableError { #[error("Resuming failed")] Resume(#[source] vm_migration::MigratableError), #[error("Reading registers failed")] - ReadRegs(#[source] crate::cpu::Error), + ReadRegs(#[source] cpu::Error), #[error("Writing registers failed")] - WriteRegs(#[source] crate::cpu::Error), + WriteRegs(#[source] cpu::Error), #[error("Reading memory failed")] ReadMem(#[source] GuestMemoryError), #[error("Writing memory failed")] WriteMem(#[source] GuestMemoryError), #[error("Translating GVA failed")] - TranslateGva(#[source] crate::cpu::Error), + TranslateGva(#[source] cpu::Error), #[error("The lock is poisened")] PoisonedState, } @@ -66,45 +68,41 @@ pub trait Debuggable: vm_migration::Pausable { addrs: &[GuestAddress], singlestep: bool, ) -> Result<(), DebuggableError>; - fn debug_pause(&mut self) -> std::result::Result<(), DebuggableError>; - fn debug_resume(&mut self) -> std::result::Result<(), DebuggableError>; - fn read_regs(&self, cpu_id: usize) -> std::result::Result; - fn write_regs( - &self, - cpu_id: usize, - regs: &CoreRegs, - ) -> std::result::Result<(), DebuggableError>; + fn debug_pause(&mut self) -> result::Result<(), DebuggableError>; + fn debug_resume(&mut self) -> result::Result<(), DebuggableError>; + fn read_regs(&self, cpu_id: usize) -> result::Result; + fn write_regs(&self, cpu_id: usize, regs: &CoreRegs) -> result::Result<(), DebuggableError>; fn read_mem( &self, guest_memory: &GuestMemoryAtomic, cpu_id: usize, vaddr: GuestAddress, len: usize, - ) -> std::result::Result, DebuggableError>; + ) -> result::Result, DebuggableError>; fn write_mem( &self, guest_memory: &GuestMemoryAtomic, cpu_id: usize, vaddr: &GuestAddress, data: &[u8], - ) -> std::result::Result<(), DebuggableError>; + ) -> result::Result<(), DebuggableError>; fn active_vcpus(&self) -> usize; } #[derive(Error, Debug)] pub enum Error { #[error("VM failed")] - Vm(#[source] crate::vm::Error), + Vm(#[source] vm::Error), #[error("GDB request failed")] GdbRequest, #[error("GDB couldn't be notified")] - GdbResponseNotify(#[source] std::io::Error), + GdbResponseNotify(#[source] io::Error), #[error("GDB response failed")] GdbResponse(#[source] mpsc::RecvError), #[error("GDB response timeout")] GdbResponseTimeout(#[source] mpsc::RecvTimeoutError), } -type GdbResult = std::result::Result; +type GdbResult = result::Result; #[derive(Debug)] pub struct GdbRequest { @@ -126,7 +124,7 @@ pub enum GdbRequestPayload { ActiveVcpus, } -pub type GdbResponse = std::result::Result; +pub type GdbResponse = result::Result; #[derive(Debug)] pub enum GdbResponsePayload { @@ -138,8 +136,8 @@ pub enum GdbResponsePayload { pub struct GdbStub { gdb_sender: mpsc::Sender, - gdb_event: vmm_sys_util::eventfd::EventFd, - vm_event: vmm_sys_util::eventfd::EventFd, + gdb_event: eventfd::EventFd, + vm_event: eventfd::EventFd, hw_breakpoints: Vec, single_step: bool, } @@ -147,8 +145,8 @@ pub struct GdbStub { impl GdbStub { pub fn new( gdb_sender: mpsc::Sender, - gdb_event: vmm_sys_util::eventfd::EventFd, - vm_event: vmm_sys_util::eventfd::EventFd, + gdb_event: eventfd::EventFd, + vm_event: eventfd::EventFd, hw_breakpoints: usize, ) -> Self { Self { @@ -165,7 +163,7 @@ impl GdbStub { payload: GdbRequestPayload, cpu_id: usize, ) -> GdbResult { - let (response_sender, response_receiver) = std::sync::mpsc::channel(); + let (response_sender, response_receiver) = mpsc::channel(); let request = GdbRequest { sender: response_sender, payload, @@ -265,7 +263,7 @@ impl MultiThreadBase for GdbStub { for (dst, v) in data.iter_mut().zip(r.iter()) { *dst = *v; } - Ok(std::cmp::min(data.len(), r.len())) + Ok(cmp::min(data.len(), r.len())) } Ok(s) => { error!("Unexpected response for ReadMem: {s:?}"); @@ -445,7 +443,7 @@ enum GdbEventLoop {} impl run_blocking::BlockingEventLoop for GdbEventLoop { type Target = GdbStub; - type Connection = Box>; + type Connection = Box>; type StopReason = MultiThreadStopReason; fn wait_for_stop_reason( @@ -478,7 +476,7 @@ impl run_blocking::BlockingEventLoop for GdbEventLoop { return Ok(run_blocking::Event::TargetStopped(stop_reason)); } Err(e) => { - if e.kind() != std::io::ErrorKind::WouldBlock { + if e.kind() != io::ErrorKind::WouldBlock { return Err(run_blocking::WaitForStopReasonError::Connection(e)); } } @@ -506,7 +504,7 @@ impl run_blocking::BlockingEventLoop for GdbEventLoop { } } -pub fn gdb_thread(mut gdbstub: GdbStub, path: &std::path::Path) { +pub fn gdb_thread(mut gdbstub: GdbStub, path: &path::Path) { let listener = match UnixListener::bind(path) { Ok(s) => s, Err(e) => { @@ -525,7 +523,7 @@ pub fn gdb_thread(mut gdbstub: GdbStub, path: &std::path::Path) { }; info!("GDB connected from {addr:?}"); - let connection: Box> = Box::new(stream); + let connection: Box> = Box::new(stream); let gdb = gdbstub::stub::GdbStub::new(connection); match gdb.run_blocking::(&mut gdbstub) { diff --git a/vmm/src/igvm/igvm_loader.rs b/vmm/src/igvm/igvm_loader.rs index 560f73e10..f8e21f3e6 100644 --- a/vmm/src/igvm/igvm_loader.rs +++ b/vmm/src/igvm/igvm_loader.rs @@ -2,10 +2,15 @@ // // Copyright © 2023, Microsoft Corporation // +#[cfg(all(feature = "kvm", feature = "sev_snp"))] +use std::cmp; use std::collections::HashMap; use std::ffi::CString; +#[cfg(feature = "kvm")] +use std::iter; use std::mem::size_of; use std::sync::{Arc, Mutex}; +use std::{ffi, io}; use hypervisor::HypervisorType; #[cfg(feature = "sev_snp")] @@ -31,15 +36,18 @@ use vm_memory::Bytes; use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemory}; #[cfg(all(feature = "kvm", feature = "sev_snp"))] use vm_migration::Snapshottable; +#[cfg(all(feature = "kvm", feature = "sev_snp", feature = "fw_cfg"))] +use vmm_sys_util::errno; use zerocopy::IntoBytes; #[cfg(all(feature = "kvm", feature = "sev_snp"))] use zerocopy::{FromBytes, FromZeros}; #[cfg(feature = "sev_snp")] use crate::GuestMemoryMmap; +use crate::cpu; use crate::cpu::CpuManager; use crate::igvm::loader::Loader; -use crate::igvm::{BootPageAcceptance, HV_PAGE_SIZE, IgvmLoadedInfo, StartupMemoryType}; +use crate::igvm::{BootPageAcceptance, HV_PAGE_SIZE, IgvmLoadedInfo, StartupMemoryType, loader}; use crate::memory_manager::{Error as MemoryManagerError, MemoryManager}; #[cfg(all(feature = "kvm", feature = "sev_snp", feature = "fw_cfg"))] use crate::sev::{MeasuredBootInfo, SEV_HASH_BLOCK_ADDRESS, SEV_HASH_BLOCK_SIZE}; @@ -77,9 +85,9 @@ pub struct SnpCpuidInfo { #[derive(Debug, Error)] pub enum Error { #[error("command line is not a valid C string")] - InvalidCommandLine(#[source] std::ffi::NulError), + InvalidCommandLine(#[source] ffi::NulError), #[error("failed to read igvm file")] - Igvm(#[source] std::io::Error), + Igvm(#[source] io::Error), #[error("invalid igvm file")] InvalidIgvmFile(#[source] igvm::Error), #[error("multiple SNP ID blocks in IGVM file")] @@ -87,7 +95,7 @@ pub enum Error { #[error("invalid guest memory map")] InvalidGuestMemmap(#[source] arch::Error), #[error("loader error")] - Loader(#[source] crate::igvm::loader::Error), + Loader(#[source] loader::Error), #[error("parameter too large for parameter area")] ParameterTooLarge, #[error("Error importing isolated pages")] @@ -101,10 +109,10 @@ pub enum Error { #[error("IGVM file not provided")] MissingIgvm, #[error("Error applying VMSA to vCPU registers: {0}")] - SetVmsa(#[source] crate::cpu::Error), + SetVmsa(#[source] cpu::Error), #[cfg(all(feature = "kvm", feature = "sev_snp", feature = "fw_cfg"))] #[error("Error building SEV-SNP measured boot hash block")] - MeasuredBoot(#[source] vmm_sys_util::errno::Error), + MeasuredBoot(#[source] errno::Error), #[cfg(all(feature = "kvm", feature = "sev_snp", feature = "fw_cfg"))] #[error( "igvmfile inserts unmeasured parameter area [0x{region_start:x}, 0x{region_end:x}) over SEV-SNP kernel hashes region [0x{hash_start:x}, 0x{hash_end:x})" @@ -441,7 +449,7 @@ pub fn load_igvm( let mut new_cp = SnpCpuidInfo::new_zeroed(); let entries = cpu_manager.lock().unwrap().common_cpuid(); - let cp_count = std::cmp::min(SNP_CPUID_LIMIT as usize, entries.len()); + let cp_count = cmp::min(SNP_CPUID_LIMIT as usize, entries.len()); // TODO: Filter cpuid rather than truncate for (i, entry) in entries.iter().enumerate().take(cp_count) { new_cp.entries[i].eax_in = entry.function; @@ -857,7 +865,7 @@ pub fn load_igvm( // https://elixir.bootlin.com/linux/v6.11/source/arch/x86/kvm/svm/sev.c#L2322 let mut updated_cp = SnpCpuidInfo::new_zeroed(); let _ = guest_memory.read(updated_cp.as_mut_bytes(), GuestAddress(group[0].gpa)); - for (set, got) in std::iter::zip(new_cp.entries.iter(), updated_cp.entries.iter()) { + for (set, got) in iter::zip(new_cp.entries.iter(), updated_cp.entries.iter()) { if set != got { error!("Set cpuid fn: {set:#x?}, but firmware expects: {got:#x?}"); } diff --git a/vmm/src/igvm/mod.rs b/vmm/src/igvm/mod.rs index 698916637..6a671dea6 100644 --- a/vmm/src/igvm/mod.rs +++ b/vmm/src/igvm/mod.rs @@ -27,6 +27,7 @@ pub mod igvm_loader; mod loader; +use std::fs; use std::path::Path; use igvm::snp_defs::SevVmsa; @@ -35,7 +36,7 @@ use igvm_defs::IGVM_VHS_SNP_ID_BLOCK; use zerocopy::FromZeros; pub fn parse_igvm(igvm_path: &Path) -> Result { - let file_contents = std::fs::read(igvm_path).map_err(igvm_loader::Error::Igvm)?; + let file_contents = fs::read(igvm_path).map_err(igvm_loader::Error::Igvm)?; IgvmFile::new_from_binary(&file_contents, Some(IsolationType::Snp)) .map_err(igvm_loader::Error::InvalidIgvmFile) } diff --git a/vmm/src/interrupt.rs b/vmm/src/interrupt.rs index 498ac96c0..ec01c02d6 100644 --- a/vmm/src/interrupt.rs +++ b/vmm/src/interrupt.rs @@ -5,11 +5,13 @@ use std::collections::HashMap; use std::io; +use std::mem::replace; use std::sync::{Arc, Mutex}; use devices::interrupt_controller::InterruptController; use hypervisor::IrqRoutingEntry; use vm_allocator::SystemAllocator; +use vm_device::interrupt; use vm_device::interrupt::{ InterruptIndex, InterruptManager, InterruptSourceConfig, InterruptSourceGroup, LegacyIrqGroupConfig, MsiIrqGroupConfig, @@ -17,7 +19,7 @@ use vm_device::interrupt::{ use vmm_sys_util::eventfd::EventFd; /// Reuse std::io::Result to simplify interoperability among crates. -type Result = std::io::Result; +type Result = io::Result; /// Per-interrupt routing state for an MSI/MSI-X vector. /// @@ -125,7 +127,7 @@ impl InterruptRoute { } fn set_notifier(&mut self, eventfd: Option, vm: &dyn hypervisor::Vm) -> Result<()> { - let old_irqfd = core::mem::replace(&mut self.irq_fd, eventfd); + let old_irqfd = replace(&mut self.irq_fd, eventfd); if self.registered { // A registered route must have a GSI allocated, since enable() // only sets registered=true after using a valid GSI. @@ -434,7 +436,7 @@ impl InterruptManager for MsiInterruptManager { fn create_group_mut( &self, config: Self::GroupConfig, - ) -> vm_device::interrupt::Result>> { + ) -> interrupt::Result>> { let r = self.create_group_raw(config)?; Ok(Arc::new(Mutex::new(r))) } diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 7a27b6925..8575b75e1 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -3,9 +3,6 @@ // SPDX-License-Identifier: Apache-2.0 // -// TODO: Trim qualified paths in this crate, then drop this expectation. -#![expect(clippy::absolute_paths)] - use std::collections::HashMap; use std::fs::File; use std::io::{Read, Write, stdout}; @@ -13,10 +10,12 @@ use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::panic::AssertUnwindSafe; #[cfg(feature = "guest_debug")] use std::path::PathBuf; +#[cfg(feature = "guest_debug")] +use std::sync::mpsc; use std::sync::mpsc::{Receiver, RecvError, SendError, Sender, channel}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; -use std::{io, mem, result, thread}; +use std::{any, io, mem, panic, path, process, result, thread}; use anyhow::{Context, anyhow}; #[cfg(feature = "dbus_api")] @@ -26,6 +25,8 @@ use api::http::HttpApiHandle; use arch::x86_64::MAX_SUPPORTED_CPUS_LEGACY; use console_devices::{ConsoleInfo, pre_create_console_devices}; use event_monitor::event; +#[cfg(all(feature = "kvm", target_arch = "x86_64"))] +use hypervisor::arch::x86; use landlock::LandlockError; use libc::{EFD_NONBLOCK, SIGINT, SIGTERM, TCSANOW, tcsetattr, termios}; use log::{debug, error, info, trace, warn}; @@ -202,7 +203,7 @@ pub enum Error { /// The API server socket is already in use by another running instance #[error("API socket {0:?} is already in use by another running instance")] - ApiSocketInUse(std::path::PathBuf), + ApiSocketInUse(path::PathBuf), #[cfg(feature = "guest_debug")] #[error("Failed to start the GDB thread")] @@ -222,7 +223,7 @@ pub enum Error { SignalHandlerSpawn(#[source] io::Error), #[error("Failed to join on threads: {0:?}")] - ThreadCleanup(std::boxed::Box), + ThreadCleanup(Box), /// Cannot create Landlock object #[error("Error creating landlock object")] @@ -347,7 +348,7 @@ pub struct PciDeviceInfo { } impl Serialize for PciDeviceInfo { - fn serialize(&self, serializer: S) -> std::result::Result + fn serialize(&self, serializer: S) -> result::Result where S: Serializer, { @@ -423,7 +424,7 @@ pub fn start_event_monitor_thread( })?; } - std::panic::catch_unwind(AssertUnwindSafe(move || { + panic::catch_unwind(AssertUnwindSafe(move || { while let Ok(event) = monitor.rx.recv() { let event = Arc::new(event); @@ -469,7 +470,7 @@ pub fn start_vmm_thread( #[cfg(feature = "guest_debug")] let gdb_hw_breakpoints = hypervisor.get_guest_debug_hw_bps(); #[cfg(feature = "guest_debug")] - let (gdb_sender, gdb_receiver) = std::sync::mpsc::channel(); + let (gdb_sender, gdb_receiver) = mpsc::channel(); #[cfg(feature = "guest_debug")] let gdb_debug_event = debug_event.try_clone().map_err(Error::EventFdClone)?; #[cfg(feature = "guest_debug")] @@ -593,7 +594,7 @@ where pub struct VmMigrationConfig { vm_config: Arc>, #[cfg(all(feature = "kvm", target_arch = "x86_64"))] - common_cpuid: Vec, + common_cpuid: Vec, memory_manager_data: MemoryManagerSnapshotData, } @@ -780,7 +781,7 @@ impl Vmm { warn!("Failed to lock original termios"); } - std::process::exit(1); + process::exit(1); } } _ => (), @@ -826,7 +827,7 @@ impl Vmm { } } - std::panic::catch_unwind(AssertUnwindSafe(|| { + panic::catch_unwind(AssertUnwindSafe(|| { Vmm::signal_handler(signals, original_termios_opt.as_ref(), &exit_evt); })) .map_err(|_| { @@ -918,7 +919,7 @@ impl Vmm { /// Try to receive a file descriptor from a socket. Returns the slot number and the file descriptor. fn vm_receive_memory_fd( socket: &mut SocketStream, - ) -> std::result::Result<(u32, File), MigratableError> { + ) -> result::Result<(u32, File), MigratableError> { if let SocketStream::Unix(unix_socket) = socket { let mut buf = [0u8; 4]; let (_, file) = unix_socket.recv_with_fd(&mut buf).map_err(|e| { @@ -945,7 +946,7 @@ impl Vmm { state: ReceiveMigrationState, req: &Request, receive_data_migration: &VmReceiveMigrationData, - ) -> std::result::Result { + ) -> result::Result { use ReceiveMigrationState::*; let invalid_command = |state: &str, cmd: Command| { @@ -958,7 +959,7 @@ impl Vmm { let mut configure_vm = |socket: &mut SocketStream, memory_files: HashMap| - -> std::result::Result { + -> result::Result { let shared_backing = !memory_files.is_empty(); let memory_manager = self.vm_receive_config(req, socket, memory_files, mode)?; let guest_memory = memory_manager.lock().unwrap().guest_memory(); @@ -982,7 +983,7 @@ impl Vmm { let recv_memory_fd = |socket: &mut SocketStream, mut memory_files: Vec<(u32, File)>| - -> std::result::Result, MigratableError> { + -> result::Result, MigratableError> { let (slot, file) = Self::vm_receive_memory_fd(socket)?; memory_files.push((slot, file)); @@ -1083,7 +1084,7 @@ impl Vmm { socket: &mut SocketStream, mut config_data: ReceiveMigrationConfiguredData, receive_data_migration: &VmReceiveMigrationData, - ) -> std::result::Result { + ) -> result::Result { let state_receive_begin = Instant::now(); // Serve faults before restore so accesses during restore resolve on demand. @@ -1136,7 +1137,7 @@ impl Vmm { socket: &mut T, existing_memory_files: HashMap, mode: MigrationMode, - ) -> std::result::Result>, MigratableError> + ) -> result::Result>, MigratableError> where T: Read, { @@ -1243,7 +1244,7 @@ impl Vmm { req: &Request, socket: &mut T, mm: Arc>, - ) -> std::result::Result< + ) -> result::Result< ( Duration, /* state receive + deserialize */ Duration, /* restoring */ @@ -1836,7 +1837,7 @@ impl Vmm { fn vm_check_cpuid_compatibility( &self, src_vm_config: &Arc>, - src_vm_cpuid: &[hypervisor::arch::x86::CpuIdEntry], + src_vm_cpuid: &[x86::CpuIdEntry], ) -> result::Result<(), MigratableError> { #[cfg(feature = "tdx")] if src_vm_config.lock().unwrap().is_tdx_enabled() { @@ -1889,7 +1890,7 @@ impl Vmm { vm_config: Arc>, prefault: bool, memory_restore_mode: MemoryRestoreMode, - ) -> std::result::Result<(), VmError> { + ) -> result::Result<(), VmError> { match &self.vm { VmOwnership::Owned(_) => Err(VmError::VmAlreadyCreated), VmOwnership::Migration { .. } => Err(VmError::VmMigrating), @@ -2509,7 +2510,7 @@ impl RequestHandler for Vmm { VmmPingResponse { build_version, version, - pid: std::process::id() as i64, + pid: process::id() as i64, features: feature_list(), } } diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 2a94171a9..f0faafa8e 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -8,6 +8,7 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::fs::{File, OpenOptions}; use std::io::{self, Seek, SeekFrom}; +use std::mem::{MaybeUninit, zeroed}; use std::num::NonZeroUsize; use std::ops::{BitAnd, Not, Sub}; use std::os::fd::{AsFd, OwnedFd}; @@ -16,11 +17,11 @@ use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::mpsc::{self, Receiver, SyncSender}; use std::sync::{Arc, Barrier, Mutex}; -use std::{ffi, result, thread}; +use std::{cmp, ffi, panic, result, thread, time}; use acpi_tables::{Aml, aml}; use anyhow::anyhow; -use arch::RegionType; +use arch::{RegionType, layout}; #[cfg(target_arch = "x86_64")] use devices::ioapic; #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] @@ -31,6 +32,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use tracer::trace_scoped; use virtio_devices::BlocksState; +use virtio_devices::mem::Error as VirtioMemError; #[cfg(target_arch = "x86_64")] use vm_allocator::GsiApic; use vm_allocator::{AddressAllocator, MemorySlotAllocator, SystemAllocator}; @@ -62,7 +64,7 @@ use crate::uffd::{ UffdRange, }; use crate::vm_config::{HotplugMethod, MemoryConfig, MemoryZoneConfig}; -use crate::{GuestMemoryMmap, GuestRegionMmap, MEMORY_MANAGER_SNAPSHOT_ID}; +use crate::{GuestMemoryMmap, GuestRegionMmap, MEMORY_MANAGER_SNAPSHOT_ID, userfaultfd}; struct UffdHandler { stop_event: EventFd, @@ -297,7 +299,7 @@ pub enum Error { /// Failed to virtio-mem resize #[error("Failed to virtio-mem resize")] - VirtioMemResizeFail(#[source] virtio_devices::mem::Error), + VirtioMemResizeFail(#[source] VirtioMemError), /// Cannot restore VM #[error("Cannot restore VM")] @@ -314,7 +316,7 @@ pub enum Error { /// Failed creating a new MmapRegion instance. #[cfg(target_arch = "x86_64")] #[error("Failed creating a new MmapRegion instance")] - NewMmapRegion(#[source] vm_memory::mmap::MmapRegionError), + NewMmapRegion(#[source] MmapRegionError), /// No memory zones found. #[error("No memory zones found")] @@ -448,14 +450,12 @@ fn mmio_address_space_size(phys_bits: u8) -> u64 { // See: https://github.com/torvalds/linux/blob/v6.3/fs/hugetlbfs/inode.c#L1169 fn statfs_get_bsize(path: &str) -> Result { let path = ffi::CString::new(path).map_err(Error::InvalidMemoryPath)?; - let mut buf = std::mem::MaybeUninit::::uninit(); + let mut buf = MaybeUninit::::uninit(); // SAFETY: FFI call with a valid path and buffer let ret = unsafe { libc::statfs(path.as_ptr(), buf.as_mut_ptr()) }; if ret != 0 { - return Err(Error::GetFileSystemBlockSize( - std::io::Error::last_os_error(), - )); + return Err(Error::GetFileSystemBlockSize(io::Error::last_os_error())); } // SAFETY: `buf` is valid at this point @@ -494,7 +494,7 @@ fn memory_zone_get_align_size(zone: &MemoryZoneConfig) -> Result { pathbuf.to_str().ok_or(Error::InvalidMemoryParameters) })?; - let align_size = std::cmp::max(page_size, statfs_get_bsize(path)?); + let align_size = cmp::max(page_size, statfs_get_bsize(path)?); Ok(align_size) } @@ -1009,8 +1009,8 @@ impl MemoryManager { } })?; - if ioctls & crate::userfaultfd::UFFD_API_RANGE_IOCTLS_BASIC - != crate::userfaultfd::UFFD_API_RANGE_IOCTLS_BASIC + if ioctls & userfaultfd::UFFD_API_RANGE_IOCTLS_BASIC + != userfaultfd::UFFD_API_RANGE_IOCTLS_BASIC { return Err(UffdError::MissingIoctlSupport { addr: host_addr, @@ -1059,7 +1059,7 @@ impl MemoryManager { let handle = thread::Builder::new() .name("uffd-handler".to_string()) .spawn(move || { - std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || { + panic::catch_unwind(panic::AssertUnwindSafe(move || { let result = Self::uffd_handler_loop( uffd_fd, thread_stop_event, @@ -1106,10 +1106,10 @@ impl MemoryManager { fn required_uffd_features(&self) -> u64 { let mut features = 0u64; if self.memory_zones.values().any(|z| z.shared || !z.hugepages) { - features |= crate::userfaultfd::UFFD_FEATURE_MISSING_SHMEM; + features |= userfaultfd::UFFD_FEATURE_MISSING_SHMEM; } if self.memory_zones.values().any(|z| z.hugepages) { - features |= crate::userfaultfd::UFFD_FEATURE_MISSING_HUGETLBFS; + features |= userfaultfd::UFFD_FEATURE_MISSING_HUGETLBFS; } features } @@ -1166,7 +1166,7 @@ impl MemoryManager { // means prefault was given up due to an error (natural completion // returns from the function instead). let mut prefault_cursor: Option<(usize, u64)> = (!ranges.is_empty()).then_some((0, 0)); - let prefault_start = std::time::Instant::now(); + let prefault_start = time::Instant::now(); const EVENT_STOP: u64 = 0; const EVENT_UFFD: u64 = 1; @@ -1230,13 +1230,13 @@ impl MemoryManager { if got_uffd_data { // SAFETY: UffdMsg is a plain repr(C) struct, safe to zero-init. - let mut msg: uffd::UffdMsg = unsafe { std::mem::zeroed() }; + let mut msg: uffd::UffdMsg = unsafe { zeroed() }; // SAFETY: reading a uffd_msg-sized struct from the valid uffd fd. let n = unsafe { libc::read( uffd_raw_fd, (&raw mut msg).cast(), - std::mem::size_of::(), + size_of::(), ) }; if n < 0 { @@ -1250,14 +1250,14 @@ impl MemoryManager { info!("UFFD handler: EOF on fd, exiting"); return Ok(()); } - if n as usize != std::mem::size_of::() { + if n as usize != size_of::() { return Err(io::Error::new( io::ErrorKind::UnexpectedEof, "Short read from userfaultfd", )); } - if msg.event != crate::userfaultfd::UFFD_EVENT_PAGEFAULT { + if msg.event != userfaultfd::UFFD_EVENT_PAGEFAULT { continue; } @@ -1566,11 +1566,11 @@ impl MemoryManager { // 4 MiB memory is mapped to simulate the flash. let uefi_mem_slot = self.allocate_memory_slot(); let uefi_region = GuestRegionMmap::new( - MmapRegion::new(arch::layout::UEFI_SIZE as usize).unwrap(), - arch::layout::UEFI_START, + MmapRegion::new(layout::UEFI_SIZE as usize).unwrap(), + layout::UEFI_START, ) .unwrap(); - const _: () = assert!(core::mem::size_of::() == core::mem::size_of::()); + const _: () = assert!(size_of::() == size_of::()); // SAFETY: guaranteed by GuestRegionMmap unsafe { @@ -2092,8 +2092,7 @@ impl MemoryManager { // over mmap_sem between thread stack allocation and page faulting. barrier.wait(); let pages = pages_per_thread + if i < remainder { 1 } else { 0 }; - let offset = - page_size * ((i * pages_per_thread) + std::cmp::min(i, remainder)); + let offset = page_size * ((i * pages_per_thread) + cmp::min(i, remainder)); // SAFETY: FFI call with correct arguments let ret = unsafe { let addr = r.as_ptr().add(offset); @@ -2186,7 +2185,7 @@ impl MemoryManager { .map_or(Ok("/dev/hugepages"), |pathbuf| { pathbuf.to_str().ok_or(Error::InvalidMemoryParameters) })?; - let align_size = std::cmp::max(page_size, statfs_get_bsize(path)?); + let align_size = cmp::max(page_size, statfs_get_bsize(path)?); Ok(align_size) } } @@ -2199,17 +2198,14 @@ impl MemoryManager { // SAFETY: FFI call. Trivially safe. let procs = unsafe { libc::sysconf(_SC_NPROCESSORS_ONLN) }; if procs > 0 { - n = std::cmp::min(procs as usize, MAX_PREFAULT_THREAD_COUNT); + n = cmp::min(procs as usize, MAX_PREFAULT_THREAD_COUNT); } // Do not create more threads than pages being allocated. - n = std::cmp::min(n, num_pages); + n = cmp::min(n, num_pages); // Do not create threads to allocate less than 64 MiB of memory. - n = std::cmp::min( - n, - std::cmp::max(1, page_size * num_pages / (64 * (1 << 26))), - ); + n = cmp::min(n, cmp::max(1, page_size * num_pages / (64 * (1 << 26)))); n } @@ -2245,8 +2241,8 @@ impl MemoryManager { .ok_or(Error::GuestAddressOverFlow)?; #[cfg(not(target_arch = "riscv64"))] - if mem_end < arch::layout::MEM_32BIT_RESERVED_START { - return Ok(arch::layout::RAM_64BIT_START); + if mem_end < layout::MEM_32BIT_RESERVED_START { + return Ok(layout::RAM_64BIT_START); } Ok(start_addr) @@ -2614,7 +2610,7 @@ impl MemoryManager { } pub fn is_hardlink(f: &File) -> bool { - let mut stat = std::mem::MaybeUninit::::uninit(); + let mut stat = MaybeUninit::::uninit(); // SAFETY: FFI call with correct arguments let ret = unsafe { libc::fstat(f.as_raw_fd(), stat.as_mut_ptr()) }; if ret != 0 { @@ -2650,7 +2646,7 @@ impl MemoryManager { pub fn memory_range_table( &self, snapshot: bool, - ) -> std::result::Result { + ) -> result::Result { let mut table = MemoryRangeTable::default(); for memory_zone in self.memory_zones.values() { @@ -2755,7 +2751,7 @@ impl MemoryManager { pub fn coredump_iterate_save_mem( &mut self, dump_state: &DumpState, - ) -> std::result::Result<(), GuestDebuggableError> { + ) -> result::Result<(), GuestDebuggableError> { let snapshot_memory_ranges = self .memory_range_table(false) .map_err(|e| GuestDebuggableError::Coredump(e.into()))?; @@ -3283,7 +3279,7 @@ impl Migratable for MemoryManager { // Also, reset the dirty bitmap logged by the vmm. // Just before we do a bulk copy we want to start/clear the dirty log so that // pages touched during our bulk copy are tracked. - fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> { + fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> { self.vm.start_dirty_log().map_err(|e| { MigratableError::MigrateSend(anyhow!("Error starting VM dirty log {e}")) })?; @@ -3295,7 +3291,7 @@ impl Migratable for MemoryManager { Ok(()) } - fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> { + fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> { self.vm.stop_dirty_log().map_err(|e| { MigratableError::MigrateSend(anyhow!("Error stopping VM dirty log {e}")) })?; @@ -3305,7 +3301,7 @@ impl Migratable for MemoryManager { // Generate a table for the pages that are dirty. The dirty pages are collapsed // together in the table if they are contiguous. - fn dirty_log(&mut self) -> std::result::Result { + fn dirty_log(&mut self) -> result::Result { let mut table = MemoryRangeTable::default(); for r in &self.guest_ram_mappings { let vm_dirty_bitmap = self.vm.get_dirty_log(r.slot, r.gpa, r.size).map_err(|e| { diff --git a/vmm/src/migration/mod.rs b/vmm/src/migration/mod.rs index 05b64cead..2d94a3136 100644 --- a/vmm/src/migration/mod.rs +++ b/vmm/src/migration/mod.rs @@ -5,6 +5,7 @@ use std::fs::File; use std::io::Read; use std::path::PathBuf; +use std::result; use anyhow::anyhow; use vm_migration::{MigratableError, Snapshot}; @@ -20,7 +21,7 @@ pub(crate) mod worker; pub const SNAPSHOT_STATE_FILE: &str = "state.json"; pub const SNAPSHOT_CONFIG_FILE: &str = "config.json"; -pub fn url_to_path(url: &str) -> std::result::Result { +pub fn url_to_path(url: &str) -> result::Result { let path: PathBuf = url .strip_prefix("file://") .ok_or_else(|| { @@ -38,7 +39,7 @@ pub fn url_to_path(url: &str) -> std::result::Result { } #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] -pub fn url_to_file(url: &str) -> std::result::Result { +pub fn url_to_file(url: &str) -> result::Result { let file: PathBuf = url .strip_prefix("file://") .ok_or_else(|| { @@ -49,7 +50,7 @@ pub fn url_to_file(url: &str) -> std::result::Result std::result::Result { +pub fn recv_vm_config(source_url: &str) -> result::Result { let mut vm_config_path = url_to_path(source_url)?; vm_config_path.push(SNAPSHOT_CONFIG_FILE); @@ -65,7 +66,7 @@ pub fn recv_vm_config(source_url: &str) -> std::result::Result std::result::Result { +pub fn recv_vm_state(source_url: &str) -> result::Result { let mut vm_state_path = url_to_path(source_url)?; vm_state_path.push(SNAPSHOT_STATE_FILE); @@ -81,7 +82,7 @@ pub fn recv_vm_state(source_url: &str) -> std::result::Result std::result::Result { +pub fn get_vm_snapshot(snapshot: &Snapshot) -> result::Result { if let Some(snapshot_data) = snapshot.snapshot_data.as_ref() { return snapshot_data.to_state(); } diff --git a/vmm/src/migration/worker.rs b/vmm/src/migration/worker.rs index 16f3a97a8..1a899653d 100644 --- a/vmm/src/migration/worker.rs +++ b/vmm/src/migration/worker.rs @@ -12,12 +12,12 @@ //! (rendezvous-channel). If spawning fails, the VM is returned to the caller in //! [`MigrationWorkerSpawnError`]. -use std::fmt::{Debug, Formatter}; +use std::fmt::{self, Debug, Formatter}; #[cfg(all(feature = "kvm", target_arch = "x86_64"))] use std::sync::Arc; -use std::sync::mpsc::Receiver; -use std::thread; +use std::sync::mpsc::{self, Receiver}; use std::thread::JoinHandle; +use std::{io, thread}; use event_monitor::event; use log::warn; @@ -32,12 +32,12 @@ use crate::vm::{Vm, VmState}; #[derive(thiserror::Error)] #[error("Migration worker could not be spawned: {spawn_error}")] pub struct MigrationWorkerSpawnError { - pub spawn_error: std::io::Error, + pub spawn_error: io::Error, pub vm: Vm, } impl Debug for MigrationWorkerSpawnError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("MigrationWorkerSpawnError") .field("spawn_error", &self.spawn_error) .field("vm", &"") @@ -121,7 +121,7 @@ impl MigrationWorker { initial_vm_state: VmState, seccomp_action: SeccompAction, ) -> Result { - let (vm_sender, vm_receiver) = std::sync::mpsc::sync_channel(0); + let (vm_sender, vm_receiver) = mpsc::sync_channel(0); let worker = MigrationWorker { vm_receiver, check_migration_evt, diff --git a/vmm/src/pci_segment.rs b/vmm/src/pci_segment.rs index d214cf7c8..9f5d065ac 100644 --- a/vmm/src/pci_segment.rs +++ b/vmm/src/pci_segment.rs @@ -554,6 +554,7 @@ impl Aml for PciSegment { #[cfg(test)] mod unit_tests { + use std::io; use std::result::Result; use vm_memory::GuestAddress; @@ -570,7 +571,7 @@ mod unit_tests { _len: u64, _pci_dev: &mut dyn pci::PciDevice, _region_type: pci::PciBarRegionType, - ) -> Result<(), std::io::Error> { + ) -> Result<(), io::Error> { Ok(()) } } diff --git a/vmm/src/seccomp_filters.rs b/vmm/src/seccomp_filters.rs index f9a106ff0..9df136dd6 100644 --- a/vmm/src/seccomp_filters.rs +++ b/vmm/src/seccomp_filters.rs @@ -4,6 +4,8 @@ // // SPDX-License-Identifier: Apache-2.0 +use std::env::consts; + use hypervisor::HypervisorType; use libc::{ BLKIOMIN, BLKIOOPT, BLKPBSZGET, BLKSSZGET, FIOCLEX, FIONBIO, SIOCGIFFLAGS, SIOCGIFHWADDR, @@ -1151,7 +1153,7 @@ pub fn get_seccomp_filter( .collect(), SeccompAction::Log, SeccompAction::Allow, - std::env::consts::ARCH.try_into().unwrap(), + consts::ARCH.try_into().unwrap(), ) .and_then(|filter| filter.try_into()) .map_err(Error::Backend), @@ -1162,7 +1164,7 @@ pub fn get_seccomp_filter( .collect(), SeccompAction::Trap, SeccompAction::Allow, - std::env::consts::ARCH.try_into().unwrap(), + consts::ARCH.try_into().unwrap(), ) .and_then(|filter| filter.try_into()) .map_err(Error::Backend), diff --git a/vmm/src/serial_manager.rs b/vmm/src/serial_manager.rs index 8ceba5c1e..b62b7abba 100644 --- a/vmm/src/serial_manager.rs +++ b/vmm/src/serial_manager.rs @@ -13,7 +13,7 @@ use std::panic::AssertUnwindSafe; use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; -use std::{io, result, thread}; +use std::{fs, io, panic, result, thread, time}; #[cfg(target_arch = "aarch64")] use devices::legacy::Pl011; @@ -24,6 +24,7 @@ use log::{error, info, warn}; use seccompiler::{SeccompAction, apply_filter}; use serial_buffer::SerialBuffer; use thiserror::Error; +use vmm_sys_util::errno; use vmm_sys_util::eventfd::EventFd; use crate::console_devices::ConsoleTransport; @@ -45,7 +46,7 @@ pub enum Error { /// Cannot queue input to the serial device. #[error("Error queuing input to the serial device")] - QueueInput(#[source] vmm_sys_util::errno::Error), + QueueInput(#[source] errno::Error), /// Cannot flush output on the serial buffer. #[error("Error flushing serial device's output buffer")] @@ -199,7 +200,7 @@ impl SerialManager { // SAFETY: STDIN_FILENO is a valid fd let fd = unsafe { libc::dup(libc::STDIN_FILENO) }; if fd == -1 { - return Err(Error::DupFd(std::io::Error::last_os_error())); + return Err(Error::DupFd(io::Error::last_os_error())); } // SAFETY: fd is valid and owned by us let stdin_clone = unsafe { File::from_raw_fd(fd) }; @@ -211,7 +212,7 @@ impl SerialManager { }; if ret < 0 { - return Err(Error::SetNonBlocking(std::io::Error::last_os_error())); + return Err(Error::SetNonBlocking(io::Error::last_os_error())); } transport = ConsoleTransport::Tty(Arc::new(stdin_clone)); @@ -352,7 +353,7 @@ impl SerialManager { let thread = thread::Builder::new() .name("serial-manager".to_string()) .spawn(move || { - std::panic::catch_unwind(AssertUnwindSafe(move || { + panic::catch_unwind(AssertUnwindSafe(move || { // Apply seccomp filter for serial manager thread. if !seccomp_filter.is_empty() { apply_filter(&seccomp_filter).map_err(Error::ApplySeccompFilter)?; @@ -503,7 +504,7 @@ impl SerialManager { // It's really important to sleep here as this will prevent // the current thread from consuming 100% of the CPU cycles // when waiting for someone to connect to the PTY. - std::thread::sleep(std::time::Duration::from_millis(500)); + thread::sleep(time::Duration::from_millis(500)); } else { // If the EPOLLHUP flag is not up on the associated event, we // can assume the other end of the PTY is connected and therefore @@ -538,7 +539,7 @@ impl Drop for SerialManager { handle.join().ok(); } if let Some(socket_console) = self.socket_console.as_ref() { - std::fs::remove_file(&socket_console.path) + fs::remove_file(&socket_console.path) .map_err(Error::RemoveUnixSocket) .ok(); } diff --git a/vmm/src/sev.rs b/vmm/src/sev.rs index c5fa9c706..0a3249f8c 100644 --- a/vmm/src/sev.rs +++ b/vmm/src/sev.rs @@ -8,6 +8,7 @@ use std::ffi::CString; use std::fs::File; use std::io::{self, Cursor, Read, Seek, SeekFrom}; use std::os::unix::fs::FileExt; +use std::result; use linux_loader::bootparam::boot_params; use sha2::{Digest, Sha256}; @@ -16,7 +17,7 @@ use vm_memory::ByteValued; use vmm_sys_util::errno; use zerocopy::{Immutable, IntoBytes}; -pub(crate) type Result = std::result::Result; +pub(crate) type Result = result::Result; // https://github.com/tianocore/edk2/blob/f98662c5e35b6ab60f46ee4350fa0e6eab0497cf/OvmfPkg/Include/Fdf/MemFd.fdf.inc#L89-L93 pub const SEV_HASH_BLOCK_ADDRESS: u64 = 0x10c00; @@ -182,6 +183,7 @@ impl MeasuredBootInfo { #[cfg(test)] mod tests { + use std::cmp; use std::io::Write; use super::*; @@ -196,7 +198,7 @@ mod tests { let effective_sects = if setup_sects == 0 { 4 } else { setup_sects }; let setup_len = (usize::from(effective_sects) + 1) * 512; let header_size = size_of::(); - let file_len = std::cmp::max(setup_len, header_size) + kernel_payload.len(); + let file_len = cmp::max(setup_len, header_size) + kernel_payload.len(); let mut buf = vec![0u8; file_len]; let bp = boot_params::from_mut_slice(&mut buf[..header_size]).unwrap(); @@ -329,7 +331,7 @@ mod tests { let effective_sects = if setup_sects == 0 { 4 } else { setup_sects }; let setup_len = (usize::from(effective_sects) + 1) * 512; let header_size = size_of::(); - let file_len = std::cmp::max(setup_len, header_size) + kernel_payload.len(); + let file_len = cmp::max(setup_len, header_size) + kernel_payload.len(); let mut buf = vec![0u8; file_len]; let bp = boot_params::from_mut_slice(&mut buf[..header_size]).unwrap(); diff --git a/vmm/src/sigwinch_listener.rs b/vmm/src/sigwinch_listener.rs index 9e3ebcfb1..db5834cf7 100644 --- a/vmm/src/sigwinch_listener.rs +++ b/vmm/src/sigwinch_listener.rs @@ -269,7 +269,7 @@ pub fn start_sigwinch_listener(seccomp_filter: BpfProgramRef, tty_sub: File) -> pub fn listen_for_sigwinch_on_tty( pty_sub: File, seccomp_action: &SeccompAction, -) -> std::io::Result { +) -> io::Result { let seccomp_filter = get_seccomp_filter(seccomp_action, Thread::PtyForeground, None).unwrap(); let console_resize_pipe = start_sigwinch_listener(&seccomp_filter, pty_sub)?; diff --git a/vmm/src/sparse.rs b/vmm/src/sparse.rs index a11663eac..10b976148 100644 --- a/vmm/src/sparse.rs +++ b/vmm/src/sparse.rs @@ -154,26 +154,23 @@ mod unit_tests { use std::io::Write; use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd}; use std::os::unix::fs::FileExt; + use std::{fs, io}; use super::{next_data_extent, write_region_sparse}; - fn make_memfd(size: u64) -> std::fs::File { + fn make_memfd(size: u64) -> fs::File { // SAFETY: memfd_create is a self-contained syscall; we own the // returned fd. let fd = unsafe { libc::syscall(libc::SYS_memfd_create, c"sparse-test".as_ptr(), 0u32) }; assert!(fd >= 0, "memfd_create failed"); // SAFETY: memfd_create returned a valid fd that we now own; wrap it // in File so it is closed on drop. - let f = unsafe { std::fs::File::from_raw_fd(fd as i32) }; + let f = unsafe { fs::File::from_raw_fd(fd as i32) }; f.set_len(size).unwrap(); f } - fn collect_extents( - fd: BorrowedFd<'_>, - start: u64, - end: u64, - ) -> std::io::Result> { + fn collect_extents(fd: BorrowedFd<'_>, start: u64, end: u64) -> io::Result> { let mut out = Vec::new(); let mut cursor = start; while let Some((off, len)) = next_data_extent(fd, cursor, end)? { @@ -190,7 +187,7 @@ mod unit_tests { /// not portable. `fallocate(PUNCH_HOLE)` is the explicit "deallocate /// these pages" syscall and is honored on every Linux filesystem we /// run tests on (tmpfs, ext4, xfs, btrfs). - fn punch_hole(f: &std::fs::File, off: u64, len: u64) { + fn punch_hole(f: &fs::File, off: u64, len: u64) { // SAFETY: FFI call; f is a valid open fd for the duration of the // call. let r = unsafe { @@ -205,7 +202,7 @@ mod unit_tests { r, 0, "fallocate PUNCH_HOLE off={off} len={len}: {}", - std::io::Error::last_os_error(), + io::Error::last_os_error(), ); } @@ -213,7 +210,7 @@ mod unit_tests { /// len, byte)` data extent, then punch every gap into a real hole. /// The resulting `SEEK_DATA`/`SEEK_HOLE` extents match `data` exactly, /// regardless of folio/THP allocation policy on the backing FS. - fn sparse_layout(f: &std::fs::File, total: u64, data: &[(u64, u64, u8)]) { + fn sparse_layout(f: &fs::File, total: u64, data: &[(u64, u64, u8)]) { f.set_len(total).unwrap(); for &(off, len, byte) in data { f.write_all_at(&vec![byte; len as usize], off).unwrap(); @@ -296,7 +293,7 @@ mod unit_tests { let used = write_region_sparse(&src, 0, &dst, 0, 4096 * 16).unwrap(); assert!(used); - let buf = std::fs::read(tmp.path()).unwrap(); + let buf = fs::read(tmp.path()).unwrap(); assert!(buf[..4096 * 3].iter().all(|&b| b == 0xFE)); assert!(buf[4096 * 3..4096 * 5].iter().all(|&b| b == 0x42)); assert!(buf[4096 * 5..].iter().all(|&b| b == 0xFE)); @@ -316,7 +313,7 @@ mod unit_tests { let _ = write_region_sparse(&src_a, 0, &dst, 0, 4096 * 16).unwrap(); let _ = write_region_sparse(&src_b, 0, &dst, 4096 * 16, 4096 * 16).unwrap(); - let buf = std::fs::read(tmp.path()).unwrap(); + let buf = fs::read(tmp.path()).unwrap(); assert!(buf[..4096].iter().all(|&b| b == 0)); assert!(buf[4096..4096 * 3].iter().all(|&b| b == 0xAA)); assert!(buf[4096 * 3..4096 * 16].iter().all(|&b| b == 0)); @@ -337,7 +334,7 @@ mod unit_tests { let used = write_region_sparse(&src, 4096 * 16, &dst, 0, 4096 * 16).unwrap(); assert!(used); - let buf = std::fs::read(tmp.path()).unwrap(); + let buf = fs::read(tmp.path()).unwrap(); assert!(buf[..4096 * 4].iter().all(|&b| b == 0)); assert!(buf[4096 * 4..4096 * 6].iter().all(|&b| b == 0x77)); assert!(buf[4096 * 6..].iter().all(|&b| b == 0)); @@ -387,7 +384,7 @@ mod unit_tests { } // Verify content matches a dense read. - let dense = std::fs::read(tmp.path()).unwrap(); + let dense = fs::read(tmp.path()).unwrap(); assert_eq!(restored, dense); // Verify the actual data landed in the right places. diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index cadd7be35..bcc573150 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -12,6 +12,8 @@ // use std::collections::{BTreeMap, BTreeSet, HashMap}; +#[cfg(feature = "fw_cfg")] +use std::ffi; use std::fs::{File, OpenOptions}; use std::io::{self, Seek, SeekFrom, Write}; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] @@ -22,22 +24,30 @@ use std::os::unix::net::UnixStream; use std::sync::{Arc, Mutex}; #[cfg(not(target_arch = "riscv64"))] use std::time::Instant; -use std::{cmp, result, str, thread}; +use std::{any, cmp, result, str, thread}; use anyhow::anyhow; #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] use arch::PciSpaceInfo; +#[cfg(not(target_arch = "x86_64"))] +use arch::aarch64; #[cfg(target_arch = "x86_64")] use arch::layout::{KVM_IDENTITY_MAP_START, KVM_TSS_START}; +#[cfg(not(target_arch = "x86_64"))] +use arch::uefi; #[cfg(all(feature = "kvm", target_arch = "x86_64"))] use arch::x86_64::MAX_SUPPORTED_CPUS_LEGACY; #[cfg(feature = "tdx")] +use arch::x86_64::tdx; +#[cfg(feature = "tdx")] use arch::x86_64::tdx::TdvfSection; -use arch::{EntryPoint, NumaNode, NumaNodes, get_host_cpu_phys_bits}; +use arch::{EntryPoint, NumaNode, NumaNodes, get_host_cpu_phys_bits, layout}; use devices::AcpiNotificationFlags; #[cfg(target_arch = "aarch64")] use devices::interrupt_controller; #[cfg(feature = "fw_cfg")] +use devices::legacy::fw_cfg; +#[cfg(feature = "fw_cfg")] use devices::legacy::fw_cfg::FwCfgItem; use event_monitor::event; #[cfg(all(target_arch = "aarch64", feature = "guest_debug"))] @@ -46,6 +56,8 @@ use gdbstub_arch::aarch64::reg::AArch64CoreRegs as CoreRegs; use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs; #[cfg(target_arch = "aarch64")] use hypervisor::arch::aarch64::regs::AARCH64_PMU_IRQ; +#[cfg(all(feature = "kvm", target_arch = "x86_64"))] +use hypervisor::arch::x86; #[cfg(all(feature = "kvm", feature = "sev_snp"))] use hypervisor::kvm::{ BOOTLOADER_SIZE, BOOTLOADER_START, KVM_VMSA_PAGE_ADDRESS, KVM_VMSA_PAGE_SIZE, @@ -56,6 +68,8 @@ use igvm::IgvmFile; #[cfg(feature = "sev_snp")] use igvm_defs::SnpPolicy; use libc::{SIGWINCH, termios}; +#[cfg(feature = "tdx")] +use linux_loader::bootparam; use linux_loader::cmdline::Cmdline; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use linux_loader::elf; @@ -66,6 +80,7 @@ use linux_loader::loader::bzimage::BzImage; use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent; #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] use linux_loader::loader::pe::Error::InvalidImageMagicNumber; +use linux_loader::{cmdline, loader}; use log::{error, info, warn}; use seccompiler::SeccompAction; use serde::{Deserialize, Serialize}; @@ -95,8 +110,10 @@ use crate::device_tree::DeviceTree; #[cfg(feature = "guest_debug")] use crate::gdb::{Debuggable, DebuggableError, GdbRequestPayload, GdbResponsePayload}; #[cfg(feature = "igvm")] -use crate::igvm::igvm_loader; +use crate::igvm::{igvm_loader, parse_igvm}; use crate::landlock::LandlockError; +#[cfg(feature = "tdx")] +use crate::memory_manager; use crate::memory_manager::{ Error as MemoryManagerError, MemoryManager, MemoryManagerSnapshotData, }; @@ -113,7 +130,7 @@ use crate::vm_config::{ }; use crate::{ CPU_MANAGER_SNAPSHOT_ID, DEVICE_MANAGER_SNAPSHOT_ID, GuestMemoryMmap, - MEMORY_MANAGER_SNAPSHOT_ID, PciDeviceInfo, cpu, + MEMORY_MANAGER_SNAPSHOT_ID, PciDeviceInfo, acpi, cpu, }; /// Errors associated with VM management @@ -126,18 +143,18 @@ pub enum Error { InitramfsFile(#[source] io::Error), #[error("Cannot load the kernel into memory")] - KernelLoad(#[source] linux_loader::loader::Error), + KernelLoad(#[source] loader::Error), #[cfg(target_arch = "aarch64")] #[error("Cannot load the UEFI binary in memory")] - UefiLoad(#[source] arch::aarch64::uefi::Error), + UefiLoad(#[source] aarch64::uefi::Error), #[cfg(target_arch = "riscv64")] #[error("Cannot load the UEFI binary in memory")] UefiLoad(#[source] arch::riscv64::uefi::Error), #[error("Cannot load the initramfs into memory")] - InitramfsLoad(#[source] std::io::Error), + InitramfsLoad(#[source] io::Error), #[error("Cannot determine initramfs load address")] InitramfsAddress(#[source] arch::Error), @@ -146,16 +163,16 @@ pub enum Error { InitramfsRead(#[source] vm_memory::GuestMemoryError), #[error("Cannot load the kernel command line in memory")] - LoadCmdLine(#[source] linux_loader::loader::Error), + LoadCmdLine(#[source] loader::Error), #[error("Failed to apply landlock config during vm_create")] ApplyLandlock(#[source] LandlockError), #[error("Cannot modify the kernel command line")] - CmdLineInsertStr(#[source] linux_loader::cmdline::Error), + CmdLineInsertStr(#[source] cmdline::Error), #[error("Cannot create the kernel command line")] - CmdLineCreate(#[source] linux_loader::cmdline::Error), + CmdLineCreate(#[source] cmdline::Error), #[error("Cannot configure system")] ConfigureSystem(#[source] arch::Error), @@ -177,7 +194,7 @@ pub enum Error { SignalHandlerSpawn(#[source] io::Error), #[error("Failed to join on threads: {0:?}")] - ThreadCleanup(std::boxed::Box), + ThreadCleanup(Box), #[error("VM config is missing")] VmMissingConfig, @@ -225,7 +242,7 @@ pub enum Error { MemoryManager(#[source] MemoryManagerError), #[error("Eventfd write error")] - EventfdError(#[source] std::io::Error), + EventfdError(#[source] io::Error), #[error("Cannot snapshot VM")] Snapshot(#[source] MigratableError), @@ -276,7 +293,7 @@ pub enum Error { AllocateFirmwareMemory(#[source] MemoryManagerError), #[error("Error manipulating firmware file")] - FirmwareFile(#[source] std::io::Error), + FirmwareFile(#[source] io::Error), #[error("Firmware too big")] FirmwareTooLarge, @@ -290,23 +307,23 @@ pub enum Error { #[cfg(feature = "tdx")] #[error("Error performing I/O on TDX firmware file")] - LoadTdvf(#[source] std::io::Error), + LoadTdvf(#[source] io::Error), #[cfg(feature = "tdx")] #[error("Error performing I/O on the TDX payload file")] - LoadPayload(#[source] std::io::Error), + LoadPayload(#[source] io::Error), #[cfg(feature = "tdx")] #[error("Error parsing TDVF")] - ParseTdvf(#[source] arch::x86_64::tdx::TdvfError), + ParseTdvf(#[source] tdx::TdvfError), #[cfg(feature = "tdx")] #[error("Error populating TDX HOB")] - PopulateHob(#[source] arch::x86_64::tdx::TdvfError), + PopulateHob(#[source] tdx::TdvfError), #[cfg(feature = "tdx")] #[error("Error allocating TDVF memory")] - AllocatingTdvfMemory(#[source] crate::memory_manager::Error), + AllocatingTdvfMemory(#[source] memory_manager::Error), #[cfg(feature = "tdx")] #[error("Error enabling TDX VM")] @@ -333,10 +350,10 @@ pub enum Error { Debug(#[source] DebuggableError), #[error("Error spawning kernel loading thread")] - KernelLoadThreadSpawn(#[source] std::io::Error), + KernelLoadThreadSpawn(#[source] io::Error), #[error("Error joining kernel loading thread")] - KernelLoadThreadJoin(std::boxed::Box), + KernelLoadThreadJoin(Box), #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] #[error("Error coredumping VM")] @@ -1187,7 +1204,7 @@ impl Vm { .map_err(Error::MissingFwCfgKernelFile)?; kernel_option = kernel; } - let mut cmdline_option: Option = None; + let mut cmdline_option: Option = None; if fw_cfg_config.cmdline { let cmdline = Vm::generate_cmdline( config.lock().unwrap().payload.as_ref().unwrap(), @@ -1220,9 +1237,9 @@ impl Vm { for fw_cfg_item in fw_cfg_items.item_list.clone() { let content = match (fw_cfg_item.string, fw_cfg_item.file) { (Some(string_val), None) => { - devices::legacy::fw_cfg::FwCfgContent::Bytes(string_val.into_bytes()) + fw_cfg::FwCfgContent::Bytes(string_val.into_bytes()) } - (None, Some(file_path)) => devices::legacy::fw_cfg::FwCfgContent::File( + (None, Some(file_path)) => fw_cfg::FwCfgContent::File( 0, File::open(file_path).map_err(Error::AddingFwCfgItem)?, ), @@ -1370,7 +1387,7 @@ impl Vm { .payload .as_ref() .and_then(|p| p.igvm.as_ref()) - .map(|igvm_path| crate::igvm::parse_igvm(igvm_path)) + .map(|igvm_path| parse_igvm(igvm_path)) .transpose() .map_err(Error::IgvmLoad)? }; @@ -1516,10 +1533,9 @@ impl Vm { .map_err(Error::MemoryManager)?; let uefi_flash = memory_manager.uefi_flash(); let mem = uefi_flash.memory(); - arch::uefi::load_uefi(mem.deref(), arch::layout::UEFI_START, &mut firmware) - .map_err(Error::UefiLoad)?; + uefi::load_uefi(mem.deref(), layout::UEFI_START, &mut firmware).map_err(Error::UefiLoad)?; Ok(EntryPoint { - entry_addr: arch::layout::UEFI_START, + entry_addr: layout::UEFI_START, }) } @@ -1533,9 +1549,9 @@ impl Vm { let mem = guest_memory.memory(); let alignment = 0x20_0000; // round up - let aligned_kernel_addr = arch::layout::KERNEL_START.0.div_ceil(alignment) * alignment; + let aligned_kernel_addr = layout::KERNEL_START.0.div_ceil(alignment) * alignment; let entry_addr = { - match linux_loader::loader::pe::PE::load( + match loader::pe::PE::load( mem.deref(), Some(GuestAddress(aligned_kernel_addr)), &mut kernel, @@ -1545,9 +1561,9 @@ impl Vm { // Try to load the binary as kernel PE file at first. // If failed, retry to load it as UEFI binary. // As the UEFI binary is formatless, it must be the last option to try. - Err(linux_loader::loader::Error::Pe(InvalidImageMagicNumber)) => { + Err(loader::Error::Pe(InvalidImageMagicNumber)) => { Self::load_firmware(&kernel, memory_manager)?; - arch::layout::UEFI_START + layout::UEFI_START } Err(e) => { return Err(Error::KernelLoad(e)); @@ -1632,25 +1648,16 @@ impl Vm { }; // Try ELF binary with PVH boot. - let entry_addr = linux_loader::loader::elf::Elf::load( - mem.deref(), - None, - &mut kernel, - Some(arch::layout::HIGH_RAM_START), - ) - // Try loading kernel as bzImage. - .or_else(|_| { - BzImage::load( - mem.deref(), - None, - &mut kernel, - Some(arch::layout::HIGH_RAM_START), - ) - }) - .map_err(Error::KernelLoad)?; + let entry_addr = + loader::elf::Elf::load(mem.deref(), None, &mut kernel, Some(layout::HIGH_RAM_START)) + // Try loading kernel as bzImage. + .or_else(|_| { + BzImage::load(mem.deref(), None, &mut kernel, Some(layout::HIGH_RAM_START)) + }) + .map_err(Error::KernelLoad)?; if let Some(cmdline) = cmdline { - linux_loader::loader::load_cmdline(mem.deref(), arch::layout::CMDLINE_START, &cmdline) + loader::load_cmdline(mem.deref(), layout::CMDLINE_START, &cmdline) .map_err(Error::LoadCmdLine)?; } @@ -1799,7 +1806,7 @@ impl Vm { #[cfg(feature = "igvm")] let cpu_manager = cpu_manager.clone(); - std::thread::Builder::new() + thread::Builder::new() .name("payload_loader".into()) .spawn(move || { Self::load_payload( @@ -1845,8 +1852,8 @@ impl Vm { arch::configure_system( &mem, - arch::layout::CMDLINE_START, - arch::layout::CMDLINE_MAX_SIZE, + layout::CMDLINE_START, + layout::CMDLINE_MAX_SIZE, &initramfs_config, boot_vcpus, entry_addr.setup_header, @@ -1914,9 +1921,7 @@ impl Vm { .unwrap() .get_vgic() .map_err(|_| { - Error::ConfigureSystem(arch::Error::PlatformSpecific( - arch::aarch64::Error::SetupGic, - )) + Error::ConfigureSystem(arch::Error::PlatformSpecific(aarch64::Error::SetupGic)) })?; // PMU interrupt sticks to PPI, so need to be added by 16 to get real irq number. @@ -1926,9 +1931,7 @@ impl Vm { .unwrap() .init_pmu(AARCH64_PMU_IRQ + 16) .map_err(|_| { - Error::ConfigureSystem(arch::Error::PlatformSpecific( - arch::aarch64::Error::VcpuInitPmu, - )) + Error::ConfigureSystem(arch::Error::PlatformSpecific(aarch64::Error::VcpuInitPmu)) })?; arch::configure_system( @@ -2467,7 +2470,7 @@ impl Vm { if section.address <= next_start_addr { (section.address, section.size, false) } else { - let last_addr = std::cmp::min(section.address - 1, region_end); + let last_addr = cmp::min(section.address - 1, region_end); (next_start_addr, last_addr - next_start_addr + 1, true) } } else { @@ -2583,7 +2586,7 @@ impl Vm { .seek(SeekFrom::Start(0x1f1)) .map_err(Error::LoadPayload)?; - let mut payload_header = linux_loader::bootparam::setup_header::default(); + let mut payload_header = bootparam::setup_header::default(); payload_file .read_volatile(&mut payload_header.as_bytes()) .unwrap(); @@ -2646,9 +2649,8 @@ impl Vm { // MMIO regions hob.add_mmio_resource( &mem, - arch::layout::MEM_32BIT_DEVICES_START.raw_value(), - arch::layout::APIC_START.raw_value() - - arch::layout::MEM_32BIT_DEVICES_START.raw_value(), + layout::MEM_32BIT_DEVICES_START.raw_value(), + layout::APIC_START.raw_value() - layout::MEM_32BIT_DEVICES_START.raw_value(), ) .map_err(Error::PopulateHob)?; let start_of_device_area = self @@ -2672,7 +2674,7 @@ impl Vm { // Loop over the ACPI tables and copy them to the HOB. - for acpi_table in crate::acpi::create_acpi_tables_tdx( + for acpi_table in acpi::create_acpi_tables_tdx( &self.device_manager.lock().unwrap(), &self.cpu_manager.lock().unwrap(), &self.memory_manager.lock().unwrap(), @@ -2733,7 +2735,7 @@ impl Vm { } let mem = self.memory_manager.lock().unwrap().guest_memory().memory(); let tpm_enabled = self.config.lock().unwrap().tpm.is_some(); - let rsdp_addr = crate::acpi::create_acpi_tables( + let rsdp_addr = acpi::create_acpi_tables( &mem, &self.device_manager.lock().unwrap(), &self.cpu_manager.lock().unwrap(), @@ -2820,7 +2822,7 @@ impl Vm { if fw_cfg_config.acpi_tables { let tpm_enabled = self.config.lock().unwrap().tpm.is_some(); - crate::acpi::create_acpi_tables_for_fw_cfg( + acpi::create_acpi_tables_for_fw_cfg( &self.device_manager.lock().unwrap(), &self.cpu_manager.lock().unwrap(), &self.memory_manager.lock().unwrap(), @@ -3009,7 +3011,7 @@ impl Vm { pub fn send_memory_fds( &mut self, socket: &mut UnixStream, - ) -> std::result::Result<(), MigratableError> { + ) -> result::Result<(), MigratableError> { for (slot, fd) in self .memory_manager .lock() @@ -3017,7 +3019,7 @@ impl Vm { .memory_slot_fds() .drain() { - Request::memory_fd(std::mem::size_of_val(&slot) as u64) + Request::memory_fd(size_of_val(&slot) as u64) .write_to(socket) .map_err(|e| { MigratableError::MigrateSend(anyhow!("Error sending memory fd request: {e}")) @@ -3037,7 +3039,7 @@ impl Vm { Ok(()) } - pub fn memory_range_table(&self) -> std::result::Result { + pub fn memory_range_table(&self) -> result::Result { self.memory_manager .lock() .unwrap() @@ -3156,7 +3158,7 @@ impl Vm { fn get_dump_state( &mut self, destination_url: &str, - ) -> std::result::Result { + ) -> result::Result { let nr_cpus = self.config.lock().unwrap().cpus.boot_vcpus; let elf_note_size = self.get_note_size(NoteDescType::ElfAndVmm, nr_cpus) as isize; let mut elf_phdr_num = 1; @@ -3211,7 +3213,7 @@ impl Vm { /// Capture the guest clock for a same-host resume (mode `SameHostResume`). /// `None` if the VM is not booted or the backend has no guest clock. - fn capture_guest_clock(&self) -> std::result::Result, MigratableError> { + fn capture_guest_clock(&self) -> result::Result, MigratableError> { let Some(boot_vcpu) = self.cpu_manager.lock().unwrap().boot_vcpu() else { return Ok(None); }; @@ -3227,7 +3229,7 @@ impl Vm { } /// Re-establish the guest clock before the vCPUs resume. No-op if none captured. - fn restore_guest_clock(&self) -> std::result::Result<(), MigratableError> { + fn restore_guest_clock(&self) -> result::Result<(), MigratableError> { let Some(saved) = &self.saved_clock else { return Ok(()); }; @@ -3242,7 +3244,7 @@ impl Vm { } impl Pausable for Vm { - fn pause(&mut self) -> std::result::Result<(), MigratableError> { + fn pause(&mut self) -> result::Result<(), MigratableError> { event!("vm", "pausing"); let new_state = VmState::Paused; self.state @@ -3272,7 +3274,7 @@ impl Pausable for Vm { Ok(()) } - fn resume(&mut self) -> std::result::Result<(), MigratableError> { + fn resume(&mut self) -> result::Result<(), MigratableError> { event!("vm", "resuming"); let current_state = self.get_state(); let new_state = VmState::Running; @@ -3305,7 +3307,7 @@ pub struct VmSnapshot { #[serde(default, skip_serializing_if = "Option::is_none")] pub clock: Option, #[cfg(all(feature = "kvm", target_arch = "x86_64"))] - pub common_cpuid: Vec, + pub common_cpuid: Vec, } pub const VM_SNAPSHOT_ID: &str = "vm"; @@ -3314,7 +3316,7 @@ impl Snapshottable for Vm { VM_SNAPSHOT_ID.to_string() } - fn snapshot(&mut self) -> std::result::Result { + fn snapshot(&mut self) -> result::Result { event!("vm", "snapshotting"); #[cfg(feature = "tdx")] @@ -3397,7 +3399,7 @@ impl Transportable for Vm { &self, snapshot: &Snapshot, destination_url: &str, - ) -> std::result::Result<(), MigratableError> { + ) -> result::Result<(), MigratableError> { let mut snapshot_config_path = url_to_path(destination_url)?; snapshot_config_path.push(SNAPSHOT_CONFIG_FILE); @@ -3453,29 +3455,29 @@ impl Transportable for Vm { } impl Migratable for Vm { - fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> { + fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> { self.memory_manager.lock().unwrap().start_dirty_log()?; self.device_manager.lock().unwrap().start_dirty_log() } - fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> { + fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> { self.memory_manager.lock().unwrap().stop_dirty_log()?; self.device_manager.lock().unwrap().stop_dirty_log() } - fn dirty_log(&mut self) -> std::result::Result { + fn dirty_log(&mut self) -> result::Result { Ok(MemoryRangeTable::new_from_tables(vec![ self.memory_manager.lock().unwrap().dirty_log()?, self.device_manager.lock().unwrap().dirty_log()?, ])) } - fn start_migration(&mut self) -> std::result::Result<(), MigratableError> { + fn start_migration(&mut self) -> result::Result<(), MigratableError> { self.memory_manager.lock().unwrap().start_migration()?; self.device_manager.lock().unwrap().start_migration() } - fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { + fn complete_migration(&mut self) -> result::Result<(), MigratableError> { self.memory_manager.lock().unwrap().complete_migration()?; self.device_manager.lock().unwrap().complete_migration() } @@ -3488,14 +3490,14 @@ impl Debuggable for Vm { cpu_id: usize, addrs: &[GuestAddress], singlestep: bool, - ) -> std::result::Result<(), DebuggableError> { + ) -> result::Result<(), DebuggableError> { self.cpu_manager .lock() .unwrap() .set_guest_debug(cpu_id, addrs, singlestep) } - fn debug_pause(&mut self) -> std::result::Result<(), DebuggableError> { + fn debug_pause(&mut self) -> result::Result<(), DebuggableError> { if self.state == VmState::Running { self.pause().map_err(DebuggableError::Pause)?; } @@ -3504,7 +3506,7 @@ impl Debuggable for Vm { Ok(()) } - fn debug_resume(&mut self) -> std::result::Result<(), DebuggableError> { + fn debug_resume(&mut self) -> result::Result<(), DebuggableError> { if self.state == VmState::BreakPoint { self.resume().map_err(DebuggableError::Pause)?; } @@ -3512,15 +3514,11 @@ impl Debuggable for Vm { Ok(()) } - fn read_regs(&self, cpu_id: usize) -> std::result::Result { + fn read_regs(&self, cpu_id: usize) -> result::Result { self.cpu_manager.lock().unwrap().read_regs(cpu_id) } - fn write_regs( - &self, - cpu_id: usize, - regs: &CoreRegs, - ) -> std::result::Result<(), DebuggableError> { + fn write_regs(&self, cpu_id: usize, regs: &CoreRegs) -> result::Result<(), DebuggableError> { self.cpu_manager.lock().unwrap().write_regs(cpu_id, regs) } @@ -3530,7 +3528,7 @@ impl Debuggable for Vm { cpu_id: usize, vaddr: GuestAddress, len: usize, - ) -> std::result::Result, DebuggableError> { + ) -> result::Result, DebuggableError> { self.cpu_manager .lock() .unwrap() @@ -3543,7 +3541,7 @@ impl Debuggable for Vm { cpu_id: usize, vaddr: &GuestAddress, data: &[u8], - ) -> std::result::Result<(), DebuggableError> { + ) -> result::Result<(), DebuggableError> { self.cpu_manager .lock() .unwrap() @@ -3569,7 +3567,7 @@ impl Elf64Writable for Vm {} #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] impl GuestDebuggable for Vm { - fn coredump(&mut self, destination_url: &str) -> std::result::Result<(), GuestDebuggableError> { + fn coredump(&mut self, destination_url: &str) -> result::Result<(), GuestDebuggableError> { event!("vm", "coredumping"); let mut resume = false; @@ -3986,7 +3984,7 @@ mod unit_tests { let regions = vec![(layout::RAM_START, (layout::FDT_MAX_SIZE + 0x1000) as usize)]; let mem = GuestMemoryMmap::from_ranges(®ions).expect("Cannot initialize memory"); - let dev_info: HashMap<(DeviceType, std::string::String), MmioDeviceInfo> = [ + let dev_info: HashMap<(DeviceType, String), MmioDeviceInfo> = [ ( (DeviceType::Serial, DeviceType::Serial.to_string()), MmioDeviceInfo { diff --git a/vmm/src/vm_config.rs b/vmm/src/vm_config.rs index a6af4f3c8..bc9cad299 100644 --- a/vmm/src/vm_config.rs +++ b/vmm/src/vm_config.rs @@ -10,8 +10,12 @@ use std::str::FromStr; use std::{fs, result}; use arch::CpuProfile; +#[cfg(target_arch = "x86_64")] +use arch::x86_64; use block::ImageType; pub use block::fcntl::LockGranularityChoice; +#[cfg(target_arch = "x86_64")] +use devices::debug_console; use log::{debug, warn}; use net_util::MacAddr; use serde::{Deserialize, Serialize}; @@ -170,7 +174,7 @@ pub struct PlatformConfig { impl PlatformConfig { /// Returns `None` if no SMBIOS-relevant platform fields are set, otherwise /// `Some` with a [`SmbiosConfig`] built from the populated fields. - pub fn smbios_config(&self) -> Option { + pub fn smbios_config(&self) -> Option { let has_system = [ &self.system_serial_number, &self.system_uuid, @@ -183,7 +187,7 @@ impl PlatformConfig { .iter() .any(|v| v.is_some()); - let system = has_system.then_some(arch::x86_64::SmbiosSystem { + let system = has_system.then_some(x86_64::SmbiosSystem { manufacturer: self.system_manufacturer.clone(), product_name: self.system_product_name.clone(), version: self.system_version.clone(), @@ -193,14 +197,14 @@ impl PlatformConfig { family: self.system_family.clone(), }); - let chassis = - self.chassis_asset_tag - .clone() - .map(|asset_tag| arch::x86_64::SmbiosChassisConfig { - asset_tag: Some(asset_tag), - }); + let chassis = self + .chassis_asset_tag + .clone() + .map(|asset_tag| x86_64::SmbiosChassisConfig { + asset_tag: Some(asset_tag), + }); - let smbios = arch::x86_64::SmbiosConfig { + let smbios = x86_64::SmbiosConfig { system, chassis, oem_strings: self.oem_strings.clone().unwrap_or_default(), @@ -753,7 +757,7 @@ impl Default for DebugConsoleConfig { Self { file: None, mode: ConsoleOutputMode::Off, - iobase: Some(devices::debug_console::DEFAULT_PORT as u16), + iobase: Some(debug_console::DEFAULT_PORT as u16), } } } @@ -1317,7 +1321,7 @@ impl VmConfig { #[cfg(all(feature = "kvm", target_arch = "x86_64"))] pub(crate) fn max_apic_id(&self) -> u32 { if let Some(topology) = &self.cpus.topology { - arch::x86_64::get_max_x2apic_id(( + x86_64::get_max_x2apic_id(( topology.threads_per_core, topology.cores_per_die, topology.dies_per_package,