Skip to content

Commit 6c210a6

Browse files
Jonathan Woollett-LightJonathanWoollett-Light
Jonathan Woollett-Light
authored andcommitted
Error type expansion
Signed-off-by: Jonathan Woollett-Light <[email protected]>
1 parent 81449b4 commit 6c210a6

31 files changed

+892
-568
lines changed

Cargo.lock

Lines changed: 9 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api_server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ serde = { version = ">=1.0.27", features = ["derive"] }
1111
serde_derive = ">=1.0.27"
1212
serde_json = ">=1.0.9"
1313
derive_more = { version = "0.99.17", default-features = false, features = ["from"] }
14+
thiserror = "1.0.32"
1415

1516
logger = { path = "../logger" }
1617
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", rev = "0a58eb1" }

src/api_server/src/lib.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,16 @@ pub type ApiRequest = Box<VmmAction>;
3434
pub type ApiResponse = Box<std::result::Result<VmmData, VmmActionError>>;
3535

3636
/// Errors thrown when binding the API server to the socket path.
37+
#[derive(thiserror::Error)]
3738
pub enum Error {
3839
/// IO related error.
40+
#[error("IO error: {0}")]
3941
Io(io::Error),
4042
/// EventFD related error.
43+
#[error("EventFd error: {0}")]
4144
Eventfd(io::Error),
4245
}
4346

44-
impl fmt::Display for Error {
45-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46-
match *self {
47-
Error::Io(ref err) => write!(f, "IO error: {}", err),
48-
Error::Eventfd(ref err) => write!(f, "EventFd error: {}", err),
49-
}
50-
}
51-
}
52-
5347
impl fmt::Debug for Error {
5448
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5549
match *self {

src/arch/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ versionize = ">=0.1.6"
1414
versionize_derive = ">=0.1.3"
1515
vm-fdt = "0.1.0"
1616
derive_more = { version = "0.99.17", default-features = false, features = ["from"] }
17+
thiserror = "1.0.32"
1718
bitflags = ">=1.0.4"
1819

1920
arch_gen = { path = "../arch_gen" }

src/arch/src/aarch64/gic/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@ pub use regs::GicState;
1616
use super::layout;
1717

1818
/// Errors thrown while setting up the GIC.
19-
#[derive(Debug)]
19+
#[derive(Debug, thiserror::Error)]
2020
pub enum Error {
2121
/// Error while calling KVM ioctl for setting up the global interrupt controller.
22+
#[error("Error while calling KVM ioctl for setting up the global interrupt controller: {0}")]
2223
CreateGIC(kvm_ioctls::Error),
2324
/// Error while setting or getting device attributes for the GIC.
25+
#[error("Error while setting or getting device attributes for the GIC: {0}, {1}, {2}")]
2426
DeviceAttribute(kvm_ioctls::Error, bool, u32),
2527
/// The number of vCPUs in the GicState doesn't match the number of vCPUs on the system
28+
#[error(
29+
"The number of vCPUs in the GicState doesn't match the number of vCPUs on the system."
30+
)]
2631
InconsistentVcpuCount,
2732
/// The VgicSysRegsState is invalid
33+
#[error("The VgicSysRegsState is invalid.")]
2834
InvalidVgicSysRegState,
2935
}
3036
type Result<T> = result::Result<T, Error>;

src/arch/src/x86_64/interrupts.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ use kvm_bindings::kvm_lapic_state;
99
use kvm_ioctls::VcpuFd;
1010
use utils::byte_order;
1111
/// Errors thrown while configuring the LAPIC.
12-
#[derive(Debug)]
12+
#[derive(Debug, thiserror::Error, PartialEq)]
1313
pub enum Error {
14-
/// Failure in retrieving the LAPIC configuration.
14+
/// Failure in getting the LAPIC configuration.
15+
#[error("Failure in getting the LAPIC configuration: {0}")]
1516
GetLapic(kvm_ioctls::Error),
16-
/// Failure in modifying the LAPIC configuration.
17+
/// Failure in setting the LAPIC configuration.
18+
#[error("Failure in setting the LAPIC configuration: {0}")]
1719
SetLapic(kvm_ioctls::Error),
1820
}
1921
type Result<T> = std::result::Result<T, Error>;

src/arch/src/x86_64/msr.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,20 +282,44 @@ pub fn create_boot_msr_entries() -> Vec<kvm_msr_entry> {
282282
]
283283
}
284284

285+
/// Error type for [`set_msrs`].
286+
#[derive(Debug, thiserror::Error)]
287+
pub enum SetMSRsError {
288+
/// Failed to create [`vmm_sys_util::fam::FamStructWrapper`] for MSRs.
289+
#[error("Could not create `vmm_sys_util::fam::FamStructWrapper` for MSRs")]
290+
Create(utils::fam::Error),
291+
/// Settings MSRs resulted in an error.
292+
#[error("Setting MSRs resulted in an error: {0}")]
293+
Set(#[from] kvm_ioctls::Error),
294+
/// Not all given MSRs were set.
295+
#[error("Not all given MSRs were set.")]
296+
Incomplete,
297+
}
298+
285299
/// Configure Model Specific Registers (MSRs) required to boot Linux for a given x86_64 vCPU.
286300
///
287301
/// # Arguments
288302
///
289303
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
290-
pub fn set_msrs(vcpu: &VcpuFd, msr_entries: &[kvm_msr_entry]) -> Result<()> {
291-
let msrs = Msrs::from_entries(&msr_entries).map_err(Error::FamError)?;
304+
///
305+
/// # Errors
306+
///
307+
/// When:
308+
/// - Failed to create [`vmm_sys_util::fam::FamStructWrapper`] for MSRs.
309+
/// - [`kvm_ioctls::ioctls::vcpu::VcpuFd::set_msrs`] errors.
310+
/// - [`kvm_ioctls::ioctls::vcpu::VcpuFd::set_msrs`] fails to write all given MSRs entries.
311+
pub fn set_msrs(
312+
vcpu: &VcpuFd,
313+
msr_entries: &[kvm_msr_entry],
314+
) -> std::result::Result<(), SetMSRsError> {
315+
let msrs = Msrs::from_entries(&msr_entries).map_err(SetMSRsError::Create)?;
292316
vcpu.set_msrs(&msrs)
293-
.map_err(Error::SetModelSpecificRegisters)
317+
.map_err(SetMSRsError::Set)
294318
.and_then(|msrs_written| {
295-
if msrs_written as u32 != msrs.as_fam_struct_ref().nmsrs {
296-
Err(Error::SetModelSpecificRegistersCount)
297-
} else {
319+
if msrs_written as u32 == msrs.as_fam_struct_ref().nmsrs {
298320
Ok(())
321+
} else {
322+
Err(SetMSRsError::Incomplete)
299323
}
300324
})
301325
}

src/arch/src/x86_64/regs.rs

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// Use of this source code is governed by a BSD-style license that can be
66
// found in the THIRD-PARTY file.
77

8-
use std::mem;
8+
use std::{fmt, mem};
99

1010
use kvm_bindings::{kvm_fpu, kvm_regs, kvm_sregs};
1111
use kvm_ioctls::VcpuFd;
@@ -19,42 +19,76 @@ const PDPTE_START: u64 = 0xa000;
1919
const PDE_START: u64 = 0xb000;
2020

2121
/// Errors thrown while setting up x86_64 registers.
22-
#[derive(Debug)]
22+
#[derive(Debug, thiserror::Error, PartialEq)]
2323
pub enum Error {
2424
/// Failed to get SREGs for this CPU.
25+
#[error("Failed to get SREGs for this CPU: {0}")]
2526
GetStatusRegisters(kvm_ioctls::Error),
2627
/// Failed to set base registers for this CPU.
28+
#[error("Failed to set base registers for this CPU: {0}")]
2729
SetBaseRegisters(kvm_ioctls::Error),
2830
/// Failed to configure the FPU.
31+
#[error("Failed to configure the FPU: {0}")]
2932
SetFPURegisters(kvm_ioctls::Error),
3033
/// Failed to set SREGs for this CPU.
34+
#[error("Failed to set SREGs for this CPU: {0}")]
3135
SetStatusRegisters(kvm_ioctls::Error),
3236
/// Writing the GDT to RAM failed.
37+
#[error("Writing the GDT to RAM failed.")]
3338
WriteGDT,
3439
/// Writing the IDT to RAM failed.
40+
#[error("Writing the IDT to RAM failed")]
3541
WriteIDT,
3642
/// Writing PDPTE to RAM failed.
43+
#[error("WritePDPTEAddress")]
3744
WritePDPTEAddress,
3845
/// Writing PDE to RAM failed.
46+
#[error("WritePDEAddress")]
3947
WritePDEAddress,
4048
/// Writing PML4 to RAM failed.
49+
#[error("WritePML4Address")]
4150
WritePML4Address,
4251
}
4352
type Result<T> = std::result::Result<T, Error>;
4453

54+
/// Error type for [`setup_fpu`].
55+
#[derive(Debug, derive_more::From, PartialEq)]
56+
pub struct SetupFpuError(utils::errno::Error);
57+
impl std::error::Error for SetupFpuError {}
58+
impl fmt::Display for SetupFpuError {
59+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60+
write!(f, "Failed to setup FPU: {}", self.0)
61+
}
62+
}
63+
4564
/// Configure Floating-Point Unit (FPU) registers for a given CPU.
4665
///
4766
/// # Arguments
4867
///
4968
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
50-
pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
69+
///
70+
/// # Errors
71+
///
72+
/// When [`kvm_ioctls::ioctls::vcpu::VcpuFd::set_fpu`] errors.
73+
pub fn setup_fpu(vcpu: &VcpuFd) -> std::result::Result<(), SetupFpuError> {
5174
let fpu: kvm_fpu = kvm_fpu {
5275
fcw: 0x37f,
5376
mxcsr: 0x1f80,
5477
..Default::default()
5578
};
5679

57-
vcpu.set_fpu(&fpu).map_err(Error::SetFPURegisters)
80+
let res = vcpu.set_fpu(&fpu)?;
81+
Ok(res)
82+
}
83+
84+
/// Error type of [`setup_regs`].
85+
#[derive(Debug, derive_more::From, PartialEq)]
86+
pub struct SetupRegistersError(utils::errno::Error);
87+
impl std::error::Error for SetupRegistersError {}
88+
impl fmt::Display for SetupRegistersError {
89+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90+
write!(f, "Failed to setup registers:{}", self.0)
91+
}
5892
}
5993

6094
/// Configure base registers for a given CPU.
@@ -63,7 +97,11 @@ pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
6397
///
6498
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
6599
/// * `boot_ip` - Starting instruction pointer.
66-
pub fn setup_regs(vcpu: &VcpuFd, boot_ip: u64) -> Result<()> {
100+
///
101+
/// # Errors
102+
///
103+
/// When [`kvm_ioctls::ioctls::vcpu::VcpuFd::set_regs`] errors.
104+
pub fn setup_regs(vcpu: &VcpuFd, boot_ip: u64) -> std::result::Result<(), SetupRegistersError> {
67105
let regs: kvm_regs = kvm_regs {
68106
rflags: 0x0000_0000_0000_0002u64,
69107
rip: boot_ip,
@@ -79,22 +117,54 @@ pub fn setup_regs(vcpu: &VcpuFd, boot_ip: u64) -> Result<()> {
79117
..Default::default()
80118
};
81119

82-
vcpu.set_regs(&regs).map_err(Error::SetBaseRegisters)
120+
vcpu.set_regs(&regs).map_err(SetupRegistersError)
121+
}
122+
123+
/// Error type for [`setup_sregs`].
124+
#[derive(Debug, thiserror::Error, PartialEq)]
125+
pub enum SetupSpecialRegistersError {
126+
/// Failed to get special registers
127+
#[error("Failed to get special registers: {0}")]
128+
GetSpecialRegisters(utils::errno::Error),
129+
/// Failed to configure segments and special registers
130+
#[error("Failed to configure segments and special registers: {0}")]
131+
ConfigureSegmentsAndSpecialRegisters(Error),
132+
/// Failed to setup page tables
133+
#[error("Failed to setup page tables: {0}")]
134+
SetupPageTables(Error),
135+
/// Failed to set special registers
136+
#[error("Failed to set special registers: {0}")]
137+
SetSpecialRegisters(utils::errno::Error),
83138
}
84139

85-
/// Configures the segment registers and system page tables for a given CPU.
140+
/// Configures the special registers and system page tables for a given CPU.
86141
///
87142
/// # Arguments
88143
///
89144
/// * `mem` - The memory that will be passed to the guest.
90145
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
91-
pub fn setup_sregs(mem: &GuestMemoryMmap, vcpu: &VcpuFd) -> Result<()> {
92-
let mut sregs: kvm_sregs = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
93-
94-
configure_segments_and_sregs(mem, &mut sregs)?;
95-
setup_page_tables(mem, &mut sregs)?; // TODO(dgreid) - Can this be done once per system instead?
96-
97-
vcpu.set_sregs(&sregs).map_err(Error::SetStatusRegisters)
146+
///
147+
/// # Errors
148+
///
149+
/// When:
150+
/// - [`kvm_ioctls::ioctls::vcpu::VcpuFd::get_sregs`] errors.
151+
/// - [`configure_segments_and_sregs`] errors.
152+
/// - [`setup_page_tables`] errors
153+
/// - [`kvm_ioctls::ioctls::vcpu::VcpuFd::set_sregs`] errors.
154+
pub fn setup_sregs(
155+
mem: &GuestMemoryMmap,
156+
vcpu: &VcpuFd,
157+
) -> std::result::Result<(), SetupSpecialRegistersError> {
158+
let mut sregs: kvm_sregs = vcpu
159+
.get_sregs()
160+
.map_err(SetupSpecialRegistersError::GetSpecialRegisters)?;
161+
162+
configure_segments_and_sregs(mem, &mut sregs)
163+
.map_err(SetupSpecialRegistersError::ConfigureSegmentsAndSpecialRegisters)?;
164+
setup_page_tables(mem, &mut sregs).map_err(SetupSpecialRegistersError::SetupPageTables)?; // TODO(dgreid) - Can this be done once per system instead?
165+
166+
vcpu.set_sregs(&sregs)
167+
.map_err(SetupSpecialRegistersError::SetSpecialRegisters)
98168
}
99169

100170
const BOOT_GDT_OFFSET: u64 = 0x500;

src/cpuid/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license = "Apache-2.0"
99
kvm-bindings = { version = ">=0.5.0", features = ["fam-wrappers"] }
1010
kvm-ioctls = ">=0.9.0"
1111
derive_more = { version = "0.99.17", default-features = false, features = ["from"] }
12+
thiserror = "1.0.32"
1213

1314
utils = { path = "../utils"}
1415
arch = { path = "../arch" }

src/cpuid/src/common.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ pub const VENDOR_ID_INTEL: &[u8; 12] = b"GenuineIntel";
1818
pub const VENDOR_ID_AMD: &[u8; 12] = b"AuthenticAMD";
1919

2020
/// cpuid related error.
21-
#[derive(Clone, Debug)]
21+
#[derive(Clone, Debug, thiserror::Error, PartialEq, Eq)]
2222
pub enum Error {
2323
/// The function was called with invalid parameters.
24+
#[error("The function was called with invalid parameters.")]
2425
InvalidParameters(String),
2526
/// Function not supported on the current architecture.
27+
#[error("Function not supported on the current architecture.")]
2628
NotSupported,
2729
}
2830

0 commit comments

Comments
 (0)