diff --git a/pci/src/bus.rs b/pci/src/bus.rs index e5fe38f22..602dd1c2e 100644 --- a/pci/src/bus.rs +++ b/pci/src/bus.rs @@ -10,6 +10,7 @@ use std::ops::DerefMut; use std::sync::{Arc, Barrier, Mutex}; use byteorder::{ByteOrder, LittleEndian}; +use thiserror::Error; use vm_device::{Bus, BusDevice, BusDeviceSync}; use crate::configuration::{ @@ -23,21 +24,28 @@ const DEVICE_ID_INTEL_VIRT_PCIE_HOST: u16 = 0x0d57; const NUM_DEVICE_IDS: usize = 32; /// Errors for device manager. -#[derive(Debug)] +#[derive(Error, Debug)] pub enum PciRootError { /// Could not allocate device address space for the device. - AllocateDeviceAddrs(PciDeviceError), + #[error("Could not allocate device address space for the device: {0}")] + AllocateDeviceAddrs(#[source] PciDeviceError), /// Could not allocate an IRQ number. + #[error("Could not allocate an IRQ number")] AllocateIrq, /// Could not add a device to the port io bus. - PioInsert(vm_device::BusError), + #[error("Could not add a device to the port io bus: {0}")] + PioInsert(#[source] vm_device::BusError), /// Could not add a device to the mmio bus. - MmioInsert(vm_device::BusError), + #[error("Could not add a device to the mmio bus: {0}")] + MmioInsert(#[source] vm_device::BusError), /// Could not find an available device slot on the PCI bus. + #[error("Could not find an available device slot on the PCI bus")] NoPciDeviceSlotAvailable, /// Invalid PCI device identifier provided. + #[error("Invalid PCI device identifier provided")] InvalidPciDeviceSlot(usize), /// Valid PCI device identifier but already used. + #[error("Valid PCI device identifier but already used")] AlreadyInUsePciDeviceSlot(usize), } pub type Result = std::result::Result; diff --git a/pci/src/configuration.rs b/pci/src/configuration.rs index 036894d8b..7264f7caf 100644 --- a/pci/src/configuration.rs +++ b/pci/src/configuration.rs @@ -4,11 +4,11 @@ // // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause -use std::fmt::{self, Display}; use std::sync::{Arc, Mutex}; use byteorder::{ByteOrder, LittleEndian}; use serde::{Deserialize, Serialize}; +use thiserror::Error; use vm_device::PciBarType; use vm_migration::{MigratableError, Pausable, Snapshot, Snapshottable}; @@ -493,60 +493,45 @@ pub struct PciBarConfiguration { prefetchable: PciBarPrefetchable, } -#[derive(Debug)] +#[derive(Error, Debug)] pub enum Error { + #[error("address {0} size {1} too big")] BarAddressInvalid(u64, u64), + #[error("bar {0} already used")] BarInUse(usize), + #[error("64bit bar {0} already used (requires two regs)")] BarInUse64(usize), + #[error("bar {0} invalid, max {max}", max = NUM_BAR_REGS - 1)] BarInvalid(usize), + #[error("64bitbar {0} invalid, requires two regs, max {max}", max = NUM_BAR_REGS - 1)] BarInvalid64(usize), + #[error("bar address {0} not a power of two")] BarSizeInvalid(u64), + #[error("empty capabilities are invalid")] CapabilityEmpty, + #[error("Invalid capability length {0}")] CapabilityLengthInvalid(usize), + #[error("capability of size {0} doesn't fit")] CapabilitySpaceFull(usize), + #[error("failed to decode 32 bits BAR size")] Decode32BarSize, + #[error("failed to decode 64 bits BAR size")] Decode64BarSize, + #[error("failed to encode 32 bits BAR size")] Encode32BarSize, + #[error("failed to encode 64 bits BAR size")] Encode64BarSize, + #[error("address {0} size {1} too big")] RomBarAddressInvalid(u64, u64), + #[error("rom bar {0} already used")] RomBarInUse(usize), + #[error("rom bar {0} invalid, max {max}", max = NUM_BAR_REGS - 1)] RomBarInvalid(usize), + #[error("rom bar address {0} not a power of two")] RomBarSizeInvalid(u64), } pub type Result = std::result::Result; -impl std::error::Error for Error {} - -impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; - match self { - BarAddressInvalid(a, s) => write!(f, "address {a} size {s} too big"), - BarInUse(b) => write!(f, "bar {b} already used"), - BarInUse64(b) => write!(f, "64bit bar {b} already used(requires two regs)"), - BarInvalid(b) => write!(f, "bar {} invalid, max {}", b, NUM_BAR_REGS - 1), - BarInvalid64(b) => write!( - f, - "64bitbar {} invalid, requires two regs, max {}", - b, - NUM_BAR_REGS - 1 - ), - BarSizeInvalid(s) => write!(f, "bar address {s} not a power of two"), - CapabilityEmpty => write!(f, "empty capabilities are invalid"), - CapabilityLengthInvalid(l) => write!(f, "Invalid capability length {l}"), - CapabilitySpaceFull(s) => write!(f, "capability of size {s} doesn't fit"), - Decode32BarSize => write!(f, "failed to decode 32 bits BAR size"), - Decode64BarSize => write!(f, "failed to decode 64 bits BAR size"), - Encode32BarSize => write!(f, "failed to encode 32 bits BAR size"), - Encode64BarSize => write!(f, "failed to encode 64 bits BAR size"), - RomBarAddressInvalid(a, s) => write!(f, "address {a} size {s} too big"), - RomBarInUse(b) => write!(f, "rom bar {b} already used"), - RomBarInvalid(b) => write!(f, "rom bar {} invalid, max {}", b, NUM_BAR_REGS - 1), - RomBarSizeInvalid(s) => write!(f, "rom bar address {s} not a power of two"), - } - } -} - impl PciConfiguration { #[allow(clippy::too_many_arguments)] pub fn new( diff --git a/pci/src/device.rs b/pci/src/device.rs index 0bc84208d..599549f72 100644 --- a/pci/src/device.rs +++ b/pci/src/device.rs @@ -5,49 +5,35 @@ // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause use std::any::Any; -use std::fmt::{self, Display}; use std::sync::{Arc, Barrier, Mutex}; use std::{io, result}; - +use thiserror::Error; use vm_allocator::{AddressAllocator, SystemAllocator}; use vm_device::Resource; use crate::configuration::{self, PciBarRegionType}; use crate::PciBarConfiguration; -#[derive(Debug)] +#[derive(Error, Debug)] pub enum Error { /// Setup of the device capabilities failed. - CapabilitiesSetup(configuration::Error), + #[error("Setup of the device capabilities failed: {0}")] + CapabilitiesSetup(#[source] configuration::Error), /// Allocating space for an IO BAR failed. + #[error("Allocating space for an IO BAR failed")] IoAllocationFailed(u64), /// Registering an IO BAR failed. - IoRegistrationFailed(u64, configuration::Error), + #[error("Registering an IO BAR failed: {0}")] + IoRegistrationFailed(u64, #[source] configuration::Error), /// Expected resource not found. + #[error("Expected resource not found")] MissingResource, /// Invalid resource. + #[error("Invalid resource: {0:?}")] InvalidResource(Resource), } pub type Result = std::result::Result; -impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; - - match self { - CapabilitiesSetup(e) => write!(f, "failed to add capability {e}"), - IoAllocationFailed(size) => { - write!(f, "failed to allocate space for an IO BAR, size={size}") - } - IoRegistrationFailed(addr, e) => { - write!(f, "failed to register an IO BAR, addr={addr} err={e}") - } - MissingResource => write!(f, "failed to find expected resource"), - InvalidResource(r) => write!(f, "invalid resource {r:?}"), - } - } -} - #[derive(Clone, Copy, Debug)] pub struct BarReprogrammingParams { pub old_base: u64, diff --git a/vm-device/src/bus.rs b/vm-device/src/bus.rs index ff7c1f8c5..70bbc049a 100644 --- a/vm-device/src/bus.rs +++ b/vm-device/src/bus.rs @@ -10,7 +10,9 @@ use std::cmp::Ordering; use std::collections::btree_map::BTreeMap; use std::sync::{Arc, Barrier, Mutex, RwLock, Weak}; -use std::{convert, error, fmt, io, result}; +use std::{convert, io, result}; + +use thiserror::Error; /// Trait for devices that respond to reads or writes in an arbitrary address space. /// @@ -51,26 +53,21 @@ impl BusDeviceSync for Mutex { } } -#[derive(Debug)] +#[derive(Error, Debug)] pub enum Error { /// The insertion failed because the new device overlapped with an old device. + #[error("The insertion failed because the new device overlapped with an old device")] Overlap, /// Failed to operate on zero sized range. + #[error("Failed to operate on zero sized range")] ZeroSizedRange, /// Failed to find address range. + #[error("Failed to find address range")] MissingAddressRange, } pub type Result = result::Result; -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "bus_error: {self:?}") - } -} - -impl error::Error for Error {} - impl convert::From for io::Error { fn from(e: Error) -> Self { io::Error::other(e) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index c60f2b33c..f1b227358 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -265,11 +265,11 @@ pub enum DeviceManagerError { /// Cannot allocate PCI BARs #[error("Cannot allocate PCI BARs: {0}")] - AllocateBars(pci::PciDeviceError), + AllocateBars(#[source] pci::PciDeviceError), /// Could not free the BARs associated with a PCI device. #[error("Could not free the BARs associated with a PCI device: {0}")] - FreePciBars(pci::PciDeviceError), + FreePciBars(#[source] pci::PciDeviceError), /// Cannot register ioevent. #[error("Cannot register ioevent: {0}")] @@ -285,7 +285,7 @@ pub enum DeviceManagerError { /// Cannot add PCI device #[error("Cannot add PCI device")] - AddPciDevice(pci::PciRootError), + AddPciDevice(#[source] pci::PciRootError), /// Cannot open persistent memory file #[error("Cannot open persistent memory file")]