Skip to content

Commit

Permalink
Implement memory range transition and management
Browse files Browse the repository at this point in the history
  • Loading branch information
ClawSeven committed Jun 26, 2023
1 parent cd03ec9 commit 2897ceb
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 69 deletions.
3 changes: 2 additions & 1 deletion sgx_trts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ hyper = ["sgx_types/hyper"]
sgx_types = { path = "../sgx_types" }
sgx_crypto_sys = { path = "../sgx_crypto/sgx_crypto_sys" }
sgx_tlibc_sys = { path = "../sgx_libc/sgx_tlibc_sys" }
intrusive-collections = "0.9.5"

intrusive-collections = { git = "https://github.com/ClawSeven/intrusive-rs.git", version = "0.9.5" }
buddy_system_allocator = "0.9.0"
spin = "0.9.4"
bitflags = "1.3"
8 changes: 3 additions & 5 deletions sgx_trts/src/emm/bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ impl<A: Allocator + Clone> BitArray<A> {
break;
}
}
true_range.push((start,end));
true_range.push((start, end));
}

return true_range;
return true_range;
}

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



// FIXME: add more unit test
// FIXME: add more unit test
64 changes: 36 additions & 28 deletions sgx_trts/src/emm/ema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,38 +103,33 @@ where
}
}

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

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

let new_bitarray = match &mut self.eaccept_map{
let new_bitarray = match &mut self.eaccept_map {
Some(bitarray) => {
let pos = (addr - self.start) >> crate::arch::SE_PAGE_SHIFT;
// split self.eaccept_map
Some(bitarray.split(pos)?)
}
None => {
None
}
None => None,
};

// 这里之后可以优化
// 1. self.clone() 会把原有的bitmap重新alloc并复制一份,但其实clone之后这里是None即可
// 2. 使用Box::new_in 会把 self.clone() 这部分在栈上的数据再拷贝一份到Box新申请的内存区域
let mut new_ema: Box<EMA<A>,A> = Box::new_in(
self.clone(),
self.alloc.clone()
);
let mut new_ema: Box<EMA<A>, A> = Box::new_in(self.clone(), self.alloc.clone());

self.start = l_start;
self.length = l_length;

new_ema.start = r_start;
new_ema.length = r_length;
new_ema.eaccept_map = new_bitarray;
Expand All @@ -145,7 +140,11 @@ where
// If the previous ema is divided into three parts -> (left ema, middle ema, right ema), return (middle ema, right ema).
// If the previous ema is divided into two parts -> (left ema, right ema)
// end split: return (None, right ema), start split: return (left ema, None)
fn split_into_three(&mut self, start: usize, length: usize) -> SgxResult<(Option<Box<EMA<A>,A>>, Option<Box<EMA<A>,A>>)> {
fn split_into_three(
&mut self,
start: usize,
length: usize,
) -> SgxResult<(Option<Box<EMA<A>, A>>, Option<Box<EMA<A>, A>>)> {
if start > self.start {
let mut new_ema = self.split(start)?;
if new_ema.start + new_ema.length > start + length {
Expand Down Expand Up @@ -260,8 +259,10 @@ where
/// uncommit EPC page
pub fn uncommit(&mut self, start: usize, length: usize, prot: ProtFlags) -> SgxResult {
// need READ for trimming
ensure!(self.info.prot != ProtFlags::NONE && self.eaccept_map.is_some(),
SgxStatus::InvalidParameter);
ensure!(
self.info.prot != ProtFlags::NONE && self.eaccept_map.is_some(),
SgxStatus::InvalidParameter
);

if self.alloc_flags.contains(AllocFlags::RESERVED) {
return Ok(());
Expand Down Expand Up @@ -303,21 +304,23 @@ where
}

let block_length = block_end - block_start;
perm::modify_ocall(block_start, block_length,
PageInfo {
perm::modify_ocall(
block_start,
block_length,
PageInfo {
typ: self.info.typ,
prot,
},
PageInfo {
PageInfo {
typ: PageType::Trim,
prot,
},
)?;

let pages = PageRange::new(
block_start,
block_length / crate::arch::SE_PAGE_SIZE,
trim_info
block_start,
block_length / crate::arch::SE_PAGE_SIZE,
trim_info,
)?;

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

// eaccept trim notify
perm::modify_ocall(block_start, block_length,
PageInfo {
perm::modify_ocall(
block_start,
block_length,
PageInfo {
typ: PageType::Trim,
prot,
},
PageInfo {
PageInfo {
typ: PageType::Trim,
prot,
},
Expand Down Expand Up @@ -401,7 +406,7 @@ where
)?;
}

Ok(())
Ok(())
}

pub fn dealloc(&mut self) -> SgxResult {
Expand All @@ -425,6 +430,10 @@ where
self.start
}

pub fn len(&self) -> usize {
self.length
}

// get and set attributes
pub fn set_flags(flags: AllocFlags) -> SgxResult<()> {
todo!()
Expand All @@ -443,12 +452,11 @@ where
}
}

//
//
// intrusive_adapter!(pub RegEmaAda = Box<EMA<ResAlloc>, ResAlloc>: EMA<ResAlloc> { link: LinkedListLink });

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

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

127 changes: 101 additions & 26 deletions sgx_trts/src/emm/interior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

use buddy_system_allocator::LockedHeap;
use intrusive_collections::intrusive_adapter;
use intrusive_collections::linked_list::CursorMut;
use intrusive_collections::{LinkedList, LinkedListLink};

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

use crate::emm::alloc::ResAlloc;
use crate::emm::ema::EMA;
use crate::emm::user::{USER_RANGE, self, is_within_user_range};
use crate::emm::user::{self, is_within_rts_range, is_within_user_range, USER_RANGE};
use crate::enclave::is_within_enclave;

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

/// first level: static memory
static STATIC: LockedHeap<32> = LockedHeap::empty();

static mut STATIC_MEM: [u8; STATIC_MEM_SIZE] = [0; STATIC_MEM_SIZE];

pub fn init() {
Expand Down Expand Up @@ -185,57 +187,130 @@ impl Reserve {
todo!()
}

fn search_ema_range(
&mut self,
addr: usize,
len: usize,
) -> SgxResult<(Box<EMA<ResAlloc>>, usize)> {
let mut cursor: CursorMut<'_, ResEmaAda> = self.emas.front_mut();
let ema_box = cursor.as_cursor().clone_pointer().unwrap();

let ptr = Box::into_raw(ema_box) as *const EMA<ResAlloc>;

let cursor_mut = unsafe { self.emas.cursor_mut_from_ptr(ptr) };

todo!()
}

// Find a free space at addr with 'len' bytes in reserve region,
// the request space mustn't intersect with existed ema node.
// If success, return the next ema cursor.
fn find_free_region_at(
&mut self,
addr: usize,
len: usize,
) -> SgxResult<CursorMut<'_, ResEmaAda>> {
if !is_within_enclave(addr as *const u8, len) || !is_within_rts_range(addr, len) {
return Err(SgxStatus::InvalidParameter);
}

let mut cursor: CursorMut<'_, ResEmaAda> = self.emas.front_mut();
while !cursor.is_null() {
let start_curr = cursor.get().map(|ema| ema.start()).unwrap();
let end_curr = start_curr + cursor.get().map(|ema| ema.len()).unwrap();
if start_curr >= addr + len {
return Ok(cursor);
}

if addr >= end_curr {
cursor.move_next();
} else {
break;
}
}

// means addr is larger than the end of the last ema node
if cursor.is_null() {
return Ok(cursor);
}

return Err(SgxStatus::InvalidParameter);
}

// Find a free space of size at least 'size' bytes in reserve region,
// return the start address
fn find_free_region(&mut self, len: usize, align: usize) -> SgxResult<usize> {
fn find_free_region(
&mut self,
len: usize,
align: usize,
) -> SgxResult<(usize, CursorMut<'_, ResEmaAda>)> {
let user_range = USER_RANGE.get().unwrap();
let user_base = user_range.start;
let user_end = user_range.end;

// no ema in list
if self.emas.is_empty() {
let mut addr = 0;
let mut addr = 0;

let mut cursor: CursorMut<'_, ResEmaAda> = self.emas.front_mut();
// no ema in list
if cursor.is_null() {
if user_base >= len {
addr = trim_to!(user_base - len, align);
if is_within_enclave(addr as *const u8, len) {
return Ok(addr);
return Ok((addr, cursor));
}
} else {
addr = round_to!(user_end, align);
if is_within_enclave(addr as *const u8, len) {
return Ok(addr);
return Ok((addr, cursor));
}
}
return Err(SgxStatus::InvalidParameter);
}

let mut cursor_next = cursor.peek_next();

let mut cursor = self.emas.cursor_mut();
while !cursor.is_null() {
let curr_end = cursor.get()
.map(|ema| ema.aligned_end(align)).unwrap();
// ema is_null means pointing to the Null object, not means this ema is empty
while !cursor_next.is_null() {
let curr_end = cursor.get().map(|ema| ema.aligned_end(align)).unwrap();

cursor.move_next();
if cursor.is_null() {
break;
}

let next_start = cursor.get()
.map(|ema| ema.start()).unwrap();

if curr_end < next_start {
let free_size = next_start - curr_end;
// 这里或许得用is_within_rts
if free_size < len && is_within_enclave(curr_end as *const u8, len){
return Ok(curr_end);
let start_next = cursor_next.get().map(|ema| ema.start()).unwrap();

if curr_end < start_next {
let free_size = start_next - curr_end;
if free_size < len && is_within_rts_range(curr_end, len) {
cursor.move_next();
return Ok((curr_end, cursor));
}
}
cursor.move_next();
cursor_next = cursor.peek_next();
}

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

todo!()
if is_within_enclave(addr as *const u8, len) && is_within_rts_range(addr, len) {
cursor.move_next();
return Ok((addr, cursor));
}

// Cursor moves to emas->front_mut.
// Firstly cursor moves to None, then moves to linkedlist head
cursor.move_next();
cursor.move_next();

// Back to the first ema to check rts region before user region
let start_first = cursor.get().map(|ema| ema.start()).unwrap();
if start_first < len {
return Err(SgxStatus::InvalidParameter);
}

addr = trim_to!(start_first, align);

if is_within_enclave(addr as *const u8, len) && is_within_rts_range(addr, len) {
return Ok((addr, cursor));
}

Err(SgxStatus::InvalidParameter)
}
}

Expand Down
Loading

0 comments on commit 2897ceb

Please sign in to comment.