diff --git a/demos/java/run_java_on_occlum.sh b/demos/java/run_java_on_occlum.sh index 3e8d347e..347b9339 100755 --- a/demos/java/run_java_on_occlum.sh +++ b/demos/java/run_java_on_occlum.sh @@ -36,7 +36,7 @@ init_instance() { } update_pku_config() { - new_json="$(jq '.metadata.pkru = 1' Occlum.json)" && echo "${new_json}" > Occlum.json + new_json="$(jq '.feature.pkru = 1' Occlum.json)" && echo "${new_json}" > Occlum.json } build_web() { diff --git a/demos/python/python_glibc/python3.10-multiprocessing/run_python3.10_on_occlum.sh b/demos/python/python_glibc/python3.10-multiprocessing/run_python3.10_on_occlum.sh index dc23d28d..499576eb 100755 --- a/demos/python/python_glibc/python3.10-multiprocessing/run_python3.10_on_occlum.sh +++ b/demos/python/python_glibc/python3.10-multiprocessing/run_python3.10_on_occlum.sh @@ -19,6 +19,7 @@ fi new_json="$(jq '.resource_limits.user_space_size = "1000MB" | .resource_limits.kernel_space_heap_size = "300MB" | + .feature.enable_posix_shm = true | .env.default += ["PYTHONHOME=/opt/python-occlum", "PATH=/bin"]' Occlum.json)" && \ echo "${new_json}" > Occlum.json occlum build diff --git a/demos/sofaboot/.gitignore b/demos/sofaboot/.gitignore new file mode 100644 index 00000000..47e92b7c --- /dev/null +++ b/demos/sofaboot/.gitignore @@ -0,0 +1,2 @@ +occlum_instance +sofa-boot-guides diff --git a/docs/pku_manual.md b/docs/pku_manual.md index b17f9ada..59727658 100644 --- a/docs/pku_manual.md +++ b/docs/pku_manual.md @@ -106,7 +106,7 @@ PKU feature can only be enabled in `HW` mode. Whether to turn on PKU feature is ```js { // ... - "metadata": { + "feature": { // "pkru" = 0: PKU feature must be disabled // "pkru" = 1: PKU feature must be enabled // "pkru" = 2: PKU feature is enabled if the platform supports it @@ -118,8 +118,8 @@ PKU feature can only be enabled in `HW` mode. Whether to turn on PKU feature is Users have three options for PKU feature: -1. If `metadata.pkru` == 0: The PKU feature must disabled in Occlum. It is the default value. Since docker has not supported PKU related syscalls in container environment by default, Occlum turns off PKU feature in default configuration. +1. If `feature.pkru` == 0: The PKU feature must disabled in Occlum. It is the default value. Since docker has not supported PKU related syscalls in container environment by default, Occlum turns off PKU feature in default configuration. -2. If `metadata.pkru` == 1: The PKU feature must enabled in Occlum. If CPU on the platform does not support PKU, then enclave cannot be successfully initialized. +2. If `feature.pkru` == 1: The PKU feature must enabled in Occlum. If CPU on the platform does not support PKU, then enclave cannot be successfully initialized. -3. If `metadata.pkru` == 2: If CPU supports PKU, also OS enables PKU feature, PKU feature is turned on in Occlum. +3. If `feature.pkru` == 2: If CPU supports PKU, also OS enables PKU feature, PKU feature is turned on in Occlum. diff --git a/docs/readthedocs/docs/source/occlum_configuration.md b/docs/readthedocs/docs/source/occlum_configuration.md index 476c9123..fa590db2 100644 --- a/docs/readthedocs/docs/source/occlum_configuration.md +++ b/docs/readthedocs/docs/source/occlum_configuration.md @@ -61,7 +61,10 @@ The template of `Occlum.json` is shown below. "version_number": 0, // Whether the enclave is debuggable through special SGX instructions. // For production enclave, it is IMPORTANT to set this value to false. - "debuggable": true, + "debuggable": true + }, + // Features + "feature": { // Whether to turn on PKU feature in Occlum // Occlum uses PKU for isolation between LibOS and userspace program, // It is useful for developers to detect potential bugs. @@ -69,7 +72,15 @@ The template of `Occlum.json` is shown below. // "pkru" = 0: PKU feature must be disabled // "pkru" = 1: PKU feature must be enabled // "pkru" = 2: PKU feature is enabled if the platform supports it - "pkru": 0 + "pkru": 0, + // Whether to enable POSIX shared memory feature. + // Enabling POSIX shm allows processes to communicate by sharing a region of memory. + // + // Set "enable_posix_shm" to true, the syscall `mmap` with flag `MAP_SHARED` + // is supported more comprehensively, implies that the file-backed memory mapping + // become shared among processes. + // More API information of POSIX shm is listed in [shm_overview](https://man7.org/linux/man-pages/man7/shm_overview.7.html). + "enable_posix_shm": false }, // Mount points and their file systems // diff --git a/etc/template/Occlum.json b/etc/template/Occlum.json index 64b4b4de..f3c3a2fa 100644 --- a/etc/template/Occlum.json +++ b/etc/template/Occlum.json @@ -34,9 +34,12 @@ "high": "0x0", "low": "0x0" }, - "pkru": 0, "amx": 0 }, + "feature": { + "pkru": 0, + "enable_posix_shm": false + }, "mount": [ { "target": "/", diff --git a/src/libos/src/config.rs b/src/libos/src/config.rs index f9e65dcc..0eca7c96 100644 --- a/src/libos/src/config.rs +++ b/src/libos/src/config.rs @@ -104,6 +104,7 @@ pub struct Config { pub process: ConfigProcess, pub env: ConfigEnv, pub app: Vec, + pub feature: ConfigFeature, } #[derive(Debug)] @@ -140,6 +141,12 @@ pub struct ConfigApp { pub mount: Vec, } +#[derive(Clone, Debug)] +pub struct ConfigFeature { + pub pkru: u32, + pub enable_posix_shm: bool, +} + #[derive(Clone, Debug, PartialEq)] #[allow(non_camel_case_types)] pub enum ConfigMountFsType { @@ -184,7 +191,6 @@ impl Config { let resource_limits = ConfigResourceLimits::from_input(&input.resource_limits)?; let process = ConfigProcess::from_input(&input.process)?; let env = ConfigEnv::from_input(&input.env)?; - let app = { let mut app = Vec::new(); for input_app in &input.app { @@ -192,12 +198,14 @@ impl Config { } app }; + let feature = ConfigFeature::from_input(&input.feature)?; Ok(Config { resource_limits, process, env, app, + feature, }) } @@ -275,6 +283,15 @@ impl ConfigApp { } } +impl ConfigFeature { + fn from_input(input: &InputConfigFeature) -> Result { + Ok(ConfigFeature { + pkru: input.pkru, + enable_posix_shm: input.enable_posix_shm, + }) + } +} + impl ConfigMount { fn from_input(input: &InputConfigMount) -> Result { let type_ = ConfigMountFsType::from_input(input.type_.as_str())?; @@ -369,6 +386,8 @@ struct InputConfig { pub env: InputConfigEnv, #[serde(default)] pub app: Vec, + #[serde(default)] + pub feature: InputConfigFeature, } #[derive(Deserialize, Debug)] @@ -488,6 +507,24 @@ struct InputConfigApp { pub mount: Vec, } +#[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] +struct InputConfigFeature { + #[serde(default)] + pub pkru: u32, + #[serde(default)] + pub enable_posix_shm: bool, +} + +impl Default for InputConfigFeature { + fn default() -> InputConfigFeature { + InputConfigFeature { + pkru: 0, + enable_posix_shm: false, + } + } +} + #[repr(C)] #[derive(Debug, Copy, Clone)] #[allow(non_camel_case_types)] diff --git a/src/libos/src/vm/vm_manager.rs b/src/libos/src/vm/vm_manager.rs index 10bd26fd..1c81c68d 100644 --- a/src/libos/src/vm/vm_manager.rs +++ b/src/libos/src/vm/vm_manager.rs @@ -9,6 +9,7 @@ use super::vm_area::{VMAccess, VMArea}; use super::vm_chunk_manager::ChunkManager; use super::vm_perms::VMPerms; use super::vm_util::*; +use crate::config::LIBOS_CONFIG; use crate::ipc::SYSTEM_V_SHM_MANAGER; use crate::process::{ThreadRef, ThreadStatus}; @@ -88,7 +89,7 @@ impl VMManager { } pub fn mmap(&self, options: &VMMapOptions) -> Result { - if options.is_shared() { + if LIBOS_CONFIG.feature.enable_posix_shm && options.is_shared() { let res = self.internal().mmap_shared_chunk(options); match res { Ok(addr) => { @@ -694,7 +695,7 @@ impl InternalVMManager { } }; - if chunk.is_shared() { + if LIBOS_CONFIG.feature.enable_posix_shm && chunk.is_shared() { trace!( "munmap_shared_chunk, chunk_range = {:?}, munmap_range = {:?}", chunk.range(), @@ -875,7 +876,7 @@ impl InternalVMManager { new_perms: VMPerms, ) -> Result<()> { debug_assert!(chunk.range().is_superset_of(&protect_range)); - if chunk.is_shared() { + if LIBOS_CONFIG.feature.enable_posix_shm && chunk.is_shared() { trace!( "mprotect_shared_chunk, chunk_range: {:?}, mprotect_range = {:?}", chunk.range(), diff --git a/test/Occlum.json b/test/Occlum.json index 65318e86..d73df3a0 100644 --- a/test/Occlum.json +++ b/test/Occlum.json @@ -39,8 +39,11 @@ "ext_prod_id": { "high": "0x0", "low": "0x0" - }, - "pkru": 0 + } + }, + "feature": { + "pkru": 0, + "enable_posix_shm": true }, "mount": [ { diff --git a/tools/gen_internal_conf/src/main.rs b/tools/gen_internal_conf/src/main.rs index 31caffe1..5e324b01 100644 --- a/tools/gen_internal_conf/src/main.rs +++ b/tools/gen_internal_conf/src/main.rs @@ -173,7 +173,10 @@ fn main() { *init_num_of_threads } else { // The user doesn't provide a value - std::cmp::min(DEFAULT_CONFIG.tcs_init_num,occlum_config.resource_limits.max_num_of_threads ) + std::cmp::min( + DEFAULT_CONFIG.tcs_init_num, + occlum_config.resource_limits.max_num_of_threads, + ) }; // For platforms with EDMM support, use the max value @@ -197,7 +200,8 @@ fn main() { if tcs_init_num > tcs_max_num { println!( "init_num_of_threads: {:?}, max_num_of_threads: {:?}, wrong configuration", - occlum_config.resource_limits.init_num_of_threads, occlum_config.resource_limits.max_num_of_threads, + occlum_config.resource_limits.init_num_of_threads, + occlum_config.resource_limits.max_num_of_threads, ); return; } @@ -353,7 +357,8 @@ fn main() { if config_user_space_init_size > config_user_space_max_size { println!( "user_space_size: {:?}, user_space_max_size: {:?}, wrong configuration", - occlum_config.resource_limits.user_space_size, occlum_config.resource_limits.user_space_max_size, + occlum_config.resource_limits.user_space_size, + occlum_config.resource_limits.user_space_max_size, ); return; } @@ -373,12 +378,13 @@ fn main() { println!("The extra_user_region_for_sdk in default config is not correct."); return; } - let user_region_mem_size = if config_user_space_max_size == config_user_space_init_size { - // SDK still need user region to track the EMA. - config_user_space_max_size - } else { - config_user_space_max_size + extra_user_region.unwrap() - }; + let user_region_mem_size = + if config_user_space_max_size == config_user_space_init_size { + // SDK still need user region to track the EMA. + config_user_space_max_size + } else { + config_user_space_max_size + extra_user_region.unwrap() + }; ( config_user_space_init_size as u64, @@ -460,7 +466,7 @@ fn main() { ISVEXTPRODID_L: kss_tuple.2, ISVFAMILYID_H: kss_tuple.3, ISVFAMILYID_L: kss_tuple.4, - PKRU: occlum_config.metadata.pkru, + PKRU: occlum_config.feature.pkru, AMX: occlum_config.metadata.amx, }; let enclave_config = serde_xml_rs::to_string(&sgx_enclave_configuration).unwrap(); @@ -493,6 +499,7 @@ fn main() { }, env: occlum_config.env, app: app_config, + feature: occlum_config.feature.clone(), }; let occlum_json_str = serde_json::to_string_pretty(&occlum_json_config).unwrap(); @@ -683,6 +690,7 @@ struct OcclumConfiguration { entry_points: serde_json::Value, env: serde_json::Value, metadata: OcclumMetadata, + feature: OcclumFeature, mount: Vec, } @@ -723,10 +731,16 @@ struct OcclumMetadata { enable_kss: bool, family_id: OcclumMetaID, ext_prod_id: OcclumMetaID, + #[serde(default)] + amx: u32, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +struct OcclumFeature { #[serde(default)] pkru: u32, #[serde(default)] - amx: u32, + enable_posix_shm: bool, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -810,4 +824,5 @@ struct InternalOcclumJson { process: OcclumProcess, env: serde_json::Value, app: serde_json::Value, + feature: OcclumFeature, }