1use twizzler_rt_abi::error::RawTwzError;
4
5pub use crate::arch::upcall::UpcallFrame;
6use crate::object::ObjID;
7
8#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
10#[repr(C)]
11pub struct ExceptionInfo {
12 pub code: u64,
14 pub info: u64,
16}
17
18impl ExceptionInfo {
19 pub fn new(code: u64, info: u64) -> Self {
21 Self { code, info }
22 }
23}
24
25#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
27#[repr(C)]
28pub struct ObjectMemoryFaultInfo {
29 pub object_id: ObjID,
31 pub error: ObjectMemoryError,
33 pub access: MemoryAccessKind,
35 pub addr: usize,
37}
38
39impl ObjectMemoryFaultInfo {
40 pub fn new(
42 object_id: ObjID,
43 error: ObjectMemoryError,
44 access: MemoryAccessKind,
45 addr: usize,
46 ) -> Self {
47 Self {
48 object_id,
49 error,
50 access,
51 addr,
52 }
53 }
54}
55
56#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
58#[repr(u8)]
59pub enum ObjectMemoryError {
60 NullPageAccess,
62 OutOfBounds(usize),
64 BackingFailed(RawTwzError),
66}
67
68#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
70#[repr(C)]
71pub struct MemoryContextViolationInfo {
72 pub address: u64,
74 pub kind: MemoryAccessKind,
76}
77
78impl MemoryContextViolationInfo {
79 pub fn new(address: u64, kind: MemoryAccessKind) -> Self {
80 Self { address, kind }
81 }
82}
83
84#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
86#[repr(u8)]
87pub enum MemoryAccessKind {
88 Read,
89 Write,
90 InstructionFetch,
91}
92
93#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
95#[repr(C)]
96pub struct SecurityViolationInfo {
97 pub address: u64,
99 pub access_kind: MemoryAccessKind,
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
105#[repr(C)]
106pub enum UpcallInfo {
107 Exception(ExceptionInfo),
108 ObjectMemoryFault(ObjectMemoryFaultInfo),
109 MemoryContextViolation(MemoryContextViolationInfo),
110 SecurityViolation(SecurityViolationInfo),
111}
112
113impl UpcallInfo {
114 pub const NR_UPCALLS: usize = 3;
116 pub fn number(&self) -> usize {
118 match self {
119 UpcallInfo::Exception(_) => 0,
120 UpcallInfo::ObjectMemoryFault(_) => 1,
121 UpcallInfo::MemoryContextViolation(_) => 2,
122 UpcallInfo::SecurityViolation(_) => 3,
123 }
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
130#[repr(C)]
131pub struct UpcallData {
132 pub info: UpcallInfo,
134 pub flags: UpcallHandlerFlags,
136 pub source_ctx: ObjID,
138 pub thread_id: ObjID,
140}
141
142#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
145#[repr(C)]
146pub struct UpcallTarget {
147 pub self_address: usize,
149 pub super_address: usize,
151 pub super_stack: usize,
153 pub super_stack_size: usize,
155 pub super_thread_ptr: usize,
157 pub super_ctx: ObjID,
159 pub options: [UpcallOptions; UpcallInfo::NR_UPCALLS],
161}
162
163impl UpcallTarget {
164 pub fn new(
166 self_address: Option<
167 unsafe extern "C-unwind" fn(*mut core::ffi::c_void, *const core::ffi::c_void) -> !,
168 >,
169 super_address: Option<
170 unsafe extern "C-unwind" fn(*mut core::ffi::c_void, *const core::ffi::c_void) -> !,
171 >,
172 super_stack: usize,
173 super_stack_size: usize,
174 super_thread_ptr: usize,
175 super_ctx: ObjID,
176 options: [UpcallOptions; UpcallInfo::NR_UPCALLS],
177 ) -> Self {
178 Self {
179 self_address: self_address.map(|addr| addr as usize).unwrap_or_default(),
180 super_address: super_address.map(|addr| addr as usize).unwrap_or_default(),
181 super_stack,
182 super_thread_ptr,
183 super_ctx,
184 options,
185 super_stack_size,
186 }
187 }
188}
189
190pub const UPCALL_EXIT_CODE: u64 = 127;
194
195bitflags::bitflags! {
196 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
198pub struct UpcallFlags : u8 {
199 const SUSPEND = 1;
201}
202}
203
204bitflags::bitflags! {
205 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
207pub struct UpcallHandlerFlags : u8 {
208 const SWITCHED_CONTEXT = 1;
210}
211}
212
213#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
215pub enum UpcallMode {
216 Abort,
219 CallSelf,
223 CallSuper,
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
233pub struct UpcallOptions {
234 pub flags: UpcallFlags,
236 pub mode: UpcallMode,
238}