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 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";
|
||||||
|
|
||||||
@ -9,42 +9,53 @@ 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,8 +72,7 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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,
|
||||||
@ -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)?;
|
||||||
@ -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,11 +208,13 @@ 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),
|
||||||
@ -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 {
|
||||||
@ -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(())
|
||||||
|
@ -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