From 9d2f298efa61f473281818c86f338464c9b554f1 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sun, 12 Dec 2021 00:54:42 +0000 Subject: [PATCH] Add sel4-config build helper for syncing crates to an seL4 kernel build. sel4-config is a build helper for keeping a crate's features in sync with an seL4 kernel. sel4_config::get_sel4_features parses a gen_config.h artifact from an seL4 build and returns the intersection of the feature set with the features listed in the caller's Cargo.toml. Change sel4-sys to use sel4-config to collect features (instead of depending only on features from Cargo.toml). sel4-sys finds the directory with kernel artifacts using an SEL4_OUT_DIR environment variable. If that's not set it falls back to ${ROOTDIR}/out/kata/kernel. Change workspace crates to use resolver="2" to deal with cargo's mishandling of dependent features (target build of serde polluted by std build-dep indirect through cargo_toml). While here make sel4-sys fall back to ${ROOTDIR}/kata/kernel when SEL4_DIR is not set in the environment. Change-Id: I47cf2eab4aa8cd2e502f741738f587c222e94716 GitOrigin-RevId: b661f0b78c0bfe70861965a420d25add8a128cb7 --- apps/system/components/.cargo/config.toml | 4 - .../system/components/DebugConsole/Cargo.toml | 1 + .../components/MlCoordinator/Cargo.toml | 1 + .../components/ProcessManager/Cargo.toml | 2 + .../components/SecurityCoordinator/Cargo.toml | 1 + .../components/StorageManager/Cargo.toml | 1 + .../components/kata-os-common/Cargo.toml | 28 ------ .../kata-os-common/src/sel4-config/Cargo.toml | 11 +++ .../kata-os-common/src/sel4-config/src/lib.rs | 46 ++++++++++ .../kata-os-common/src/sel4-sys/Cargo.toml | 24 ++--- .../kata-os-common/src/sel4-sys/build.rs | 91 ++++++++++++------- 11 files changed, 135 insertions(+), 75 deletions(-) delete mode 100644 apps/system/components/.cargo/config.toml create mode 100644 apps/system/components/kata-os-common/src/sel4-config/Cargo.toml create mode 100644 apps/system/components/kata-os-common/src/sel4-config/src/lib.rs diff --git a/apps/system/components/.cargo/config.toml b/apps/system/components/.cargo/config.toml deleted file mode 100644 index 37a93d6..0000000 --- a/apps/system/components/.cargo/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[env] -# Pathname to seL4 kernel for xml files and (eventually) tools scripts, -# defaults to "sel4" if not set -SEL4_DIR = { value = "../../../../../kernel", relative = true } \ No newline at end of file diff --git a/apps/system/components/DebugConsole/Cargo.toml b/apps/system/components/DebugConsole/Cargo.toml index 730158b..9752d0f 100644 --- a/apps/system/components/DebugConsole/Cargo.toml +++ b/apps/system/components/DebugConsole/Cargo.toml @@ -9,6 +9,7 @@ members = [ "kata-uart-client", "zmodem", ] +resolver = "2" [profile.dev] opt-level = 0 diff --git a/apps/system/components/MlCoordinator/Cargo.toml b/apps/system/components/MlCoordinator/Cargo.toml index 7b75abf..888b05c 100644 --- a/apps/system/components/MlCoordinator/Cargo.toml +++ b/apps/system/components/MlCoordinator/Cargo.toml @@ -5,6 +5,7 @@ members = [ "kata-ml-interface", "kata-vec-core" ] +resolver = "2" [profile.dev] opt-level = 0 diff --git a/apps/system/components/ProcessManager/Cargo.toml b/apps/system/components/ProcessManager/Cargo.toml index d02bca7..da48d85 100644 --- a/apps/system/components/ProcessManager/Cargo.toml +++ b/apps/system/components/ProcessManager/Cargo.toml @@ -5,6 +5,8 @@ members = [ "kata-proc-interface", "kata-proc-manager", ] +resolver = "2" + [profile.dev] opt-level = 0 diff --git a/apps/system/components/SecurityCoordinator/Cargo.toml b/apps/system/components/SecurityCoordinator/Cargo.toml index 6ebcb95..8911ac7 100644 --- a/apps/system/components/SecurityCoordinator/Cargo.toml +++ b/apps/system/components/SecurityCoordinator/Cargo.toml @@ -5,6 +5,7 @@ members = [ "kata-security-coordinator", "kata-security-interface", ] +resolver = "2" [profile.dev] opt-level = 0 diff --git a/apps/system/components/StorageManager/Cargo.toml b/apps/system/components/StorageManager/Cargo.toml index 5c3d535..095342a 100644 --- a/apps/system/components/StorageManager/Cargo.toml +++ b/apps/system/components/StorageManager/Cargo.toml @@ -5,6 +5,7 @@ members = [ "kata-storage-interface", "kata-storage-manager", ] +resolver = "2" [profile.dev] opt-level = 0 diff --git a/apps/system/components/kata-os-common/Cargo.toml b/apps/system/components/kata-os-common/Cargo.toml index abfaf2f..29ba89c 100644 --- a/apps/system/components/kata-os-common/Cargo.toml +++ b/apps/system/components/kata-os-common/Cargo.toml @@ -3,33 +3,5 @@ name = "kata-os-common" version = "0.1.0" edition = "2018" -[features] -default = [ - "CONFIG_PRINTING", - "CONFIG_DEBUG_BUILD", - "CONFIG_KERNEL_MCS", -] -CONFIG_ARM_HYPERVISOR_SUPPORT = [ - "sel4-sys/CONFIG_ARM_HYPERVISOR_SUPPORT", -] -CONFIG_ARM_SMMU = [ - "sel4-sys/CONFIG_ARM_SMMU", -] -CONFIG_DEBUG_BUILD = [ - "sel4-sys/CONFIG_DEBUG_BUILD", -] -CONFIG_KERNEL_MCS = [ - "sel4-sys/CONFIG_KERNEL_MCS", -] -CONFIG_PRINTING = [ - "sel4-sys/CONFIG_PRINTING", -] -CONFIG_SMP_SUPPORT = [ - "sel4-sys/CONFIG_SMP_SUPPORT", -] -CONFIG_VTX = [ - "sel4-sys/CONFIG_VTX", -] - [dependencies] sel4-sys = { path = "src/sel4-sys" } diff --git a/apps/system/components/kata-os-common/src/sel4-config/Cargo.toml b/apps/system/components/kata-os-common/src/sel4-config/Cargo.toml new file mode 100644 index 0000000..34c06d7 --- /dev/null +++ b/apps/system/components/kata-os-common/src/sel4-config/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "sel4-config" +version = "0.1.0" +edition = "2018" +description = "build glue for seL4 kernel configuration" + +[lib] +path = "src/lib.rs" + +[dependencies] +cargo_toml = "0.10.2" diff --git a/apps/system/components/kata-os-common/src/sel4-config/src/lib.rs b/apps/system/components/kata-os-common/src/sel4-config/src/lib.rs new file mode 100644 index 0000000..8e8efc4 --- /dev/null +++ b/apps/system/components/kata-os-common/src/sel4-config/src/lib.rs @@ -0,0 +1,46 @@ +// Cargo/rust build glue to import seL4 kernel configuration. We +// parse the gen_config.h file from a build area to find features +// needed by a dependent crate (sel4-sys, kata-os-rootserver, etc). +// +// The caller is responsible for supplying a pathname to the top +// of the kernel build area. Typically this comes from the +// SEL4_OUT_DIR environment variable. + +use std::collections::BTreeSet; +use std::env; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::PathBuf; +use std::string::String; +use std::vec::Vec; + +pub fn get_sel4_features(sel4_out_dir: &str) -> Vec { + // Parse the kernel's gen_config.h file to get features. + let gen_config_file = + File::open(format!("{}/gen_config/kernel/gen_config.h", sel4_out_dir)).unwrap(); + let kernel_config_features = BufReader::new(gen_config_file) + .lines() + .filter_map(|line| { + let line = line.unwrap(); + let mut splitted = line.split_whitespace(); + match (splitted.next()?, splitted.next()?) { + ("#define", param) => Some(param.to_owned()), + _ => None, + } + }) + .collect::>(); + println!("kernel_config_features {:?}", kernel_config_features); + + // Return only features specified in the Cargo.toml. + let manifest_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("Cargo.toml"); + let manifest = cargo_toml::Manifest::from_path(manifest_path).unwrap(); + manifest + .features + .into_keys() + .collect::>() + .intersection(&kernel_config_features) + .cloned() + .collect::>() +} + +// TODO(sleffler): unit tests diff --git a/apps/system/components/kata-os-common/src/sel4-sys/Cargo.toml b/apps/system/components/kata-os-common/src/sel4-sys/Cargo.toml index 5f14814..80e26fc 100644 --- a/apps/system/components/kata-os-common/src/sel4-sys/Cargo.toml +++ b/apps/system/components/kata-os-common/src/sel4-sys/Cargo.toml @@ -17,23 +17,28 @@ readme = "README.md" license = "MIT/Apache-2.0" build = "build.rs" +# NB: the sel4-config crate tries to sync features to a kernel build by +# parsing build artifacts (see the crate). +[build-dependencies] +sel4-config = { path = "../sel4-config" } + # NB: used by build.rs -[env] +[build-env] # Name of python3 interpreter executable, defaults to "python3" PYTHON = "python3" +# Pathname to seL4 kernel source +SEL4_DIR = "${ROOTDIR}kata/kernel" + +# Pathname to seL4 kernel build artifacts (used by sel4-config) +SEL4_OUT_DIR = "${ROOTDIR}out/kata/kernel" + # Beware CONFIG_KERNEL_MCS & CONFIG_SMP_SUPPORT must match the kernel # config for syscall numbering (aka invocation labeling) to line up. # Other syscalls api's are generated only when the associated config # knobs are set but do not affect the syscall ABI (e.g. CONFIG_PRINTING). [features] -default = [ -# "CONFIG_KERNEL_MCS", - "CONFIG_PRINTING", - "CONFIG_DEBUG_BUILD", - "CONFIG_SET_TLS_BASE_SELF", -] -# Changes api, blech +default = [] CONFIG_KERNEL_MCS = [] CONFIG_PRINTING = [] CONFIG_DEBUG_BUILD = [] @@ -44,12 +49,9 @@ CONFIG_BENCHMARK_TRACK_UTILISATION = [] # TCBSetBreakpoint, TCBUnsetBreakpoint, TCBSetTLSBase CONFIG_HARDWARE_DEBUG_API = [] CONFIG_SET_TLS_BASE_SELF = [] -# note: if you're looking at these, be aware that hypervisor support is not -# yet available at all. these features shouldn't be enabled. CONFIG_VTX = [] CONFIG_ARM_SMMU = [] CONFIG_ARM_HYPERVISOR_SUPPORT = [] -unstable = [] # XXX? [lib] path = "lib.rs" diff --git a/apps/system/components/kata-os-common/src/sel4-sys/build.rs b/apps/system/components/kata-os-common/src/sel4-sys/build.rs index 815d82c..ab178a5 100644 --- a/apps/system/components/kata-os-common/src/sel4-sys/build.rs +++ b/apps/system/components/kata-os-common/src/sel4-sys/build.rs @@ -27,7 +27,29 @@ fn main() { // Default to "seL4" for backwards compat; can either use git submodule or // symbolic link (neither recommended) - let sel4_dir = env::var("SEL4_DIR").unwrap_or_else(|_| "seL4".to_string()); + let sel4_dir = env::var("SEL4_DIR").unwrap_or_else( + |_| format!("{}/kata/kernel", env::var("ROOTDIR").unwrap()) + ); + println!("sel4_dir {}", sel4_dir); + + // If SEL4_OUT_DIR is not set we expect the kernel build at a fixed + // location relative to the ROOTDIR env variable. + println!("SEL4_OUT_DIR {:?}", env::var("SEL4_OUT_DIR")); + let sel4_out_dir = env::var("SEL4_OUT_DIR").unwrap_or_else( + |_| format!("{}/out/kata/kernel", env::var("ROOTDIR").unwrap()) + ); + println!("sel4_out_dir {}", sel4_out_dir); + + // Dredge seL4 kerenl config for settings we need as features to generate + // correct code: e.g. CONFIG_KERNEL_MCS enables MCS support which changes + // the system call numbering. + let features = sel4_config::get_sel4_features(&sel4_out_dir); + println!("features = {:?}", features); + let mut has_mcs = false; + for feature in features { + println!("cargo:rustc-cfg=feature=\"{}\"", feature); + if feature.as_str() == "CONFIG_KERNEL_MCS" { has_mcs = true; } + } // Use CARGO_TARGET_ARCH and CARGO_TARGET_POINTER_WIDTH // to select the target architecture; @@ -59,25 +81,25 @@ fn main() { "{}/libsel4/sel4_arch_include/{}/interfaces/sel4arch.xml", sel4_dir, arch ); - let args = vec![ - "tools/syscall_stub_gen.py", + + let mut cmd = Command::new("/usr/bin/env"); + cmd.arg(&python_bin) + .arg("tools/syscall_stub_gen.py"); + if has_mcs { + cmd.arg("--mcs"); + } + cmd.args(&[ "-a", arch, "-w", cargo_target_pointer_width.as_str(), "--buffer", - #[cfg(feature = "CONFIG_KERNEL_MCS")] - "--mcs", "-o", &*outfile, &*xml_interfaces_file, &*xml_arch_file, &*xml_sel4_arch_file, - ]; - - let mut cmd = Command::new("/usr/bin/env"); - cmd.arg(&python_bin).args(&args); - + ]); println!("Running: {:?}", cmd); assert!(cmd.status().unwrap().success()); @@ -91,27 +113,30 @@ fn main() { sel4_dir, arch ); let mut cmd = Command::new("/usr/bin/env"); - cmd.arg(&python_bin).args(&[ - "tools/invocation_header_gen.py", - "--dest", - &*format!("{}/{}_invocation.rs", out_dir, arch), - &*xml_interfaces_file, - &*xml_arch_file, - &*xml_sel4_arch_file, - ]); + cmd.arg(&python_bin) + .args(&[ + "tools/invocation_header_gen.py", + "--dest", + &*format!("{}/{}_invocation.rs", out_dir, arch), + &*xml_interfaces_file, + &*xml_arch_file, + &*xml_sel4_arch_file, + ]); println!("Running {:?}", cmd); assert!(cmd.status().unwrap().success()); // TODO(sleffler): requires pip install tempita let mut cmd = Command::new("/usr/bin/env"); - cmd.arg(&python_bin).args(&[ - "tools/syscall_header_gen.py", - #[cfg(feature = "CONFIG_KERNEL_MCS")] - "--mcs", - "--xml", - &*format!("{}/libsel4/include/api/syscall.xml", sel4_dir), - "--dest", - &*format!("{}/syscalls.rs", out_dir), + cmd.arg(&python_bin) + .arg("tools/syscall_header_gen.py"); + if has_mcs { + cmd.arg("--mcs"); + } + cmd.args(&[ + "--xml", + &*format!("{}/libsel4/include/api/syscall.xml", sel4_dir), + "--dest", + &*format!("{}/syscalls.rs", out_dir), ]); println!("Running {:?}", cmd); assert!(cmd.status().unwrap().success()); @@ -128,12 +153,14 @@ fn main() { )) .unwrap(); let mut cmd = Command::new("/usr/bin/env"); - cmd.arg(&python_bin) - .arg("tools/bitfield_gen.py") - .arg("--language=rust") - // .arg("--word-size=32") - .stdin(unsafe { Stdio::from_raw_fd(bfin.as_raw_fd()) }) - .stdout(unsafe { Stdio::from_raw_fd(bfout.as_raw_fd()) }); + cmd.args(&[ + &python_bin, + "tools/bitfield_gen.py", + "--language=rust", + // "--word-size=32" + ]) + .stdin(unsafe { Stdio::from_raw_fd(bfin.as_raw_fd()) }) + .stdout(unsafe { Stdio::from_raw_fd(bfout.as_raw_fd()) }); println!("Running {:?}", cmd); assert!(cmd.status().unwrap().success()); std::mem::forget(bfin);