Use Intel SGX SDK reserved memory as the user space memory
This commit is contained in:
		
							parent
							
								
									cfbab68a9d
								
							
						
					
					
						commit
						f020fed2ae
					
				| @ -82,10 +82,6 @@ CXX_FLAGS := $(SGX_CXXFLAGS_T) $(C_COMMON_FLAGS) | |||||||
| ifdef OCCLUM_BUILTIN_CONF_FILE_MAC | ifdef OCCLUM_BUILTIN_CONF_FILE_MAC | ||||||
| C_FLAGS += -DOCCLUM_BUILTIN_CONF_FILE_MAC='"$(OCCLUM_BUILTIN_CONF_FILE_MAC)"' | C_FLAGS += -DOCCLUM_BUILTIN_CONF_FILE_MAC='"$(OCCLUM_BUILTIN_CONF_FILE_MAC)"' | ||||||
| endif | endif | ||||||
| # The total size of user-space memory must be builtin into the binary
 |  | ||||||
| ifdef OCCLUM_BUILTIN_VM_USER_SPACE_SIZE |  | ||||||
| C_FLAGS += -DOCCLUM_BUILTIN_VM_USER_SPACE_SIZE='($(OCCLUM_BUILTIN_VM_USER_SPACE_SIZE))' |  | ||||||
| endif |  | ||||||
| 
 | 
 | ||||||
| _Other_Link_Flags := -L$(RUST_SGX_SDK_DIR)/compiler-rt/ -L$(BUILD_DIR)/lib | _Other_Link_Flags := -L$(RUST_SGX_SDK_DIR)/compiler-rt/ -L$(BUILD_DIR)/lib | ||||||
| _Other_Enclave_Libs := -locclum-libos-core -lsgx_tprotected_fs | _Other_Enclave_Libs := -locclum-libos-core -lsgx_tprotected_fs | ||||||
|  | |||||||
| @ -1,17 +0,0 @@ | |||||||
| #include <stddef.h> |  | ||||||
| 
 |  | ||||||
| // The total size of the memory available to user programs
 |  | ||||||
| // Should be provided by Makefile
 |  | ||||||
| #ifndef OCCLUM_BUILTIN_VM_USER_SPACE_SIZE |  | ||||||
| #define OCCLUM_BUILTIN_VM_USER_SPACE_SIZE      (128*1024*1024) |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| static char __preallocated_memory[OCCLUM_BUILTIN_VM_USER_SPACE_SIZE] |  | ||||||
|     __attribute__ (( |  | ||||||
|         section(".executable_data,\"awx\",@nobits#"), |  | ||||||
|         aligned(4096))) = {0}; |  | ||||||
| 
 |  | ||||||
| void vm_get_preallocated_user_space_memory(void** paddr, size_t* psize) { |  | ||||||
|     *paddr = __preallocated_memory; |  | ||||||
|     *psize = sizeof(__preallocated_memory); |  | ||||||
| } |  | ||||||
| @ -1,71 +1,109 @@ | |||||||
| use super::*; | use super::*; | ||||||
|  | use config::LIBOS_CONFIG; | ||||||
| 
 | 
 | ||||||
| /// The virtual memory manager for the entire user space
 | /// The virtual memory manager for the entire user space
 | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct UserSpaceVMManager { | pub struct UserSpaceVMManager { | ||||||
|     vm_manager: Arc<SgxMutex<VMManager>>, |     total_size: usize, | ||||||
|  |     free_size: SgxMutex<usize>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl UserSpaceVMManager { | impl UserSpaceVMManager { | ||||||
|     pub unsafe fn from(addr: usize, size: usize) -> Result<UserSpaceVMManager> { |     fn new() -> UserSpaceVMManager { | ||||||
|         let vm_manager = Arc::new(SgxMutex::new(VMManager::from(addr, size)?)); |         let rsrv_mem_size = LIBOS_CONFIG.resource_limits.user_space_size; | ||||||
|         Ok(UserSpaceVMManager { vm_manager }) |         UserSpaceVMManager { | ||||||
|  |             total_size: rsrv_mem_size, | ||||||
|  |             free_size: SgxMutex::new(rsrv_mem_size), | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn alloc(&self, size: usize) -> Result<UserSpaceVMRange> { |     pub fn alloc(&self, size: usize) -> Result<UserSpaceVMRange> { | ||||||
|         let user_vm_range = unsafe { |         let vm_range = unsafe { | ||||||
|             let mmap_options = VMMapOptionsBuilder::default().size(size).build()?; |             let ptr = sgx_alloc_rsrv_mem(size); | ||||||
|  |             let perm = MemPerm::READ | MemPerm::WRITE | MemPerm::EXEC; | ||||||
|  |             if ptr.is_null() { | ||||||
|  |                 return_errno!(ENOMEM, "run out of reserved memory"); | ||||||
|  |             } | ||||||
|  |             // Change the page permission to RWX
 | ||||||
|  |             assert!(sgx_tprotect_rsrv_mem(ptr, size, perm.bits()) == sgx_status_t::SGX_SUCCESS); | ||||||
| 
 | 
 | ||||||
|             let mut vm_manager = self.vm_manager.lock().unwrap(); |             let addr = ptr as usize; | ||||||
|             let user_vm_addr = vm_manager.mmap(&mmap_options)?; |             debug!("allocated rsrv addr is 0x{:x}, len is 0x{:x}", addr, size); | ||||||
|             VMRange::from_unchecked(user_vm_addr, user_vm_addr + size) |             VMRange::from_unchecked(addr, addr + size) | ||||||
|         }; |         }; | ||||||
|         Ok(UserSpaceVMRange::new( | 
 | ||||||
|             user_vm_range, |         *self.free_size.lock().unwrap() -= size; | ||||||
|             self.vm_manager.clone(), |         Ok(UserSpaceVMRange::new(vm_range)) | ||||||
|         )) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     fn add_free_size(&self, user_space_vmrange: &UserSpaceVMRange) { | ||||||
|  |         *self.free_size.lock().unwrap() += user_space_vmrange.range().size(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // The empty range is not added to sub_range
 | ||||||
|     pub fn alloc_dummy(&self) -> UserSpaceVMRange { |     pub fn alloc_dummy(&self) -> UserSpaceVMRange { | ||||||
|         let empty_user_vm_range = unsafe { VMRange::from_unchecked(0, 0) }; |         let empty_user_vm_range = unsafe { VMRange::from_unchecked(0, 0) }; | ||||||
|         UserSpaceVMRange::new(empty_user_vm_range, self.vm_manager.clone()) |         UserSpaceVMRange::new(empty_user_vm_range) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn get_total_size(&self) -> usize { | ||||||
|  |         self.total_size | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn get_free_size(&self) -> usize { | ||||||
|  |         *self.free_size.lock().unwrap() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| lazy_static! { | lazy_static! { | ||||||
|     pub static ref USER_SPACE_VM_MANAGER: UserSpaceVMManager = { |     pub static ref USER_SPACE_VM_MANAGER: UserSpaceVMManager = UserSpaceVMManager::new(); | ||||||
|         let (addr, size) = { | } | ||||||
|             let mut addr: usize = 0; | 
 | ||||||
|             let mut size: usize = 0; | bitflags! { | ||||||
|             unsafe { vm_get_preallocated_user_space_memory(&mut addr, &mut size) }; |     struct MemPerm: i32 { | ||||||
|             (addr, size) |         const READ  = 1; | ||||||
|         }; |         const WRITE = 2; | ||||||
|         let user_space_vm_manager = unsafe { |         const EXEC  = 4; | ||||||
|             match UserSpaceVMManager::from(addr, size) { |  | ||||||
|                 Ok(user_space_vm) => user_space_vm, |  | ||||||
|                 Err(_) => panic!("Failed to initialize the user space virtual memory"), |  | ||||||
|     } |     } | ||||||
|         }; |  | ||||||
|         user_space_vm_manager |  | ||||||
|     }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| extern "C" { | extern "C" { | ||||||
|     pub fn vm_get_preallocated_user_space_memory(addr: &mut usize, size: &mut usize); |     // Allocate a range of EPC memory from the reserved memory area with RW permission
 | ||||||
|  |     //
 | ||||||
|  |     // Parameters:
 | ||||||
|  |     // Inputs: length [in]: Size of region to be allocated in bytes. Page aligned
 | ||||||
|  |     // Return: Starting address of the new allocated memory area on success; otherwise NULL
 | ||||||
|  |     //
 | ||||||
|  |     fn sgx_alloc_rsrv_mem(length: usize) -> *const c_void; | ||||||
|  | 
 | ||||||
|  |     // Free a range of EPC memory from the reserved memory area
 | ||||||
|  |     //
 | ||||||
|  |     // Parameters:
 | ||||||
|  |     // Inputs: addr[in]: Starting address of region to be freed. Page aligned.
 | ||||||
|  |     //         length[in]: The length of the memory to be freed in bytes.  Page aligned
 | ||||||
|  |     // Return: 0 on success; otherwise -1
 | ||||||
|  |     //
 | ||||||
|  |     fn sgx_free_rsrv_mem(addr: *const c_void, length: usize) -> i32; | ||||||
|  | 
 | ||||||
|  |     // Modify the access permissions of the pages in the reserved memory area
 | ||||||
|  |     //
 | ||||||
|  |     // Parameters:
 | ||||||
|  |     // Inputs: addr[in]: Starting address of region which needs to change access
 | ||||||
|  |     //         permission. Page aligned.
 | ||||||
|  |     //         length[in]: The length of the memory to be manipulated in bytes. Page aligned.
 | ||||||
|  |     //         prot[in]: The target memory protection.
 | ||||||
|  |     // Return: sgx_status_t
 | ||||||
|  |     //
 | ||||||
|  |     fn sgx_tprotect_rsrv_mem(addr: *const c_void, length: usize, prot: i32) -> sgx_status_t; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct UserSpaceVMRange { | pub struct UserSpaceVMRange { | ||||||
|     vm_range: VMRange, |     vm_range: VMRange, | ||||||
|     vm_manager: Arc<SgxMutex<VMManager>>, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl UserSpaceVMRange { | impl UserSpaceVMRange { | ||||||
|     fn new(vm_range: VMRange, vm_manager: Arc<SgxMutex<VMManager>>) -> UserSpaceVMRange { |     fn new(vm_range: VMRange) -> UserSpaceVMRange { | ||||||
|         UserSpaceVMRange { |         UserSpaceVMRange { vm_range } | ||||||
|             vm_range, |  | ||||||
|             vm_manager, |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn range(&self) -> &VMRange { |     pub fn range(&self) -> &VMRange { | ||||||
| @ -75,14 +113,14 @@ impl UserSpaceVMRange { | |||||||
| 
 | 
 | ||||||
| impl Drop for UserSpaceVMRange { | impl Drop for UserSpaceVMRange { | ||||||
|     fn drop(&mut self) { |     fn drop(&mut self) { | ||||||
|         let addr = self.vm_range.start(); |         let addr = self.vm_range.start() as *const c_void; | ||||||
|         let size = self.vm_range.size(); |         let size = self.vm_range.size(); | ||||||
|         if size == 0 { |         if size == 0 { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         let mut vm_manager = self.vm_manager.lock().unwrap(); | 
 | ||||||
|         vm_manager |         USER_SPACE_VM_MANAGER.add_free_size(self); | ||||||
|             .munmap(addr, size) | 
 | ||||||
|             .expect("munmap should always succeed"); |         assert!(unsafe { sgx_free_rsrv_mem(addr, size) == 0 }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -84,6 +84,16 @@ fn main() { | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // get the user space size
 | ||||||
|  |     let user_space_size = parse_memory_size(&occlum_config.resource_limits.user_space_size); | ||||||
|  |     if user_space_size.is_err() { | ||||||
|  |         println!( | ||||||
|  |             "The user_space_size \"{}\" is not correct.", | ||||||
|  |             occlum_config.resource_limits.user_space_size | ||||||
|  |         ); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     let sgx_enclave_configuration = EnclaveConfiguration { |     let sgx_enclave_configuration = EnclaveConfiguration { | ||||||
|         ProdID: occlum_config.metadata.product_id, |         ProdID: occlum_config.metadata.product_id, | ||||||
|         ISVSVN: occlum_config.metadata.version_number, |         ISVSVN: occlum_config.metadata.version_number, | ||||||
| @ -97,6 +107,10 @@ fn main() { | |||||||
|         }, |         }, | ||||||
|         MiscSelect: "0".to_string(), |         MiscSelect: "0".to_string(), | ||||||
|         MiscMask: "0xFFFFFFFF".to_string(), |         MiscMask: "0xFFFFFFFF".to_string(), | ||||||
|  |         ReservedMemMaxSize: user_space_size.unwrap() as u64, | ||||||
|  |         ReservedMemMinSize: user_space_size.unwrap() as u64, | ||||||
|  |         ReservedMemInitSize: user_space_size.unwrap() as u64, | ||||||
|  |         ReservedMemExecutable: 1, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // Generate the enclave configuration
 |     // Generate the enclave configuration
 | ||||||
| @ -175,4 +189,8 @@ struct EnclaveConfiguration { | |||||||
|     DisableDebug: u32, |     DisableDebug: u32, | ||||||
|     MiscSelect: String, |     MiscSelect: String, | ||||||
|     MiscMask: String, |     MiscMask: String, | ||||||
|  |     ReservedMemMaxSize: u64, | ||||||
|  |     ReservedMemMinSize: u64, | ||||||
|  |     ReservedMemInitSize: u64, | ||||||
|  |     ReservedMemExecutable: u32, | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user