Skip to content

Commit 2897ceb

Browse files
committed
Implement memory range transition and management
1 parent cd03ec9 commit 2897ceb

File tree

6 files changed

+175
-69
lines changed

6 files changed

+175
-69
lines changed

sgx_trts/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ hyper = ["sgx_types/hyper"]
3939
sgx_types = { path = "../sgx_types" }
4040
sgx_crypto_sys = { path = "../sgx_crypto/sgx_crypto_sys" }
4141
sgx_tlibc_sys = { path = "../sgx_libc/sgx_tlibc_sys" }
42-
intrusive-collections = "0.9.5"
42+
43+
intrusive-collections = { git = "https://github.com/ClawSeven/intrusive-rs.git", version = "0.9.5" }
4344
buddy_system_allocator = "0.9.0"
4445
spin = "0.9.4"
4546
bitflags = "1.3"

sgx_trts/src/emm/bitmap.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ impl<A: Allocator + Clone> BitArray<A> {
9999
break;
100100
}
101101
}
102-
true_range.push((start,end));
102+
true_range.push((start, end));
103103
}
104104

105-
return true_range;
105+
return true_range;
106106
}
107107

108108
/// Set the value of the bit at a given index.
@@ -155,6 +155,4 @@ impl<A: Allocator + Clone> BitArray<A> {
155155
}
156156
}
157157

158-
159-
160-
// FIXME: add more unit test
158+
// FIXME: add more unit test

sgx_trts/src/emm/ema.rs

+36-28
Original file line numberDiff line numberDiff line change
@@ -103,38 +103,33 @@ where
103103
}
104104
}
105105

106-
// Returns a newly allocated ema in charging of the memory in the range [addr, len).
107-
// After the call, the original ema will be left containing the elements [0, addr)
106+
// Returns a newly allocated ema in charging of the memory in the range [addr, len).
107+
// After the call, the original ema will be left containing the elements [0, addr)
108108
// with its previous capacity unchanged.
109-
pub fn split(&mut self, addr: usize) -> SgxResult<Box<EMA<A>,A>> {
109+
pub fn split(&mut self, addr: usize) -> SgxResult<Box<EMA<A>, A>> {
110110
let l_start = self.start;
111111
let l_length = addr - l_start;
112112

113113
let r_start = addr;
114114
let r_length = (self.start + self.length) - addr;
115115

116-
let new_bitarray = match &mut self.eaccept_map{
116+
let new_bitarray = match &mut self.eaccept_map {
117117
Some(bitarray) => {
118118
let pos = (addr - self.start) >> crate::arch::SE_PAGE_SHIFT;
119119
// split self.eaccept_map
120120
Some(bitarray.split(pos)?)
121121
}
122-
None => {
123-
None
124-
}
122+
None => None,
125123
};
126-
124+
127125
// 这里之后可以优化
128126
// 1. self.clone() 会把原有的bitmap重新alloc并复制一份,但其实clone之后这里是None即可
129127
// 2. 使用Box::new_in 会把 self.clone() 这部分在栈上的数据再拷贝一份到Box新申请的内存区域
130-
let mut new_ema: Box<EMA<A>,A> = Box::new_in(
131-
self.clone(),
132-
self.alloc.clone()
133-
);
128+
let mut new_ema: Box<EMA<A>, A> = Box::new_in(self.clone(), self.alloc.clone());
134129

135130
self.start = l_start;
136131
self.length = l_length;
137-
132+
138133
new_ema.start = r_start;
139134
new_ema.length = r_length;
140135
new_ema.eaccept_map = new_bitarray;
@@ -145,7 +140,11 @@ where
145140
// If the previous ema is divided into three parts -> (left ema, middle ema, right ema), return (middle ema, right ema).
146141
// If the previous ema is divided into two parts -> (left ema, right ema)
147142
// end split: return (None, right ema), start split: return (left ema, None)
148-
fn split_into_three(&mut self, start: usize, length: usize) -> SgxResult<(Option<Box<EMA<A>,A>>, Option<Box<EMA<A>,A>>)> {
143+
fn split_into_three(
144+
&mut self,
145+
start: usize,
146+
length: usize,
147+
) -> SgxResult<(Option<Box<EMA<A>, A>>, Option<Box<EMA<A>, A>>)> {
149148
if start > self.start {
150149
let mut new_ema = self.split(start)?;
151150
if new_ema.start + new_ema.length > start + length {
@@ -260,8 +259,10 @@ where
260259
/// uncommit EPC page
261260
pub fn uncommit(&mut self, start: usize, length: usize, prot: ProtFlags) -> SgxResult {
262261
// need READ for trimming
263-
ensure!(self.info.prot != ProtFlags::NONE && self.eaccept_map.is_some(),
264-
SgxStatus::InvalidParameter);
262+
ensure!(
263+
self.info.prot != ProtFlags::NONE && self.eaccept_map.is_some(),
264+
SgxStatus::InvalidParameter
265+
);
265266

266267
if self.alloc_flags.contains(AllocFlags::RESERVED) {
267268
return Ok(());
@@ -303,21 +304,23 @@ where
303304
}
304305

305306
let block_length = block_end - block_start;
306-
perm::modify_ocall(block_start, block_length,
307-
PageInfo {
307+
perm::modify_ocall(
308+
block_start,
309+
block_length,
310+
PageInfo {
308311
typ: self.info.typ,
309312
prot,
310313
},
311-
PageInfo {
314+
PageInfo {
312315
typ: PageType::Trim,
313316
prot,
314317
},
315318
)?;
316319

317320
let pages = PageRange::new(
318-
block_start,
319-
block_length / crate::arch::SE_PAGE_SIZE,
320-
trim_info
321+
block_start,
322+
block_length / crate::arch::SE_PAGE_SIZE,
323+
trim_info,
321324
)?;
322325

323326
let init_idx = (block_start - self.start) >> crate::arch::SE_PAGE_SHIFT;
@@ -328,12 +331,14 @@ where
328331
}
329332

330333
// eaccept trim notify
331-
perm::modify_ocall(block_start, block_length,
332-
PageInfo {
334+
perm::modify_ocall(
335+
block_start,
336+
block_length,
337+
PageInfo {
333338
typ: PageType::Trim,
334339
prot,
335340
},
336-
PageInfo {
341+
PageInfo {
337342
typ: PageType::Trim,
338343
prot,
339344
},
@@ -401,7 +406,7 @@ where
401406
)?;
402407
}
403408

404-
Ok(())
409+
Ok(())
405410
}
406411

407412
pub fn dealloc(&mut self) -> SgxResult {
@@ -425,6 +430,10 @@ where
425430
self.start
426431
}
427432

433+
pub fn len(&self) -> usize {
434+
self.length
435+
}
436+
428437
// get and set attributes
429438
pub fn set_flags(flags: AllocFlags) -> SgxResult<()> {
430439
todo!()
@@ -443,12 +452,11 @@ where
443452
}
444453
}
445454

446-
//
455+
//
447456
// intrusive_adapter!(pub RegEmaAda = Box<EMA<ResAlloc>, ResAlloc>: EMA<ResAlloc> { link: LinkedListLink });
448457

449458
// regular ema adapter
450459
intrusive_adapter!(pub RegEmaAda = Box<EMA<ResAlloc>>: EMA<ResAlloc> { link: LinkedListLink });
451460

452461
// reserve ema adapter
453462
intrusive_adapter!(pub ResEmaAda = Box<EMA<ResAlloc>>: EMA<ResAlloc> { link: LinkedListLink });
454-

sgx_trts/src/emm/interior.rs

+101-26
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
use buddy_system_allocator::LockedHeap;
1919
use intrusive_collections::intrusive_adapter;
20+
use intrusive_collections::linked_list::CursorMut;
2021
use intrusive_collections::{LinkedList, LinkedListLink};
2122

2223
use alloc::boxed::Box;
@@ -30,8 +31,9 @@ use spin::{Mutex, Once};
3031
use sgx_types::error::{SgxResult, SgxStatus};
3132
use sgx_types::types::ProtectPerm;
3233

34+
use crate::emm::alloc::ResAlloc;
3335
use crate::emm::ema::EMA;
34-
use crate::emm::user::{USER_RANGE, self, is_within_user_range};
36+
use crate::emm::user::{self, is_within_rts_range, is_within_user_range, USER_RANGE};
3537
use crate::enclave::is_within_enclave;
3638

3739
use super::ema::ResEmaAda;
@@ -40,7 +42,7 @@ const STATIC_MEM_SIZE: usize = 65536;
4042

4143
/// first level: static memory
4244
static STATIC: LockedHeap<32> = LockedHeap::empty();
43-
45+
4446
static mut STATIC_MEM: [u8; STATIC_MEM_SIZE] = [0; STATIC_MEM_SIZE];
4547

4648
pub fn init() {
@@ -185,57 +187,130 @@ impl Reserve {
185187
todo!()
186188
}
187189

190+
fn search_ema_range(
191+
&mut self,
192+
addr: usize,
193+
len: usize,
194+
) -> SgxResult<(Box<EMA<ResAlloc>>, usize)> {
195+
let mut cursor: CursorMut<'_, ResEmaAda> = self.emas.front_mut();
196+
let ema_box = cursor.as_cursor().clone_pointer().unwrap();
197+
198+
let ptr = Box::into_raw(ema_box) as *const EMA<ResAlloc>;
199+
200+
let cursor_mut = unsafe { self.emas.cursor_mut_from_ptr(ptr) };
201+
202+
todo!()
203+
}
204+
205+
// Find a free space at addr with 'len' bytes in reserve region,
206+
// the request space mustn't intersect with existed ema node.
207+
// If success, return the next ema cursor.
208+
fn find_free_region_at(
209+
&mut self,
210+
addr: usize,
211+
len: usize,
212+
) -> SgxResult<CursorMut<'_, ResEmaAda>> {
213+
if !is_within_enclave(addr as *const u8, len) || !is_within_rts_range(addr, len) {
214+
return Err(SgxStatus::InvalidParameter);
215+
}
216+
217+
let mut cursor: CursorMut<'_, ResEmaAda> = self.emas.front_mut();
218+
while !cursor.is_null() {
219+
let start_curr = cursor.get().map(|ema| ema.start()).unwrap();
220+
let end_curr = start_curr + cursor.get().map(|ema| ema.len()).unwrap();
221+
if start_curr >= addr + len {
222+
return Ok(cursor);
223+
}
224+
225+
if addr >= end_curr {
226+
cursor.move_next();
227+
} else {
228+
break;
229+
}
230+
}
231+
232+
// means addr is larger than the end of the last ema node
233+
if cursor.is_null() {
234+
return Ok(cursor);
235+
}
236+
237+
return Err(SgxStatus::InvalidParameter);
238+
}
239+
188240
// Find a free space of size at least 'size' bytes in reserve region,
189241
// return the start address
190-
fn find_free_region(&mut self, len: usize, align: usize) -> SgxResult<usize> {
242+
fn find_free_region(
243+
&mut self,
244+
len: usize,
245+
align: usize,
246+
) -> SgxResult<(usize, CursorMut<'_, ResEmaAda>)> {
191247
let user_range = USER_RANGE.get().unwrap();
192248
let user_base = user_range.start;
193249
let user_end = user_range.end;
194250

195-
// no ema in list
196-
if self.emas.is_empty() {
197-
let mut addr = 0;
251+
let mut addr = 0;
198252

253+
let mut cursor: CursorMut<'_, ResEmaAda> = self.emas.front_mut();
254+
// no ema in list
255+
if cursor.is_null() {
199256
if user_base >= len {
200257
addr = trim_to!(user_base - len, align);
201258
if is_within_enclave(addr as *const u8, len) {
202-
return Ok(addr);
259+
return Ok((addr, cursor));
203260
}
204261
} else {
205262
addr = round_to!(user_end, align);
206263
if is_within_enclave(addr as *const u8, len) {
207-
return Ok(addr);
264+
return Ok((addr, cursor));
208265
}
209266
}
210267
return Err(SgxStatus::InvalidParameter);
211268
}
212269

270+
let mut cursor_next = cursor.peek_next();
213271

214-
let mut cursor = self.emas.cursor_mut();
215-
while !cursor.is_null() {
216-
let curr_end = cursor.get()
217-
.map(|ema| ema.aligned_end(align)).unwrap();
272+
// ema is_null means pointing to the Null object, not means this ema is empty
273+
while !cursor_next.is_null() {
274+
let curr_end = cursor.get().map(|ema| ema.aligned_end(align)).unwrap();
218275

219-
cursor.move_next();
220-
if cursor.is_null() {
221-
break;
222-
}
223-
224-
let next_start = cursor.get()
225-
.map(|ema| ema.start()).unwrap();
226-
227-
if curr_end < next_start {
228-
let free_size = next_start - curr_end;
229-
// 这里或许得用is_within_rts
230-
if free_size < len && is_within_enclave(curr_end as *const u8, len){
231-
return Ok(curr_end);
276+
let start_next = cursor_next.get().map(|ema| ema.start()).unwrap();
277+
278+
if curr_end < start_next {
279+
let free_size = start_next - curr_end;
280+
if free_size < len && is_within_rts_range(curr_end, len) {
281+
cursor.move_next();
282+
return Ok((curr_end, cursor));
232283
}
233284
}
234285
cursor.move_next();
286+
cursor_next = cursor.peek_next();
235287
}
236288

289+
addr = cursor.get().map(|ema| ema.aligned_end(align)).unwrap();
237290

238-
todo!()
291+
if is_within_enclave(addr as *const u8, len) && is_within_rts_range(addr, len) {
292+
cursor.move_next();
293+
return Ok((addr, cursor));
294+
}
295+
296+
// Cursor moves to emas->front_mut.
297+
// Firstly cursor moves to None, then moves to linkedlist head
298+
cursor.move_next();
299+
cursor.move_next();
300+
301+
// Back to the first ema to check rts region before user region
302+
let start_first = cursor.get().map(|ema| ema.start()).unwrap();
303+
if start_first < len {
304+
return Err(SgxStatus::InvalidParameter);
305+
}
306+
307+
addr = trim_to!(start_first, align);
308+
309+
if is_within_enclave(addr as *const u8, len) && is_within_rts_range(addr, len) {
310+
return Ok((addr, cursor));
311+
}
312+
313+
Err(SgxStatus::InvalidParameter)
239314
}
240315
}
241316

0 commit comments

Comments
 (0)