[config] Add "feature" field to Occlum.json

This commit is contained in:
Shaowei Song 2023-12-24 17:29:51 +08:00 committed by volcano
parent 5efc54cb81
commit 76edc08233
10 changed files with 98 additions and 25 deletions

@ -36,7 +36,7 @@ init_instance() {
} }
update_pku_config() { 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() { build_web() {

@ -19,6 +19,7 @@ fi
new_json="$(jq '.resource_limits.user_space_size = "1000MB" | new_json="$(jq '.resource_limits.user_space_size = "1000MB" |
.resource_limits.kernel_space_heap_size = "300MB" | .resource_limits.kernel_space_heap_size = "300MB" |
.feature.enable_posix_shm = true |
.env.default += ["PYTHONHOME=/opt/python-occlum", "PATH=/bin"]' Occlum.json)" && \ .env.default += ["PYTHONHOME=/opt/python-occlum", "PATH=/bin"]' Occlum.json)" && \
echo "${new_json}" > Occlum.json echo "${new_json}" > Occlum.json
occlum build occlum build

2
demos/sofaboot/.gitignore vendored Normal file

@ -0,0 +1,2 @@
occlum_instance
sofa-boot-guides

@ -106,7 +106,7 @@ PKU feature can only be enabled in `HW` mode. Whether to turn on PKU feature is
```js ```js
{ {
// ... // ...
"metadata": { "feature": {
// "pkru" = 0: PKU feature must be disabled // "pkru" = 0: PKU feature must be disabled
// "pkru" = 1: PKU feature must be enabled // "pkru" = 1: PKU feature must be enabled
// "pkru" = 2: PKU feature is enabled if the platform supports it // "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: 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.

@ -61,7 +61,10 @@ The template of `Occlum.json` is shown below.
"version_number": 0, "version_number": 0,
// Whether the enclave is debuggable through special SGX instructions. // Whether the enclave is debuggable through special SGX instructions.
// For production enclave, it is IMPORTANT to set this value to false. // 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 // Whether to turn on PKU feature in Occlum
// Occlum uses PKU for isolation between LibOS and userspace program, // Occlum uses PKU for isolation between LibOS and userspace program,
// It is useful for developers to detect potential bugs. // 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" = 0: PKU feature must be disabled
// "pkru" = 1: PKU feature must be enabled // "pkru" = 1: PKU feature must be enabled
// "pkru" = 2: PKU feature is enabled if the platform supports it // "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 // Mount points and their file systems
// //

@ -34,9 +34,12 @@
"high": "0x0", "high": "0x0",
"low": "0x0" "low": "0x0"
}, },
"pkru": 0,
"amx": 0 "amx": 0
}, },
"feature": {
"pkru": 0,
"enable_posix_shm": false
},
"mount": [ "mount": [
{ {
"target": "/", "target": "/",

@ -104,6 +104,7 @@ pub struct Config {
pub process: ConfigProcess, pub process: ConfigProcess,
pub env: ConfigEnv, pub env: ConfigEnv,
pub app: Vec<ConfigApp>, pub app: Vec<ConfigApp>,
pub feature: ConfigFeature,
} }
#[derive(Debug)] #[derive(Debug)]
@ -140,6 +141,12 @@ pub struct ConfigApp {
pub mount: Vec<ConfigMount>, pub mount: Vec<ConfigMount>,
} }
#[derive(Clone, Debug)]
pub struct ConfigFeature {
pub pkru: u32,
pub enable_posix_shm: bool,
}
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum ConfigMountFsType { pub enum ConfigMountFsType {
@ -184,7 +191,6 @@ impl Config {
let resource_limits = ConfigResourceLimits::from_input(&input.resource_limits)?; let resource_limits = ConfigResourceLimits::from_input(&input.resource_limits)?;
let process = ConfigProcess::from_input(&input.process)?; let process = ConfigProcess::from_input(&input.process)?;
let env = ConfigEnv::from_input(&input.env)?; let env = ConfigEnv::from_input(&input.env)?;
let app = { let app = {
let mut app = Vec::new(); let mut app = Vec::new();
for input_app in &input.app { for input_app in &input.app {
@ -192,12 +198,14 @@ impl Config {
} }
app app
}; };
let feature = ConfigFeature::from_input(&input.feature)?;
Ok(Config { Ok(Config {
resource_limits, resource_limits,
process, process,
env, env,
app, app,
feature,
}) })
} }
@ -275,6 +283,15 @@ impl ConfigApp {
} }
} }
impl ConfigFeature {
fn from_input(input: &InputConfigFeature) -> Result<ConfigFeature> {
Ok(ConfigFeature {
pkru: input.pkru,
enable_posix_shm: input.enable_posix_shm,
})
}
}
impl ConfigMount { impl ConfigMount {
fn from_input(input: &InputConfigMount) -> Result<ConfigMount> { fn from_input(input: &InputConfigMount) -> Result<ConfigMount> {
let type_ = ConfigMountFsType::from_input(input.type_.as_str())?; let type_ = ConfigMountFsType::from_input(input.type_.as_str())?;
@ -369,6 +386,8 @@ struct InputConfig {
pub env: InputConfigEnv, pub env: InputConfigEnv,
#[serde(default)] #[serde(default)]
pub app: Vec<InputConfigApp>, pub app: Vec<InputConfigApp>,
#[serde(default)]
pub feature: InputConfigFeature,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
@ -488,6 +507,24 @@ struct InputConfigApp {
pub mount: Vec<InputConfigMount>, pub mount: Vec<InputConfigMount>,
} }
#[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)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]

@ -9,6 +9,7 @@ use super::vm_area::{VMAccess, VMArea};
use super::vm_chunk_manager::ChunkManager; use super::vm_chunk_manager::ChunkManager;
use super::vm_perms::VMPerms; use super::vm_perms::VMPerms;
use super::vm_util::*; use super::vm_util::*;
use crate::config::LIBOS_CONFIG;
use crate::ipc::SYSTEM_V_SHM_MANAGER; use crate::ipc::SYSTEM_V_SHM_MANAGER;
use crate::process::{ThreadRef, ThreadStatus}; use crate::process::{ThreadRef, ThreadStatus};
@ -88,7 +89,7 @@ impl VMManager {
} }
pub fn mmap(&self, options: &VMMapOptions) -> Result<usize> { pub fn mmap(&self, options: &VMMapOptions) -> Result<usize> {
if options.is_shared() { if LIBOS_CONFIG.feature.enable_posix_shm && options.is_shared() {
let res = self.internal().mmap_shared_chunk(options); let res = self.internal().mmap_shared_chunk(options);
match res { match res {
Ok(addr) => { Ok(addr) => {
@ -694,7 +695,7 @@ impl InternalVMManager {
} }
}; };
if chunk.is_shared() { if LIBOS_CONFIG.feature.enable_posix_shm && chunk.is_shared() {
trace!( trace!(
"munmap_shared_chunk, chunk_range = {:?}, munmap_range = {:?}", "munmap_shared_chunk, chunk_range = {:?}, munmap_range = {:?}",
chunk.range(), chunk.range(),
@ -875,7 +876,7 @@ impl InternalVMManager {
new_perms: VMPerms, new_perms: VMPerms,
) -> Result<()> { ) -> Result<()> {
debug_assert!(chunk.range().is_superset_of(&protect_range)); debug_assert!(chunk.range().is_superset_of(&protect_range));
if chunk.is_shared() { if LIBOS_CONFIG.feature.enable_posix_shm && chunk.is_shared() {
trace!( trace!(
"mprotect_shared_chunk, chunk_range: {:?}, mprotect_range = {:?}", "mprotect_shared_chunk, chunk_range: {:?}, mprotect_range = {:?}",
chunk.range(), chunk.range(),

@ -39,8 +39,11 @@
"ext_prod_id": { "ext_prod_id": {
"high": "0x0", "high": "0x0",
"low": "0x0" "low": "0x0"
}
}, },
"pkru": 0 "feature": {
"pkru": 0,
"enable_posix_shm": true
}, },
"mount": [ "mount": [
{ {

@ -173,7 +173,10 @@ fn main() {
*init_num_of_threads *init_num_of_threads
} else { } else {
// The user doesn't provide a value // 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 // For platforms with EDMM support, use the max value
@ -197,7 +200,8 @@ fn main() {
if tcs_init_num > tcs_max_num { if tcs_init_num > tcs_max_num {
println!( println!(
"init_num_of_threads: {:?}, max_num_of_threads: {:?}, wrong configuration", "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; return;
} }
@ -353,7 +357,8 @@ fn main() {
if config_user_space_init_size > config_user_space_max_size { if config_user_space_init_size > config_user_space_max_size {
println!( println!(
"user_space_size: {:?}, user_space_max_size: {:?}, wrong configuration", "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; return;
} }
@ -373,7 +378,8 @@ fn main() {
println!("The extra_user_region_for_sdk in default config is not correct."); println!("The extra_user_region_for_sdk in default config is not correct.");
return; return;
} }
let user_region_mem_size = if config_user_space_max_size == config_user_space_init_size { 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. // SDK still need user region to track the EMA.
config_user_space_max_size config_user_space_max_size
} else { } else {
@ -460,7 +466,7 @@ fn main() {
ISVEXTPRODID_L: kss_tuple.2, ISVEXTPRODID_L: kss_tuple.2,
ISVFAMILYID_H: kss_tuple.3, ISVFAMILYID_H: kss_tuple.3,
ISVFAMILYID_L: kss_tuple.4, ISVFAMILYID_L: kss_tuple.4,
PKRU: occlum_config.metadata.pkru, PKRU: occlum_config.feature.pkru,
AMX: occlum_config.metadata.amx, AMX: occlum_config.metadata.amx,
}; };
let enclave_config = serde_xml_rs::to_string(&sgx_enclave_configuration).unwrap(); let enclave_config = serde_xml_rs::to_string(&sgx_enclave_configuration).unwrap();
@ -493,6 +499,7 @@ fn main() {
}, },
env: occlum_config.env, env: occlum_config.env,
app: app_config, app: app_config,
feature: occlum_config.feature.clone(),
}; };
let occlum_json_str = serde_json::to_string_pretty(&occlum_json_config).unwrap(); let occlum_json_str = serde_json::to_string_pretty(&occlum_json_config).unwrap();
@ -683,6 +690,7 @@ struct OcclumConfiguration {
entry_points: serde_json::Value, entry_points: serde_json::Value,
env: serde_json::Value, env: serde_json::Value,
metadata: OcclumMetadata, metadata: OcclumMetadata,
feature: OcclumFeature,
mount: Vec<OcclumMount>, mount: Vec<OcclumMount>,
} }
@ -723,10 +731,16 @@ struct OcclumMetadata {
enable_kss: bool, enable_kss: bool,
family_id: OcclumMetaID, family_id: OcclumMetaID,
ext_prod_id: OcclumMetaID, ext_prod_id: OcclumMetaID,
#[serde(default)]
amx: u32,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
struct OcclumFeature {
#[serde(default)] #[serde(default)]
pkru: u32, pkru: u32,
#[serde(default)] #[serde(default)]
amx: u32, enable_posix_shm: bool,
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -810,4 +824,5 @@ struct InternalOcclumJson {
process: OcclumProcess, process: OcclumProcess,
env: serde_json::Value, env: serde_json::Value,
app: serde_json::Value, app: serde_json::Value,
feature: OcclumFeature,
} }