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