kernel/
restricted_state.rs1use core::ffi::c_void;
6use core::ptr::{self, NonNull};
7use debug::ltracef;
8use kalloc::Box;
9use zx_status::Status;
10use zx_types::{zx_exception_report_t, zx_restricted_state_t, zx_status_t};
11
12use arch_rs::ArchSavedNormalState;
13
14const LOCAL_TRACE: u32 = 0;
15
16unsafe extern "C" {
17 fn cpp_restricted_state_create_vmo_mapping(
18 out_vmo: *mut *mut c_void,
19 out_mapping: *mut *mut c_void,
20 out_base: *mut *mut zx_restricted_state_t,
21 ) -> zx_status_t;
22 fn cpp_restricted_state_destroy_vmo_mapping(vmo: *mut c_void, mapping: *mut c_void);
23}
24
25#[repr(C)]
33pub struct RestrictedState {
34 in_restricted: bool,
35 vector_ptr: usize,
36 context: usize,
37 exception_report_ptr: *mut zx_exception_report_t,
38 vmo: NonNull<c_void>,
39 mapping: NonNull<c_void>,
40 state_mapping_ptr: NonNull<zx_restricted_state_t>,
41 arch: ArchSavedNormalState,
42}
43
44const _: () = {
50 assert!(core::mem::offset_of!(RestrictedState, in_restricted) == 0);
51 assert!(core::mem::offset_of!(RestrictedState, vector_ptr) == 8);
52 assert!(core::mem::offset_of!(RestrictedState, context) == 16);
53 assert!(core::mem::offset_of!(RestrictedState, exception_report_ptr) == 24);
54 assert!(core::mem::offset_of!(RestrictedState, vmo) == 32);
55 assert!(core::mem::offset_of!(RestrictedState, mapping) == 40);
56 assert!(core::mem::offset_of!(RestrictedState, state_mapping_ptr) == 48);
57 assert!(core::mem::offset_of!(RestrictedState, arch) == 56);
58 assert!(core::mem::align_of::<RestrictedState>() == 8);
59 #[cfg(not(target_arch = "riscv64"))]
60 assert!(core::mem::size_of::<RestrictedState>() == 72);
61 #[cfg(target_arch = "riscv64")]
62 assert!(core::mem::size_of::<RestrictedState>() == 64);
63};
64
65impl RestrictedState {
66 pub fn create(exception_report_ptr: *mut zx_exception_report_t) -> Result<Box<Self>, Status> {
68 let mut raw_vmo = ptr::null_mut();
69 let mut raw_mapping = ptr::null_mut();
70 let mut raw_base = ptr::null_mut();
71 let raw_status = unsafe {
74 cpp_restricted_state_create_vmo_mapping(&mut raw_vmo, &mut raw_mapping, &mut raw_base)
75 };
76 Status::ok(raw_status)?;
77
78 let (vmo, mapping, state_mapping_ptr) =
79 match (NonNull::new(raw_vmo), NonNull::new(raw_mapping), NonNull::new(raw_base)) {
80 (Some(vmo), Some(mapping), Some(base)) => (vmo, mapping, base),
81 _ => {
82 unsafe { cpp_restricted_state_destroy_vmo_mapping(raw_vmo, raw_mapping) };
84 return Err(Status::NO_MEMORY);
85 }
86 };
87
88 ltracef!("mapping at {:#x}\n", state_mapping_ptr.as_ptr() as usize);
89
90 let state = Box::try_new(Self {
91 in_restricted: false,
92 vector_ptr: 0,
93 context: 0,
94 exception_report_ptr,
95 vmo,
96 mapping,
97 state_mapping_ptr,
98 arch: ArchSavedNormalState::default(),
99 });
100
101 match state {
102 Ok(s) => Ok(s),
103 Err(_) => {
104 unsafe { cpp_restricted_state_destroy_vmo_mapping(raw_vmo, raw_mapping) };
106 Err(Status::NO_MEMORY)
107 }
108 }
109 }
110
111 pub fn in_restricted(&self) -> bool {
113 self.in_restricted
114 }
115
116 pub fn set_in_restricted(&mut self, val: bool) {
118 self.in_restricted = val;
119 }
120
121 pub fn vector_ptr(&self) -> usize {
123 self.vector_ptr
124 }
125
126 pub fn set_vector_ptr(&mut self, val: usize) {
128 self.vector_ptr = val;
129 }
130
131 pub fn context(&self) -> usize {
133 self.context
134 }
135
136 pub fn set_context(&mut self, val: usize) {
138 self.context = val;
139 }
140
141 pub fn exception_report_ptr(&self) -> *mut zx_exception_report_t {
143 self.exception_report_ptr
144 }
145
146 pub fn arch_normal_state(&self) -> &ArchSavedNormalState {
148 &self.arch
149 }
150
151 pub fn arch_normal_state_mut(&mut self) -> &mut ArchSavedNormalState {
153 &mut self.arch
154 }
155
156 pub fn state(&self) -> &zx_restricted_state_t {
158 unsafe { self.state_mapping_ptr.as_ref() }
160 }
161
162 pub fn state_mut(&mut self) -> &mut zx_restricted_state_t {
164 unsafe { self.state_mapping_ptr.as_mut() }
166 }
167
168 pub fn state_ptr(&self) -> *mut zx_restricted_state_t {
170 self.state_mapping_ptr.as_ptr()
171 }
172
173 pub fn vmo(&self) -> *mut c_void {
175 self.vmo.as_ptr()
176 }
177}
178
179impl Drop for RestrictedState {
180 fn drop(&mut self) {
181 unsafe {
184 cpp_restricted_state_destroy_vmo_mapping(self.vmo.as_ptr(), self.mapping.as_ptr());
185 }
186 }
187}
188
189#[unsafe(no_mangle)]
195pub unsafe extern "C" fn rust_restricted_state_create(
196 exception_report_ptr: *mut zx_exception_report_t,
197 out_ptr: *mut *mut RestrictedState,
198) -> zx_status_t {
199 match RestrictedState::create(exception_report_ptr) {
200 Ok(box_state) => {
201 unsafe {
203 *out_ptr = Box::into_raw(box_state);
204 }
205 Status::OK.into_raw()
206 }
207 Err(status) => status.into_raw(),
208 }
209}
210
211#[unsafe(no_mangle)]
217pub unsafe extern "C" fn rust_restricted_state_destroy(ptr: *mut RestrictedState) {
218 if !ptr.is_null() {
219 unsafe {
221 let _ = Box::from_raw(ptr);
222 }
223 }
224}