Format all Rust code with cargo fmt
				
					
				
			In addition, to ensure that all future Rust code complies with `cargo fmt`, we add a Git post-commit hook that generates warnings if the commited code is not formated consistently.
This commit is contained in:
		
							parent
							
								
									dff0dbf77d
								
							
						
					
					
						commit
						7001b32a4a
					
				| @ -1,7 +1,7 @@ | ||||
| use super::*; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use std::sgxfs::{SgxFile}; | ||||
| use std::path::{Path, PathBuf}; | ||||
| use std::sgxfs::SgxFile; | ||||
| 
 | ||||
| const LIBOS_CONFIG_PATH: &str = "Occlum.json.protected"; | ||||
| 
 | ||||
| @ -9,42 +9,53 @@ lazy_static! { | ||||
|     pub static ref LIBOS_CONFIG: Config = { | ||||
|         let mut config_file = { | ||||
|             let config_file = match SgxFile::open_integrity_only(LIBOS_CONFIG_PATH) { | ||||
|                 Err(_) => panic!("Failed to find or open Occlum's config file: {}", | ||||
|                             LIBOS_CONFIG_PATH), | ||||
|                 Err(_) => panic!( | ||||
|                     "Failed to find or open Occlum's config file: {}", | ||||
|                     LIBOS_CONFIG_PATH | ||||
|                 ), | ||||
|                 Ok(file) => file, | ||||
|             }; | ||||
| 
 | ||||
|             let actual_mac = match config_file.get_mac() { | ||||
|                 Err(_) => panic!("Failed to get the MAC of Occlum's config file: {}", | ||||
|                             LIBOS_CONFIG_PATH), | ||||
|                 Err(_) => panic!( | ||||
|                     "Failed to get the MAC of Occlum's config file: {}", | ||||
|                     LIBOS_CONFIG_PATH | ||||
|                 ), | ||||
|                 Ok(mac) => mac, | ||||
|             }; | ||||
|             let expected_mac = conf_get_hardcoded_file_mac(); | ||||
|             if actual_mac != expected_mac { | ||||
|                 panic!("The MAC of Occlum's config file is not as expected: {}", | ||||
|                         LIBOS_CONFIG_PATH); | ||||
|                 panic!( | ||||
|                     "The MAC of Occlum's config file is not as expected: {}", | ||||
|                     LIBOS_CONFIG_PATH | ||||
|                 ); | ||||
|             } | ||||
| 
 | ||||
|             config_file | ||||
|         }; | ||||
|         let config_json = { | ||||
|             let mut config_json = String::new(); | ||||
|             config_file.read_to_string(&mut config_json) | ||||
|                 .map_err(|_| { | ||||
|                     panic!("Failed to read from Occlum's config file: {}", | ||||
|                         LIBOS_CONFIG_PATH); | ||||
|             config_file.read_to_string(&mut config_json).map_err(|_| { | ||||
|                 panic!( | ||||
|                     "Failed to read from Occlum's config file: {}", | ||||
|                     LIBOS_CONFIG_PATH | ||||
|                 ); | ||||
|             }); | ||||
|             config_json | ||||
|         }; | ||||
|         let config_input: InputConfig = match serde_json::from_str(&config_json) { | ||||
|             Err(_) => panic!("Failed to parse JSON from Occlum's config file: {}", | ||||
|                         LIBOS_CONFIG_PATH), | ||||
|             Ok(config_input) => config_input | ||||
|             Err(_) => panic!( | ||||
|                 "Failed to parse JSON from Occlum's config file: {}", | ||||
|                 LIBOS_CONFIG_PATH | ||||
|             ), | ||||
|             Ok(config_input) => config_input, | ||||
|         }; | ||||
|         let config = match Config::from_input(&config_input) { | ||||
|             Err(_) => panic!("Found invalid config in Occlum's config file: {}", | ||||
|                         LIBOS_CONFIG_PATH), | ||||
|             Ok(config) => config | ||||
|             Err(_) => panic!( | ||||
|                 "Found invalid config in Occlum's config file: {}", | ||||
|                 LIBOS_CONFIG_PATH | ||||
|             ), | ||||
|             Ok(config) => config, | ||||
|         }; | ||||
|         config | ||||
|     }; | ||||
| @ -61,8 +72,7 @@ fn conf_get_hardcoded_file_mac() -> sgx_aes_gcm_128bit_tag_t { | ||||
|             .to_str() | ||||
|             .expect("Invalid MAC") | ||||
|     }; | ||||
|     let mac = parse_mac(mac_str) | ||||
|         .expect("Invalid MAC"); | ||||
|     let mac = parse_mac(mac_str).expect("Invalid MAC"); | ||||
|     mac | ||||
| } | ||||
| 
 | ||||
| @ -82,7 +92,6 @@ fn parse_mac(mac_str: &str) -> Result<sgx_aes_gcm_128bit_tag_t, Error> { | ||||
|     Ok(mac) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Config { | ||||
|     pub vm: ConfigVM, | ||||
| @ -124,7 +133,6 @@ pub struct ConfigMountOptions { | ||||
|     pub mac: Option<sgx_aes_gcm_128bit_tag_t>, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| impl Config { | ||||
|     fn from_input(input: &InputConfig) -> Result<Config, Error> { | ||||
|         let vm = ConfigVM::from_input(&input.vm)?; | ||||
| @ -181,14 +189,18 @@ impl ConfigMount { | ||||
|         }; | ||||
|         let source = input.source.as_ref().map(|s| PathBuf::from(s)); | ||||
|         let options = ConfigMountOptions::from_input(&input.options)?; | ||||
|         Ok(ConfigMount { type_, target, source, options, }) | ||||
|         Ok(ConfigMount { | ||||
|             type_, | ||||
|             target, | ||||
|             source, | ||||
|             options, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ConfigMountOptions { | ||||
|     fn from_input(input: &InputConfigMountOptions) -> Result<ConfigMountOptions, Error> { | ||||
|         let (integrity_only, mac) = | ||||
|             if !input.integrity_only { | ||||
|         let (integrity_only, mac) = if !input.integrity_only { | ||||
|             (false, None) | ||||
|         } else { | ||||
|             if input.mac.is_none() { | ||||
| @ -196,11 +208,13 @@ impl ConfigMountOptions { | ||||
|             } | ||||
|             (true, Some(parse_mac(&input.mac.as_ref().unwrap())?)) | ||||
|         }; | ||||
|         Ok(ConfigMountOptions { integrity_only, mac }) | ||||
|         Ok(ConfigMountOptions { | ||||
|             integrity_only, | ||||
|             mac, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| fn parse_memory_size(mem_str: &str) -> Result<usize, Error> { | ||||
|     const UNIT2FACTOR: [(&str, usize); 5] = [ | ||||
|         ("KB", 1024), | ||||
| @ -216,18 +230,16 @@ fn parse_memory_size(mem_str: &str) -> Result<usize, Error> { | ||||
|         .position(|(unit, _)| mem_str.ends_with(unit)) | ||||
|         .ok_or_else(|| Error::new(Errno::EINVAL, "No unit")) | ||||
|         .map(|unit_i| &UNIT2FACTOR[unit_i])?; | ||||
|     let number = | ||||
|         match mem_str[0..mem_str.len() - unit.len()] | ||||
|     let number = match mem_str[0..mem_str.len() - unit.len()] | ||||
|         .trim() | ||||
|         .parse::<usize>() | ||||
|     { | ||||
|         Err(_) => return errno!(EINVAL, "No number"), | ||||
|             Ok(number) => number | ||||
|         Ok(number) => number, | ||||
|     }; | ||||
|     Ok(number * factor) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Deserialize, Debug)] | ||||
| #[serde(deny_unknown_fields)] | ||||
| struct InputConfig { | ||||
| @ -255,7 +267,7 @@ impl InputConfigVM { | ||||
| impl Default for InputConfigVM { | ||||
|     fn default() -> InputConfigVM { | ||||
|         InputConfigVM { | ||||
|             user_space_size: InputConfigVM::get_user_space_size() | ||||
|             user_space_size: InputConfigVM::get_user_space_size(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -81,9 +81,7 @@ fn do_boot(path_str: &str, argv: &Vec<CString>) -> Result<(), Error> { | ||||
|     util::mpx_util::mpx_enable()?; | ||||
| 
 | ||||
|     // The default environment variables
 | ||||
|     let envp = vec![ | ||||
|         CString::new("OCCLUM=yes").unwrap() | ||||
|     ]; | ||||
|     let envp = vec![CString::new("OCCLUM=yes").unwrap()]; | ||||
|     let file_actions = Vec::new(); | ||||
|     let parent = &process::IDLE_PROCESS; | ||||
|     process::do_spawn(&path_str, argv, &envp, &file_actions, parent)?; | ||||
|  | ||||
| @ -31,9 +31,8 @@ impl File for DevRandom { | ||||
|                 } | ||||
|                 Err(e) => { | ||||
|                     if total_nbytes > 0 { | ||||
|                         break
 | ||||
|                     } | ||||
|                     else { | ||||
|                         break; | ||||
|                     } else { | ||||
|                         return Err(e); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @ -7,32 +7,32 @@ use {process, std}; | ||||
| use super::*; | ||||
| 
 | ||||
| pub use self::access::{do_access, do_faccessat, AccessFlags, AccessModes, AT_FDCWD}; | ||||
| use self::dev_null::DevNull; | ||||
| use self::dev_random::DevRandom; | ||||
| use self::dev_zero::DevZero; | ||||
| pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile}; | ||||
| pub use self::file_table::{FileDesc, FileTable}; | ||||
| use self::inode_file::OpenOptions; | ||||
| pub use self::inode_file::{INodeExt, INodeFile}; | ||||
| pub use self::root_inode::{ROOT_INODE}; | ||||
| pub use self::io_multiplexing::*; | ||||
| use self::dev_null::DevNull; | ||||
| use self::dev_zero::DevZero; | ||||
| use self::dev_random::DevRandom; | ||||
| pub use self::pipe::Pipe; | ||||
| pub use self::root_inode::ROOT_INODE; | ||||
| pub use self::socket_file::{AsSocket, SocketFile}; | ||||
| pub use self::unix_socket::{AsUnixSocket, UnixSocketFile}; | ||||
| use std::any::Any; | ||||
| use std::mem::uninitialized; | ||||
| 
 | ||||
| mod access; | ||||
| mod dev_null; | ||||
| mod dev_random; | ||||
| mod dev_zero; | ||||
| mod file; | ||||
| mod file_table; | ||||
| mod hostfs; | ||||
| mod inode_file; | ||||
| mod root_inode; | ||||
| mod io_multiplexing; | ||||
| mod dev_null; | ||||
| mod dev_zero; | ||||
| mod dev_random; | ||||
| mod pipe; | ||||
| mod root_inode; | ||||
| mod sgx_impl; | ||||
| mod socket_file; | ||||
| mod unix_socket; | ||||
|  | ||||
| @ -1,14 +1,14 @@ | ||||
| use super::*; | ||||
| use super::hostfs::HostFS; | ||||
| use super::sgx_impl::SgxStorage; | ||||
| use super::*; | ||||
| use config::{ConfigMount, ConfigMountFsType}; | ||||
| use std::path::{Path, PathBuf}; | ||||
| 
 | ||||
| use rcore_fs::vfs::{FileSystem, FileType, FsError, INode}; | ||||
| use rcore_fs_sefs::SEFS; | ||||
| use rcore_fs_sefs::dev::*; | ||||
| use rcore_fs_mountfs::{MountFS, MNode}; | ||||
| use rcore_fs_mountfs::{MNode, MountFS}; | ||||
| use rcore_fs_ramfs::RamFS; | ||||
| use rcore_fs_sefs::dev::*; | ||||
| use rcore_fs_sefs::SEFS; | ||||
| 
 | ||||
| lazy_static! { | ||||
|     /// The root of file system
 | ||||
| @ -26,9 +26,9 @@ lazy_static! { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| fn open_or_create_root_fs_according_to(mount_config: &Vec<ConfigMount>) | ||||
|     -> Result<Arc<MountFS>, Error> | ||||
| { | ||||
| fn open_or_create_root_fs_according_to( | ||||
|     mount_config: &Vec<ConfigMount>, | ||||
| ) -> Result<Arc<MountFS>, Error> { | ||||
|     let root_sefs_source = { | ||||
|         let root_mount_config = mount_config | ||||
|             .iter() | ||||
| @ -39,29 +39,40 @@ fn open_or_create_root_fs_according_to(mount_config: &Vec<ConfigMount>) | ||||
|             return errno!(EINVAL, "The mount point at / must be SEFS"); | ||||
|         } | ||||
|         if root_mount_config.options.integrity_only { | ||||
|             return errno!(EINVAL, "The root SEFS at / must be encrypted (i.e., integrity-only is not enough)"); | ||||
|             return errno!( | ||||
|                 EINVAL, | ||||
|                 "The root SEFS at / must be encrypted (i.e., integrity-only is not enough)" | ||||
|             ); | ||||
|         } | ||||
|         if root_mount_config.source.is_none() { | ||||
|             return errno!(EINVAL, "The root SEFS must be given a source path (on host)"); | ||||
|             return errno!( | ||||
|                 EINVAL, | ||||
|                 "The root SEFS must be given a source path (on host)" | ||||
|             ); | ||||
|         } | ||||
|         root_mount_config.source.as_ref().unwrap() | ||||
|     }; | ||||
| 
 | ||||
|     let root_sefs = { | ||||
|         SEFS::open(Box::new(SgxStorage::new(root_sefs_source, false)), | ||||
|             &time::OcclumTimeProvider) | ||||
|         SEFS::open( | ||||
|             Box::new(SgxStorage::new(root_sefs_source, false)), | ||||
|             &time::OcclumTimeProvider, | ||||
|         ) | ||||
|     } | ||||
|     .or_else(|_| { | ||||
|         SEFS::create(Box::new(SgxStorage::new(root_sefs_source, false)), | ||||
|             &time::OcclumTimeProvider) | ||||
|         SEFS::create( | ||||
|             Box::new(SgxStorage::new(root_sefs_source, false)), | ||||
|             &time::OcclumTimeProvider, | ||||
|         ) | ||||
|     })?; | ||||
|     let root_mountable_sefs = MountFS::new(root_sefs); | ||||
|     Ok(root_mountable_sefs) | ||||
| } | ||||
| 
 | ||||
| fn mount_nonroot_fs_according_to(mount_config: &Vec<ConfigMount>, root: &MNode) | ||||
|     -> Result<(), Error> | ||||
| { | ||||
| fn mount_nonroot_fs_according_to( | ||||
|     mount_config: &Vec<ConfigMount>, | ||||
|     root: &MNode, | ||||
| ) -> Result<(), Error> { | ||||
|     for mc in mount_config { | ||||
|         if mc.target == Path::new("/") { | ||||
|             continue; | ||||
| @ -79,10 +90,13 @@ fn mount_nonroot_fs_according_to(mount_config: &Vec<ConfigMount>, root: &MNode) | ||||
|         match mc.type_ { | ||||
|             TYPE_SEFS => { | ||||
|                 if !mc.options.integrity_only { | ||||
|                     return errno!(EINVAL, "Must be integrity-only SEFS") | ||||
|                     return errno!(EINVAL, "Must be integrity-only SEFS"); | ||||
|                 } | ||||
|                 if mc.source.is_none() { | ||||
|                     return errno!(EINVAL, "Source is expected for integrity-only SEFS is supported") | ||||
|                     return errno!( | ||||
|                         EINVAL, | ||||
|                         "Source is expected for integrity-only SEFS is supported" | ||||
|                     ); | ||||
|                 } | ||||
|                 let source_path = mc.source.as_ref().unwrap(); | ||||
| 
 | ||||
| @ -93,28 +107,26 @@ fn mount_nonroot_fs_according_to(mount_config: &Vec<ConfigMount>, root: &MNode) | ||||
|                 }; | ||||
|                 let sefs = SEFS::open(device, &time::OcclumTimeProvider)?; | ||||
|                 mount_fs_at(sefs, &root, target_dirname)?; | ||||
|             }, | ||||
|             } | ||||
|             TYPE_HOSTFS => { | ||||
|                 if mc.source.is_none() { | ||||
|                     return errno!(EINVAL, "Source is expected for HostFS") | ||||
|                     return errno!(EINVAL, "Source is expected for HostFS"); | ||||
|                 } | ||||
|                 let source_path = mc.source.as_ref().unwrap(); | ||||
| 
 | ||||
|                 let hostfs = HostFS::new(source_path); | ||||
|                 mount_fs_at(hostfs, &root, target_dirname)?; | ||||
|             }, | ||||
|             } | ||||
|             TYPE_RAMFS => { | ||||
|                 let ramfs = RamFS::new(); | ||||
|                 mount_fs_at(ramfs, &root, target_dirname)?; | ||||
|             }, | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| fn mount_fs_at(fs: Arc<dyn FileSystem>, parent_inode: &MNode, dirname: &str) | ||||
|     -> Result<(), Error> | ||||
| { | ||||
| fn mount_fs_at(fs: Arc<dyn FileSystem>, parent_inode: &MNode, dirname: &str) -> Result<(), Error> { | ||||
|     let mount_dir = match parent_inode.find(false, dirname) { | ||||
|         Ok(existing_dir) => { | ||||
|             if existing_dir.metadata()?.type_ != FileType::Dir { | ||||
| @ -122,9 +134,7 @@ fn mount_fs_at(fs: Arc<dyn FileSystem>, parent_inode: &MNode, dirname: &str) | ||||
|             } | ||||
|             existing_dir | ||||
|         } | ||||
|         Err(_) => { | ||||
|             parent_inode.create(dirname, FileType::Dir, 0o777)? | ||||
|         } | ||||
|         Err(_) => parent_inode.create(dirname, FileType::Dir, 0o777)?, | ||||
|     }; | ||||
|     mount_dir.mount(fs); | ||||
|     Ok(()) | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| use super::{sgx_aes_gcm_128bit_tag_t}; | ||||
| use super::sgx_aes_gcm_128bit_tag_t; | ||||
| use rcore_fs::dev::TimeProvider; | ||||
| use rcore_fs::vfs::Timespec; | ||||
| use rcore_fs_sefs::dev::*; | ||||
| @ -31,7 +31,11 @@ impl SgxStorage { | ||||
|     /// It lookups cache first, if miss, then call `open_fn` to open one,
 | ||||
|     /// and add it to cache before return.
 | ||||
|     #[cfg(feature = "sgx_file_cache")] | ||||
|     fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>) -> DevResult<LockedFile> { | ||||
|     fn get( | ||||
|         &self, | ||||
|         file_id: usize, | ||||
|         open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>, | ||||
|     ) -> DevResult<LockedFile> { | ||||
|         // query cache
 | ||||
|         let mut caches = self.file_cache.lock().unwrap(); | ||||
|         if let Some(locked_file) = caches.get(&file_id) { | ||||
| @ -46,7 +50,11 @@ impl SgxStorage { | ||||
|     } | ||||
|     /// Get file by `file_id` without cache.
 | ||||
|     #[cfg(not(feature = "sgx_file_cache"))] | ||||
|     fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>) -> LockedFile { | ||||
|     fn get( | ||||
|         &self, | ||||
|         file_id: usize, | ||||
|         open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>, | ||||
|     ) -> LockedFile { | ||||
|         open_fn(self) | ||||
|     } | ||||
| 
 | ||||
| @ -84,11 +92,13 @@ impl Storage for SgxStorage { | ||||
| 
 | ||||
|             // Check the MAC of the root file against the given root MAC of the storage
 | ||||
|             if file_id == 0 && self.root_mac.is_some() { | ||||
|                 let root_file_mac = file.get_mac() | ||||
|                     .expect("Failed to get mac"); | ||||
|                 let root_file_mac = file.get_mac().expect("Failed to get mac"); | ||||
|                 if root_file_mac != self.root_mac.unwrap() { | ||||
|                     println!("Expected MAC = {:#?}, actual MAC = {:?}", | ||||
|                         self.root_mac.unwrap(), root_file_mac); | ||||
|                     println!( | ||||
|                         "Expected MAC = {:#?}, actual MAC = {:?}", | ||||
|                         self.root_mac.unwrap(), | ||||
|                         root_file_mac | ||||
|                     ); | ||||
|                     return Err(DeviceError); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -23,9 +23,9 @@ extern crate lazy_static; | ||||
| #[macro_use] | ||||
| extern crate log; | ||||
| extern crate rcore_fs; | ||||
| extern crate rcore_fs_sefs; | ||||
| extern crate rcore_fs_ramfs; | ||||
| extern crate rcore_fs_mountfs; | ||||
| extern crate rcore_fs_ramfs; | ||||
| extern crate rcore_fs_sefs; | ||||
| #[macro_use] | ||||
| extern crate derive_builder; | ||||
| extern crate serde; | ||||
| @ -39,9 +39,9 @@ use std::panic; | ||||
| 
 | ||||
| #[macro_use] | ||||
| mod prelude; | ||||
| mod errno; | ||||
| mod entry; | ||||
| mod config; | ||||
| mod entry; | ||||
| mod errno; | ||||
| mod fs; | ||||
| mod misc; | ||||
| mod process; | ||||
|  | ||||
| @ -3,11 +3,11 @@ pub use self::exit::{do_exit, do_wait4, ChildProcessFilter}; | ||||
| pub use self::futex::{futex_op_and_flags_from_u32, futex_wait, futex_wake, FutexFlags, FutexOp}; | ||||
| pub use self::process::{Status, IDLE_PROCESS}; | ||||
| pub use self::process_table::get; | ||||
| pub use self::sched::{do_sched_getaffinity, do_sched_setaffinity, CpuSet}; | ||||
| pub use self::spawn::{do_spawn, FileAction}; | ||||
| pub use self::task::{current_pid, get_current, run_task}; | ||||
| pub use self::thread::{do_clone, do_set_tid_address, CloneFlags, ThreadGroup}; | ||||
| pub use self::wait::{WaitQueue, Waiter}; | ||||
| pub use self::sched::{CpuSet, do_sched_getaffinity, do_sched_setaffinity}; | ||||
| 
 | ||||
| #[allow(non_camel_case_types)] | ||||
| pub type pid_t = u32; | ||||
| @ -71,14 +71,14 @@ mod exit; | ||||
| mod futex; | ||||
| mod process; | ||||
| mod process_table; | ||||
| mod sched; | ||||
| mod spawn; | ||||
| mod task; | ||||
| mod thread; | ||||
| mod wait; | ||||
| mod sched; | ||||
| 
 | ||||
| use self::task::Task; | ||||
| use super::*; | ||||
| use fs::{File, FileRef, FileTable}; | ||||
| use misc::ResourceLimitsRef; | ||||
| use vm::{ProcessVM}; | ||||
| use vm::ProcessVM; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use super::task::Task; | ||||
| use super::*; | ||||
| use fs::{File, FileRef, FileTable}; | ||||
| use vm::{ProcessVM}; | ||||
| use vm::ProcessVM; | ||||
| 
 | ||||
| lazy_static! { | ||||
|     // Dummy object to make all processes having a parent
 | ||||
|  | ||||
| @ -1,8 +1,20 @@ | ||||
| use super::*; | ||||
| 
 | ||||
| extern "C" { | ||||
|     fn ocall_sched_getaffinity(ret: *mut i32, errno: *mut i32, pid: i32, cpusetsize: size_t, mask: *mut c_uchar) -> sgx_status_t; | ||||
|     fn ocall_sched_setaffinity(ret: *mut i32, errno: *mut i32, pid: i32, cpusetsize: size_t, mask: *const c_uchar) -> sgx_status_t; | ||||
|     fn ocall_sched_getaffinity( | ||||
|         ret: *mut i32, | ||||
|         errno: *mut i32, | ||||
|         pid: i32, | ||||
|         cpusetsize: size_t, | ||||
|         mask: *mut c_uchar, | ||||
|     ) -> sgx_status_t; | ||||
|     fn ocall_sched_setaffinity( | ||||
|         ret: *mut i32, | ||||
|         errno: *mut i32, | ||||
|         pid: i32, | ||||
|         cpusetsize: size_t, | ||||
|         mask: *const c_uchar, | ||||
|     ) -> sgx_status_t; | ||||
| } | ||||
| 
 | ||||
| pub struct CpuSet { | ||||
| @ -11,13 +23,17 @@ pub struct CpuSet { | ||||
| 
 | ||||
| impl CpuSet { | ||||
|     pub fn new(len: usize) -> CpuSet { | ||||
|         let mut cpuset = CpuSet { vec: Vec::with_capacity(len) }; | ||||
|         let mut cpuset = CpuSet { | ||||
|             vec: Vec::with_capacity(len), | ||||
|         }; | ||||
|         cpuset.vec.resize(len, 0); | ||||
|         cpuset | ||||
|     } | ||||
| 
 | ||||
|     pub fn from_raw_buf(ptr: *const u8, cpusize: usize) -> CpuSet { | ||||
|         let mut cpuset = CpuSet { vec: Vec::with_capacity(cpusize) }; | ||||
|         let mut cpuset = CpuSet { | ||||
|             vec: Vec::with_capacity(cpusize), | ||||
|         }; | ||||
|         let buf_slice = unsafe { std::slice::from_raw_parts(ptr, cpusize) }; | ||||
|         cpuset.vec.extend_from_slice(buf_slice); | ||||
|         cpuset | ||||
| @ -63,11 +79,7 @@ impl std::fmt::UpperHex for CpuSet { | ||||
| } | ||||
| 
 | ||||
| fn find_host_tid(pid: pid_t) -> Result<pid_t, Error> { | ||||
|     let process_ref = if pid == 0 { | ||||
|         get_current() | ||||
|     } else { | ||||
|         get(pid)? | ||||
|     }; | ||||
|     let process_ref = if pid == 0 { get_current() } else { get(pid)? }; | ||||
|     let mut process = process_ref.lock().unwrap(); | ||||
|     let host_tid = process.get_host_tid(); | ||||
|     Ok(host_tid) | ||||
|  | ||||
| @ -86,8 +86,7 @@ impl StackBuf { | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn put(&self, val: u64) -> Result<*const u64, Error> | ||||
|     { | ||||
|     pub fn put(&self, val: u64) -> Result<*const u64, Error> { | ||||
|         let val_ptr = self.alloc(8, 8)? as *mut u64; | ||||
|         unsafe { | ||||
|             ptr::write(val_ptr, val); | ||||
| @ -238,7 +237,8 @@ impl AuxTable { | ||||
|         if key == AuxKey::AT_NULL || key == AuxKey::AT_IGNORE { | ||||
|             return errno!(EINVAL, "Illegal key"); | ||||
|         } | ||||
|         self.table.entry(key) | ||||
|         self.table | ||||
|             .entry(key) | ||||
|             .and_modify(|val_mut| *val_mut = val) | ||||
|             .or_insert(val); | ||||
|         Ok(()) | ||||
|  | ||||
| @ -7,7 +7,7 @@ pub fn do_init( | ||||
|     elf_file: &ElfFile, | ||||
|     elf_buf: &[u8], | ||||
|     ldso_elf_file: &ElfFile, | ||||
|     ldso_elf_buf: &[u8] | ||||
|     ldso_elf_buf: &[u8], | ||||
| ) -> Result<ProcessVM, Error> { | ||||
|     // Alloc all virtual memory areas
 | ||||
|     let mut code_seg = get_code_segment(elf_file)?; | ||||
| @ -24,7 +24,10 @@ pub fn do_init( | ||||
|     let ldso_code_start = 0; | ||||
|     let ldso_code_end = align_down(ldso_data_seg.get_mem_addr(), ldso_data_seg.get_mem_align()); | ||||
|     let ldso_data_start = ldso_code_end; | ||||
|     let ldso_data_end = align_up(ldso_data_seg.get_mem_addr() + ldso_data_seg.get_mem_size(), 4096); | ||||
|     let ldso_data_end = align_up( | ||||
|         ldso_data_seg.get_mem_addr() + ldso_data_seg.get_mem_size(), | ||||
|         4096, | ||||
|     ); | ||||
|     let ldso_code_size = ldso_code_end - ldso_code_start; | ||||
|     let ldso_data_size = ldso_data_end - ldso_data_start; | ||||
| 
 | ||||
|  | ||||
| @ -64,8 +64,8 @@ pub fn do_spawn<P: AsRef<Path>>( | ||||
|     }; | ||||
| 
 | ||||
|     let ldso_elf_file = { | ||||
|         let ldso_elf_file = | ||||
|             ElfFile::new(&ldso_elf_buf).map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?; | ||||
|         let ldso_elf_file = ElfFile::new(&ldso_elf_buf) | ||||
|             .map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?; | ||||
|         header::sanity_check(&ldso_elf_file) | ||||
|             .map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?; | ||||
|         /* | ||||
| @ -78,15 +78,13 @@ pub fn do_spawn<P: AsRef<Path>>( | ||||
| 
 | ||||
|     let (new_pid, new_process_ref) = { | ||||
|         let cwd = parent_ref.lock().unwrap().get_cwd().to_owned(); | ||||
|         let vm = init_vm::do_init(&elf_file, &elf_buf[..], | ||||
|                                   &ldso_elf_file, &ldso_elf_buf[..])?; | ||||
|         let vm = init_vm::do_init(&elf_file, &elf_buf[..], &ldso_elf_file, &ldso_elf_buf[..])?; | ||||
|         let base_addr = vm.get_base_addr(); | ||||
|         let auxtbl = init_auxtbl(&vm, &elf_file)?; | ||||
|         let task = { | ||||
|             let ldso_entry = { | ||||
|                 let ldso_base_addr = vm.get_ldso_code_range().start(); | ||||
|                 let ldso_entry = ldso_base_addr + | ||||
|                     elf_helper::get_start_address(&ldso_elf_file)?; | ||||
|                 let ldso_entry = ldso_base_addr + elf_helper::get_start_address(&ldso_elf_file)?; | ||||
|                 if !vm.get_ldso_code_range().contains(ldso_entry) { | ||||
|                     return errno!(EINVAL, "Invalid program entry"); | ||||
|                 } | ||||
| @ -96,8 +94,13 @@ pub fn do_spawn<P: AsRef<Path>>( | ||||
|             let user_stack_limit = vm.get_stack_limit(); | ||||
|             let user_rsp = init_stack::do_init(user_stack_base, 4096, argv, envp, &auxtbl)?; | ||||
|             unsafe { | ||||
|                 Task::new(ldso_entry, user_rsp, | ||||
|                           user_stack_base, user_stack_limit, None)? | ||||
|                 Task::new( | ||||
|                     ldso_entry, | ||||
|                     user_rsp, | ||||
|                     user_stack_base, | ||||
|                     user_stack_limit, | ||||
|                     None, | ||||
|                 )? | ||||
|             } | ||||
|         }; | ||||
|         let vm_ref = Arc::new(SgxMutex::new(vm)); | ||||
| @ -167,10 +170,7 @@ fn init_files(parent_ref: &ProcessRef, file_actions: &[FileAction]) -> Result<Fi | ||||
|     Ok(file_table) | ||||
| } | ||||
| 
 | ||||
| fn init_auxtbl( | ||||
|     process_vm: &ProcessVM, | ||||
|     elf_file: &ElfFile, | ||||
| ) -> Result<AuxTable, Error> { | ||||
| fn init_auxtbl(process_vm: &ProcessVM, elf_file: &ElfFile) -> Result<AuxTable, Error> { | ||||
|     let mut auxtbl = AuxTable::new(); | ||||
|     auxtbl.set(AuxKey::AT_PAGESZ, 4096)?; | ||||
|     auxtbl.set(AuxKey::AT_UID, 0)?; | ||||
|  | ||||
| @ -40,7 +40,8 @@ impl Segment { | ||||
|             return Err(( | ||||
|                 Errno::EINVAL, | ||||
|                 "Memory address and file offset is not equal, per modulo", | ||||
|             ).into()); | ||||
|             ) | ||||
|                 .into()); | ||||
|         } | ||||
|         if ph64.mem_size < ph64.file_size { | ||||
|             return Err((Errno::EINVAL, "Memory size must be greater than file size").into()); | ||||
|  | ||||
| @ -52,7 +52,6 @@ impl Task { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| lazy_static! { | ||||
|     static ref NEW_PROCESS_QUEUE: SgxMutex<VecDeque<ProcessRef>> = | ||||
|         { SgxMutex::new(VecDeque::new()) }; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use super::vm::VMRange; | ||||
| use super::*; | ||||
| use super::vm::{VMRange}; | ||||
| 
 | ||||
| pub struct ThreadGroup { | ||||
|     threads: Vec<ProcessRef>, | ||||
| @ -64,9 +64,13 @@ pub fn do_clone( | ||||
|             let user_stack_base = user_stack_range.end(); | ||||
|             let user_stack_limit = user_stack_range.start(); | ||||
|             unsafe { | ||||
|                 Task::new(thread_entry, user_rsp, | ||||
|                           user_stack_base, user_stack_limit, | ||||
|                           new_tls)? | ||||
|                 Task::new( | ||||
|                     thread_entry, | ||||
|                     user_rsp, | ||||
|                     user_stack_base, | ||||
|                     user_stack_limit, | ||||
|                     new_tls, | ||||
|                 )? | ||||
|             } | ||||
|         }; | ||||
|         let files_ref = current.get_files().clone(); | ||||
| @ -119,11 +123,9 @@ fn guess_user_stack_bound(vm: &ProcessVM, user_rsp: usize) -> Result<&VMRange, E | ||||
|     // The next three cases are very unlikely, but valid
 | ||||
|     else if vm.get_stack_range().contains(user_rsp) { | ||||
|         Ok(vm.get_stack_range()) | ||||
|     } | ||||
|     else if vm.get_heap_range().contains(user_rsp) { | ||||
|     } else if vm.get_heap_range().contains(user_rsp) { | ||||
|         Ok(vm.get_heap_range()) | ||||
|     } | ||||
|     else if vm.get_data_range().contains(user_rsp) { | ||||
|     } else if vm.get_data_range().contains(user_rsp) { | ||||
|         Ok(vm.get_data_range()) | ||||
|     } | ||||
|     // Invalid
 | ||||
|  | ||||
| @ -10,12 +10,12 @@ | ||||
| use fs::*; | ||||
| use misc::{resource_t, rlimit_t, utsname_t}; | ||||
| use prelude::*; | ||||
| use process::{pid_t, ChildProcessFilter, CloneFlags, FileAction, FutexFlags, FutexOp, CpuSet}; | ||||
| use process::{pid_t, ChildProcessFilter, CloneFlags, CpuSet, FileAction, FutexFlags, FutexOp}; | ||||
| use std::ffi::{CStr, CString}; | ||||
| use std::ptr; | ||||
| use time::{timeval_t, clockid_t, timespec_t}; | ||||
| use time::{clockid_t, timespec_t, timeval_t}; | ||||
| use util::mem_util::from_user::*; | ||||
| use vm::{VMPerms, MMapFlags}; | ||||
| use vm::{MMapFlags, VMPerms}; | ||||
| use {fs, process, std, vm}; | ||||
| 
 | ||||
| use super::*; | ||||
| @ -175,8 +175,12 @@ pub extern "C" fn dispatch_syscall( | ||||
|         ), | ||||
|         SYS_ARCH_PRCTL => do_arch_prctl(arg0 as u32, arg1 as *mut usize), | ||||
|         SYS_SET_TID_ADDRESS => do_set_tid_address(arg0 as *mut pid_t), | ||||
|         SYS_SCHED_GETAFFINITY => do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar), | ||||
|         SYS_SCHED_SETAFFINITY => do_sched_setaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *const c_uchar), | ||||
|         SYS_SCHED_GETAFFINITY => { | ||||
|             do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar) | ||||
|         } | ||||
|         SYS_SCHED_SETAFFINITY => { | ||||
|             do_sched_setaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *const c_uchar) | ||||
|         } | ||||
| 
 | ||||
|         // memory
 | ||||
|         SYS_MMAP => do_mmap( | ||||
| @ -803,7 +807,6 @@ fn do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t) -> Result<isize, | ||||
|     Ok(0) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // FIXME: use this
 | ||||
| const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void; | ||||
| 
 | ||||
|  | ||||
| @ -35,7 +35,6 @@ extern "C" { | ||||
|     fn ocall_gettimeofday(sec: *mut time_t, usec: *mut suseconds_t) -> sgx_status_t; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[repr(C)] | ||||
| #[derive(Debug, Default, Copy, Clone)] | ||||
| #[allow(non_camel_case_types)] | ||||
| @ -81,7 +80,11 @@ pub fn do_clock_gettime(clockid: ClockID) -> Result<timespec_t, Error> { | ||||
|     let mut sec = 0; | ||||
|     let mut nsec = 0; | ||||
|     unsafe { | ||||
|         ocall_clock_gettime(clockid as clockid_t, &mut sec as *mut time_t, &mut nsec as *mut i64); | ||||
|         ocall_clock_gettime( | ||||
|             clockid as clockid_t, | ||||
|             &mut sec as *mut time_t, | ||||
|             &mut nsec as *mut i64, | ||||
|         ); | ||||
|     } | ||||
|     Ok(timespec_t { sec, nsec }) | ||||
| } | ||||
| @ -90,7 +93,6 @@ extern "C" { | ||||
|     fn ocall_clock_gettime(clockid: clockid_t, sec: *mut time_t, ns: *mut i64) -> sgx_status_t; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // For SEFS
 | ||||
| 
 | ||||
| pub struct OcclumTimeProvider; | ||||
|  | ||||
| @ -1,14 +1,14 @@ | ||||
| use fs::{File, FileDesc, FileRef}; | ||||
| use prelude::*; | ||||
| use process::{get_current, Process, ProcessRef}; | ||||
| use fs::{FileDesc, FileRef, File}; | ||||
| use std::fmt; | ||||
| 
 | ||||
| mod vm_manager; | ||||
| mod user_space_vm; | ||||
| mod process_vm; | ||||
| mod user_space_vm; | ||||
| mod vm_manager; | ||||
| 
 | ||||
| pub use self::process_vm::{ProcessVM, ProcessVMBuilder, MMapFlags, VMPerms}; | ||||
| pub use self::vm_manager::{VMRange}; | ||||
| pub use self::process_vm::{MMapFlags, ProcessVM, ProcessVMBuilder, VMPerms}; | ||||
| pub use self::vm_manager::VMRange; | ||||
| 
 | ||||
| pub fn do_mmap( | ||||
|     addr: usize, | ||||
|  | ||||
| @ -1,10 +1,11 @@ | ||||
| use super::*; | ||||
| use super::vm_manager::{VMRange, VMManager, VMMapOptionsBuilder, VMMapOptions, VMMapAddr, VMInitializer}; | ||||
| use super::user_space_vm::{UserSpaceVMManager, UserSpaceVMRange, USER_SPACE_VM_MANAGER}; | ||||
| use super::super::config; | ||||
| use super::user_space_vm::{UserSpaceVMManager, UserSpaceVMRange, USER_SPACE_VM_MANAGER}; | ||||
| use super::vm_manager::{ | ||||
|     VMInitializer, VMManager, VMMapAddr, VMMapOptions, VMMapOptionsBuilder, VMRange, | ||||
| }; | ||||
| use super::*; | ||||
| use std::slice; | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Debug, Default)] | ||||
| pub struct ProcessVMBuilder { | ||||
|     code_size: usize, | ||||
| @ -47,17 +48,23 @@ impl ProcessVMBuilder { | ||||
|         let data_size = self.data_size; | ||||
|         let ldso_code_size = self.ldso_code_size.unwrap_or(0); | ||||
|         let ldso_data_size = self.ldso_data_size.unwrap_or(0); | ||||
|         let heap_size = self.heap_size.unwrap_or( | ||||
|             config::LIBOS_CONFIG.process.default_heap_size); | ||||
|         let stack_size = self.stack_size.unwrap_or( | ||||
|             config::LIBOS_CONFIG.process.default_stack_size); | ||||
|         let mmap_size = self.mmap_size.unwrap_or( | ||||
|             config::LIBOS_CONFIG.process.default_mmap_size); | ||||
|         let heap_size = self | ||||
|             .heap_size | ||||
|             .unwrap_or(config::LIBOS_CONFIG.process.default_heap_size); | ||||
|         let stack_size = self | ||||
|             .stack_size | ||||
|             .unwrap_or(config::LIBOS_CONFIG.process.default_stack_size); | ||||
|         let mmap_size = self | ||||
|             .mmap_size | ||||
|             .unwrap_or(config::LIBOS_CONFIG.process.default_mmap_size); | ||||
|         let range_sizes = vec![ | ||||
|             code_size, data_size, | ||||
|             ldso_code_size, ldso_data_size, | ||||
|             heap_size, stack_size, | ||||
|             mmap_size | ||||
|             code_size, | ||||
|             data_size, | ||||
|             ldso_code_size, | ||||
|             ldso_data_size, | ||||
|             heap_size, | ||||
|             stack_size, | ||||
|             mmap_size, | ||||
|         ]; | ||||
| 
 | ||||
|         let process_range = { | ||||
| @ -109,7 +116,6 @@ impl ProcessVMBuilder { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// The per-process virtual memory
 | ||||
| #[derive(Debug)] | ||||
| pub struct ProcessVM { | ||||
| @ -212,7 +218,7 @@ impl ProcessVM { | ||||
|         perms: VMPerms, | ||||
|         flags: MMapFlags, | ||||
|         fd: FileDesc, | ||||
|         offset: usize | ||||
|         offset: usize, | ||||
|     ) -> Result<usize, Error> { | ||||
|         let addr_option = { | ||||
|             if flags.contains(MMapFlags::MAP_FIXED) { | ||||
| @ -235,7 +241,10 @@ impl ProcessVM { | ||||
|                 let current_ref = get_current(); | ||||
|                 let current_process = current_ref.lock().unwrap(); | ||||
|                 let file_ref = current_process.get_files().lock().unwrap().get(fd)?; | ||||
|                 VMInitializer::LoadFromFile { file: file_ref, offset: offset } | ||||
|                 VMInitializer::LoadFromFile { | ||||
|                     file: file_ref, | ||||
|                     offset: offset, | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         let mmap_options = VMMapOptionsBuilder::default() | ||||
| @ -256,7 +265,6 @@ impl ProcessVM { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| bitflags! { | ||||
|     pub struct MMapFlags : u32 { | ||||
|         const MAP_FILE            = 0x0; | ||||
| @ -283,12 +291,10 @@ bitflags! { | ||||
| impl MMapFlags { | ||||
|     pub fn from_u32(bits: u32) -> Result<MMapFlags, Error> { | ||||
|         // TODO: detect non-supporting flags
 | ||||
|         MMapFlags::from_bits(bits) | ||||
|             .ok_or_else(|| (Errno::EINVAL, "Unknown mmap flags").into()) | ||||
|         MMapFlags::from_bits(bits).ok_or_else(|| (Errno::EINVAL, "Unknown mmap flags").into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| bitflags! { | ||||
|     pub struct VMPerms : u32 { | ||||
|         const READ        = 0x1; | ||||
| @ -311,12 +317,10 @@ impl VMPerms { | ||||
|     } | ||||
| 
 | ||||
|     pub fn from_u32(bits: u32) -> Result<VMPerms, Error> { | ||||
|         VMPerms::from_bits(bits) | ||||
|             .ok_or_else(|| (Errno::EINVAL, "Unknown permission bits").into()) | ||||
|         VMPerms::from_bits(bits).ok_or_else(|| (Errno::EINVAL, "Unknown permission bits").into()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| unsafe fn fill_zeros(addr: usize, size: usize) { | ||||
|     let ptr = addr as *mut u8; | ||||
|     let buf = slice::from_raw_parts_mut(ptr, size); | ||||
| @ -324,4 +328,3 @@ unsafe fn fill_zeros(addr: usize, size: usize) { | ||||
|         *b = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use super::vm_manager::{VMManager, VMMapOptions, VMMapOptionsBuilder, VMRange}; | ||||
| use super::*; | ||||
| use super::vm_manager::{VMRange, VMManager, VMMapOptionsBuilder, VMMapOptions}; | ||||
| 
 | ||||
| /// The virtual memory manager for the entire user space
 | ||||
| #[derive(Debug)] | ||||
| @ -10,28 +10,25 @@ pub struct UserSpaceVMManager { | ||||
| impl UserSpaceVMManager { | ||||
|     pub unsafe fn from(addr: usize, size: usize) -> Result<UserSpaceVMManager, Error> { | ||||
|         let vm_manager = Arc::new(SgxMutex::new(VMManager::from(addr, size)?)); | ||||
|         Ok(UserSpaceVMManager { | ||||
|             vm_manager, | ||||
|         }) | ||||
|         Ok(UserSpaceVMManager { vm_manager }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn alloc(&self, size: usize) -> Result<UserSpaceVMRange, Error> { | ||||
|         let user_vm_range = unsafe { | ||||
|             let mmap_options = VMMapOptionsBuilder::default() | ||||
|                 .size(size) | ||||
|                 .build()?; | ||||
|             let mmap_options = VMMapOptionsBuilder::default().size(size).build()?; | ||||
| 
 | ||||
|             let mut vm_manager = self.vm_manager.lock().unwrap(); | ||||
|             let user_vm_addr = vm_manager.mmap(&mmap_options)?; | ||||
|             VMRange::from_unchecked(user_vm_addr, user_vm_addr + size) | ||||
|         }; | ||||
|         Ok(UserSpaceVMRange::new(user_vm_range, self.vm_manager.clone())) | ||||
|         Ok(UserSpaceVMRange::new( | ||||
|             user_vm_range, | ||||
|             self.vm_manager.clone(), | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     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()) | ||||
|     } | ||||
| } | ||||
| @ -58,7 +55,6 @@ extern "C" { | ||||
|     pub fn vm_get_preallocated_user_space_memory(addr: &mut usize, size: &mut usize); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct UserSpaceVMRange { | ||||
|     vm_range: VMRange, | ||||
| @ -82,8 +78,12 @@ impl Drop for UserSpaceVMRange { | ||||
|     fn drop(&mut self) { | ||||
|         let addr = self.vm_range.start(); | ||||
|         let size = self.vm_range.size(); | ||||
|         if size == 0 { return; } | ||||
|         if size == 0 { | ||||
|             return; | ||||
|         } | ||||
|         let mut vm_manager = self.vm_manager.lock().unwrap(); | ||||
|         vm_manager.munmap(addr, size).expect("munmap should always succeed"); | ||||
|         vm_manager | ||||
|             .munmap(addr, size) | ||||
|             .expect("munmap should always succeed"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use super::*; | ||||
| use std::{slice}; | ||||
| use std::slice; | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub enum VMInitializer { | ||||
| @ -19,12 +19,12 @@ impl VMInitializer { | ||||
|         match self { | ||||
|             VMInitializer::DoNothing() => { | ||||
|                 // Do nothing
 | ||||
|             }, | ||||
|             } | ||||
|             VMInitializer::FillZeros() => { | ||||
|                 for b in buf { | ||||
|                     *b = 0; | ||||
|                 } | ||||
|             }, | ||||
|             } | ||||
|             VMInitializer::LoadFromFile { file, offset } => { | ||||
|                 // TODO: make sure that read_at does not move file cursor
 | ||||
|                 let len = file.read_at(*offset, buf)?; | ||||
| @ -37,7 +37,6 @@ impl VMInitializer { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Clone, Copy, Debug, PartialEq)] | ||||
| pub enum VMMapAddr { | ||||
|     Any,          // Free to choose any address
 | ||||
| @ -51,21 +50,22 @@ impl Default for VMMapAddr { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Builder, Debug, Default)] | ||||
| #[builder(build_fn(skip), no_std)] | ||||
| pub struct VMMapOptions { | ||||
|     size: usize, | ||||
|     align: usize, | ||||
|     addr: VMMapAddr, | ||||
|     initializer: VMInitializer | ||||
|     initializer: VMInitializer, | ||||
| } | ||||
| 
 | ||||
| // VMMapOptionsBuilder is generated automatically, except the build function
 | ||||
| impl VMMapOptionsBuilder { | ||||
|     pub fn build(&self) -> Result<VMMapOptions, Error> { | ||||
|         let size = { | ||||
|             let size = self.size.ok_or_else(|| (Errno::EINVAL, "Invalid size for mmap"))?; | ||||
|             let size = self | ||||
|                 .size | ||||
|                 .ok_or_else(|| (Errno::EINVAL, "Invalid size for mmap"))?; | ||||
|             if size == 0 { | ||||
|                 return errno!(EINVAL, "Invalid size for mmap"); | ||||
|             } | ||||
| @ -82,9 +82,7 @@ impl VMMapOptionsBuilder { | ||||
|             let addr = self.addr.unwrap_or_default(); | ||||
|             match addr { | ||||
|                 // TODO: check addr + size overflow
 | ||||
|                 VMMapAddr::Any => { | ||||
|                    VMMapAddr::Any | ||||
|                 } | ||||
|                 VMMapAddr::Any => VMMapAddr::Any, | ||||
|                 VMMapAddr::Hint(addr) => { | ||||
|                     let addr = align_down(addr, PAGE_SIZE); | ||||
|                     VMMapAddr::Hint(addr) | ||||
| @ -98,8 +96,8 @@ impl VMMapOptionsBuilder { | ||||
|             } | ||||
|         }; | ||||
|         let initializer = match self.initializer.as_ref() { | ||||
|             Some(initializer) => { initializer.clone() } | ||||
|             None => { VMInitializer::default() } | ||||
|             Some(initializer) => initializer.clone(), | ||||
|             None => VMInitializer::default(), | ||||
|         }; | ||||
|         Ok(VMMapOptions { | ||||
|             size, | ||||
| @ -124,7 +122,6 @@ impl VMMapOptions { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Debug, Default)] | ||||
| pub struct VMManager { | ||||
|     range: VMRange, | ||||
| @ -141,20 +138,14 @@ impl VMManager { | ||||
|             let end_sentry = VMRange::from(end, end)?; | ||||
|             vec![start_sentry, end_sentry] | ||||
|         }; | ||||
|         Ok(VMManager { | ||||
|             range, | ||||
|             sub_ranges, | ||||
|         }) | ||||
|         Ok(VMManager { range, sub_ranges }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn range(&self) -> &VMRange { | ||||
|         &self.range | ||||
|     } | ||||
| 
 | ||||
|     pub fn mmap( | ||||
|         &mut self, | ||||
|         options: &VMMapOptions, | ||||
|     ) -> Result<usize, Error> { | ||||
|     pub fn mmap(&mut self, options: &VMMapOptions) -> Result<usize, Error> { | ||||
|         // TODO: respect options.align when mmap
 | ||||
|         let addr = *options.addr(); | ||||
|         let size = *options.size(); | ||||
| @ -194,22 +185,24 @@ impl VMManager { | ||||
| 
 | ||||
|             let effective_munmap_range_opt = munmap_range.intersect(&self.range); | ||||
|             if effective_munmap_range_opt.is_none() { | ||||
|                 return Ok(()) | ||||
|                 return Ok(()); | ||||
|             } | ||||
| 
 | ||||
|             let effective_munmap_range = effective_munmap_range_opt.unwrap(); | ||||
|             if effective_munmap_range.empty() { | ||||
|                 return Ok(()) | ||||
|                 return Ok(()); | ||||
|             } | ||||
|             effective_munmap_range | ||||
|         }; | ||||
| 
 | ||||
|         let new_sub_ranges = self.sub_ranges | ||||
|         let new_sub_ranges = self | ||||
|             .sub_ranges | ||||
|             .iter() | ||||
|             .flat_map(|subrange| { | ||||
|                 if subrange.size() > 0 { | ||||
|                     subrange.subtract(&munmap_range) | ||||
|                 } else { // Keep the two sentry subranges intact
 | ||||
|                 } else { | ||||
|                     // Keep the two sentry subranges intact
 | ||||
|                     vec![*subrange] | ||||
|                 } | ||||
|             }) | ||||
| @ -219,17 +212,20 @@ impl VMManager { | ||||
|     } | ||||
| 
 | ||||
|     pub fn find_mmap_region(&self, addr: usize) -> Result<&VMRange, Error> { | ||||
|         self.sub_ranges.iter() | ||||
|         self.sub_ranges | ||||
|             .iter() | ||||
|             .find(|subrange| subrange.contains(addr)) | ||||
|             .ok_or(Error::new(Errno::ESRCH, | ||||
|                               "no mmap regions that contains the address")) | ||||
|             .ok_or(Error::new( | ||||
|                 Errno::ESRCH, | ||||
|                 "no mmap regions that contains the address", | ||||
|             )) | ||||
|     } | ||||
| 
 | ||||
|     // Find the free subrange that satisfies the constraints of size and address
 | ||||
|     fn find_free_subrange( | ||||
|         &mut self, | ||||
|         size: usize, | ||||
|         addr: VMMapAddr | ||||
|         addr: VMMapAddr, | ||||
|     ) -> Result<(usize, VMRange), Error> { | ||||
|         // TODO: reduce the complexity from O(N) to O(log(N)), where N is
 | ||||
|         // the number of existing subranges.
 | ||||
| @ -253,9 +249,7 @@ impl VMManager { | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 unsafe { | ||||
|                     VMRange::from_unchecked(free_range_start, free_range_end) | ||||
|                 } | ||||
|                 unsafe { VMRange::from_unchecked(free_range_start, free_range_end) } | ||||
|             }; | ||||
| 
 | ||||
|             match addr { | ||||
| @ -289,7 +283,8 @@ impl VMManager { | ||||
|             } | ||||
| 
 | ||||
|             if result_free_range == None | ||||
|                 || result_free_range.as_ref().unwrap().size() > free_range.size() { | ||||
|                 || result_free_range.as_ref().unwrap().size() > free_range.size() | ||||
|             { | ||||
|                 result_free_range = Some(free_range); | ||||
|                 result_idx = Some(idx); | ||||
|             } | ||||
| @ -308,7 +303,7 @@ impl VMManager { | ||||
|         &self, | ||||
|         size: usize, | ||||
|         addr: VMMapAddr, | ||||
|         free_subrange: &VMRange | ||||
|         free_subrange: &VMRange, | ||||
|     ) -> VMRange { | ||||
|         debug_assert!(free_subrange.size() >= size); | ||||
| 
 | ||||
| @ -384,19 +379,22 @@ impl VMRange { | ||||
|         let other_end = other.end(); | ||||
| 
 | ||||
|         match (self_start < other_start, other_end < self_end) { | ||||
|             (false, false) => { | ||||
|                 Vec::new() | ||||
|             } | ||||
|             (false, false) => Vec::new(), | ||||
|             (false, true) => unsafe { | ||||
|                 vec![VMRange::from_unchecked(self_start.max(other_end), self_end)] | ||||
|             } | ||||
|             }, | ||||
|             (true, false) => unsafe { | ||||
|                 vec![VMRange::from_unchecked(self_start, self_end.min(other_start))] | ||||
|             } | ||||
|                 vec![VMRange::from_unchecked( | ||||
|                     self_start, | ||||
|                     self_end.min(other_start), | ||||
|                 )] | ||||
|             }, | ||||
|             (true, true) => unsafe { | ||||
|                 vec![VMRange::from_unchecked(self_start, other_start), | ||||
|                      VMRange::from_unchecked(other_end, self_end)] | ||||
|             } | ||||
|                 vec![ | ||||
|                     VMRange::from_unchecked(self_start, other_start), | ||||
|                     VMRange::from_unchecked(other_end, self_end), | ||||
|                 ] | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -407,7 +405,10 @@ impl VMRange { | ||||
|             return None; | ||||
|         } | ||||
|         unsafe { | ||||
|             Some(VMRange::from_unchecked(intersection_start, intersection_end)) | ||||
|             Some(VMRange::from_unchecked( | ||||
|                 intersection_start, | ||||
|                 intersection_end, | ||||
|             )) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user