-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy patherror.rs
139 lines (132 loc) · 5.24 KB
/
error.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! UserspaceError and KernelError
use failure::Backtrace;
use crate::paging::error::MmError;
use crate::mem::VirtualAddress;
use core::fmt::{self, Display};
pub use kfs_libkern::error::KernelError as UserspaceError;
#[derive(Debug, Clone, Copy)]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub enum ArithmeticOperation { Add, Sub, Mul, Div, Mod, Pow }
impl Display for ArithmeticOperation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ArithmeticOperation::Add => write!(f, "+"),
ArithmeticOperation::Sub => write!(f, "-"),
ArithmeticOperation::Mul => write!(f, "*"),
ArithmeticOperation::Div => write!(f, "/"),
ArithmeticOperation::Mod => write!(f, "%"),
ArithmeticOperation::Pow => write!(f, "**"),
}
}
}
/// Kernel Error.
///
/// Used pretty much everywhere that an error can occur. Holds the reason of the error,
/// and a backtrace of its origin, for debug.
///
/// When a KernelError must be propagated to userspace, i.e. a syscall failed, it must be
/// converted to a [UserspaceError].
#[derive(Debug, Fail)]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub enum KernelError {
#[fail(display = "Frame allocation error: physical address space exhausted")]
PhysicalMemoryExhaustion {
backtrace: Backtrace
},
#[fail(display = "Virtual allocation error: virtual address space exhausted")]
VirtualMemoryExhaustion {
backtrace: Backtrace,
},
#[fail(display = "Invalid address: virtual address {} len {} is considered invalid", address, length)]
InvalidAddress {
address: VirtualAddress,
length: usize,
backtrace: Backtrace,
},
#[fail(display = "Invalid size: size {} is considered invalid", size)]
InvalidSize {
size: usize,
backtrace: Backtrace,
},
#[fail(display = "Alignment error: expected alignment {}, got {}", needed, given)]
AlignmentError {
given: usize,
needed: usize,
backtrace: Backtrace,
},
#[fail(display = "Arithmetic error: {} {} {} would cause an overflow", lhs, operation, rhs)]
WouldOverflow {
lhs: usize,
rhs: usize,
operation: ArithmeticOperation,
backtrace: Backtrace,
},
#[fail(display = "Length error: length is 0")]
ZeroLengthError {
backtrace: Backtrace,
},
#[fail(display = "Memory management error: {}", _0)]
MmError(MmError),
#[fail(display = "Process was killed before finishing operation")]
ProcessKilled {
backtrace: Backtrace,
},
#[fail(display = "Thread was already started")]
ThreadAlreadyStarted {
backtrace: Backtrace,
},
#[fail(display = "Invalid combination of values passed.")]
InvalidCombination {
backtrace: Backtrace,
},
#[fail(display = "The passed value ({}) would overflow the maximum ({}).", value, maximum)]
ExceedingMaximum {
value: u64,
maximum: u64,
backtrace: Backtrace,
},
#[fail(display = "Invalid kernel capability u32: {}", _0)]
InvalidKernelCaps {
kcap: u32,
backtrace: Backtrace,
},
// TODO: Properly split this up.
#[fail(display = "Error related to IPC")]
IpcError {
backtrace: Backtrace,
},
#[fail(display = "Value is reserved for future use.")]
ReservedValue {
backtrace: Backtrace,
},
#[doc(hidden)]
#[fail(display = "Should never ever ***EVER*** be returned")]
ThisWillNeverHappenButPleaseDontMatchExhaustively,
}
impl From<KernelError> for UserspaceError {
fn from(err: KernelError) -> UserspaceError {
match err {
KernelError::PhysicalMemoryExhaustion { .. } => UserspaceError::MemoryFull,
KernelError::VirtualMemoryExhaustion { .. } => UserspaceError::MemoryFull,
KernelError::ThreadAlreadyStarted { .. } => UserspaceError::ProcessAlreadyStarted,
KernelError::InvalidAddress { .. } => UserspaceError::InvalidAddress,
KernelError::InvalidSize { .. } => UserspaceError::InvalidSize,
KernelError::ZeroLengthError { .. } => UserspaceError::InvalidSize,
// TODO: AlignementError should discriminate unaligned size and unaligned address
// BODY: We can only convey InvalidSize and InvalidAddress to userspace.
// BODY: We should define two check functions, that work on a either size or an address,
// BODY: and can propagate the right error to userspace automatically.
// BODY:
// BODY: We must then remove KernelError::AlignmentError.
KernelError::AlignmentError { .. } => UserspaceError::InvalidAddress,
KernelError::InvalidCombination { .. } => UserspaceError::InvalidCombination,
KernelError::ExceedingMaximum { .. } => UserspaceError::ExceedingMaximum,
KernelError::InvalidKernelCaps { .. } => UserspaceError::InvalidKernelCaps,
KernelError::ReservedValue { .. } => UserspaceError::ReservedValue,
//KernelError::
KernelError::ThisWillNeverHappenButPleaseDontMatchExhaustively => unreachable!(),
// todo
_ => unimplemented!("Unmatched Error: {}", err)
}
}
}