Skip to content

Commit

Permalink
Cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
dbittman committed Nov 29, 2024
1 parent d54d4c2 commit dfbfa18
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 36 deletions.
1 change: 0 additions & 1 deletion src/bin/bootstrap/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ fn start_runtime(_runtime_monitor: ObjID, _runtime_library: ObjID) -> ! {
.add_compartment("monitor", NewCompartmentFlags::EXPORT_GATES)
.unwrap();

info!("==> {}", monitor_comp_id);
let monitor_id = ctx
.load_library_in_compartment(monitor_comp_id, unlib, true)
.unwrap()[0]
Expand Down
11 changes: 11 additions & 0 deletions src/runtime/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# runtime subdirectory

This subdirectory contains all the crates for the core runtime:

- dynlink: the dynamic linker code
- minruntime: the minimal (no_std, static linking available) runtime
- monitor: the monitor implementation
- monitor-api: the API crate for interaction with the monitor from runtime or user programs
- rt: reference runtime wrapper crate
- rt-impl: the reference runtime implementation. Users should link against the wrapper crate (rt), not this one.
- secgate: secure gate types and utility functions
22 changes: 19 additions & 3 deletions src/runtime/monitor-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,14 @@ impl CompartmentHandle {
pub fn libs(&self) -> LibraryIter<'_> {
LibraryIter::new(self)
}

pub fn wait(&self, flags: CompartmentFlags) -> CompartmentFlags {
CompartmentFlags::from_bits_truncate(
gates::monitor_rt_compartment_wait(self.desc(), flags.bits())
.ok()
.unwrap_or(0),
)
}
}

/// An iterator over libraries in a compartment.
Expand Down Expand Up @@ -534,10 +542,18 @@ bitflags::bitflags! {
/// Compartment state flags.
#[derive(Clone, Debug, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct CompartmentFlags : u64 {
/// Compartment is ready (libraries relocated and constructors run).
/// Compartment is ready (loaded, reloacated, runtime started and ctors run).
const READY = 0x1;
/// The main thread has exited.
const EXITED = 0x2;
/// Compartment is a binary, not a library.
const IS_BINARY = 0x2;
/// Compartment runtime thread may exit.
const THREAD_CAN_EXIT = 0x4;
/// Compartment thread has been started once.
const STARTED = 0x8;
/// Compartment destructors have run.
const DESTRUCTED = 0x10;
/// Compartment thread has exited.
const EXITED = 0x20;
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/runtime/monitor/secapi/gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,21 @@ impl Display for LoadCompartmentError {
}
}

#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_compartment_wait(
info: &secgate::GateCallInfo,
desc: Option<Descriptor>,
flags: u64,
) -> u64 {
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.compartment_wait(caller, desc, flags)
}

#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
Expand Down
29 changes: 11 additions & 18 deletions src/runtime/monitor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,53 +75,46 @@ pub fn main() {
}

fn monitor_init() -> miette::Result<()> {
// If we have monitor tests to run, do so.
if let Some(ki_name) = dlengine::get_kernel_init_info()
.names()
.iter()
.find(|iname| iname.name() == "monitor_test_info")
{
info!("starting monitor tests [{}]", ki_name.name());
// Read the monitor test binary name.
const MAX_NAMELEN: usize = 0x1000;
let info =
twizzler_rt_abi::object::twz_rt_map_object(ki_name.id(), MapFlags::READ).unwrap();
let test_name_slice =
unsafe { core::slice::from_raw_parts(info.start().add(NULLPAGE_SIZE), 0x1000) };
unsafe { core::slice::from_raw_parts(info.start().add(NULLPAGE_SIZE), MAX_NAMELEN) };
let first_null = test_name_slice
.iter()
.position(|x| *x == 0)
.unwrap_or(0x1000 - 1);
.unwrap_or(MAX_NAMELEN - 1);
let test_name = String::from_utf8_lossy(&test_name_slice[0..first_null]);
info!("monitor test binary: {}", test_name);
debug!("monitor test binary: {}", test_name);
if let Some(_ki_name) = dlengine::get_kernel_init_info()
.names()
.iter()
.find(|iname| iname.name() == test_name)
{
// Load and wait for tests to complete
let comp: CompartmentHandle =
CompartmentLoader::new("montest", test_name, NewCompartmentFlags::empty())
.args(&["montest"])
.load()
.into_diagnostic()?;
let mut eb = 0;
let delay_exp_backoff = |state: &mut u64| {
let val = *state;
if val < 1000 {
if val == 0 {
*state = 1;
} else {
*state *= 2;
}
}
tracing::info!("sleep: {}", val);
std::thread::sleep(Duration::from_millis(val));
};
while !comp.info().flags.contains(CompartmentFlags::EXITED) {
delay_exp_backoff(&mut eb);
let mut flags = comp.info().flags;
while !flags.contains(CompartmentFlags::EXITED) {
flags = comp.wait(flags);
}
} else {
tracing::error!("failed to start monitor tests: {}", ki_name.name());
}
}
info!("monitor early init completed, starting init");
// TODO: start init...

Ok(())
}
15 changes: 14 additions & 1 deletion src/runtime/monitor/src/mon/compartment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,20 @@ impl super::Monitor {
)
}

pub fn compartment_wait(&self, caller: ObjID, desc: Option<Descriptor>, flags: u64) -> u64 {
let Some(instance) = ({
let comphandles = self._compartment_handles.write(ThreadKey::get().unwrap());
let comp_id = desc
.map(|comp| comphandles.lookup(caller, comp).map(|ch| ch.instance))
.unwrap_or(Some(caller));
comp_id
}) else {
return 0;
};
self.wait_for_compartment_state_change(instance, flags);
self.load_compartment_flags(instance)
}

/// Open a handle to the n'th dependency compartment of a given compartment.
pub fn get_compartment_deps(
&self,
Expand Down Expand Up @@ -287,7 +301,6 @@ impl super::Monitor {
let compname = split.next().ok_or(LoadCompartmentError::Unknown)?;
let libname = split.next().ok_or(LoadCompartmentError::Unknown)?;
let root = UnloadedLibrary::new(libname);
tracing::info!("A");

// parse args
let args_bytes = arg_bytes.split_inclusive(|b| *b == 0);
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/monitor/src/mon/compartment/loader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{borrow::Cow, collections::HashSet, ffi::CStr, ptr::null_mut};
use std::{collections::HashSet, ffi::CStr, ptr::null_mut};

use dynlink::{
compartment::CompartmentId,
Expand Down
15 changes: 7 additions & 8 deletions src/runtime/monitor/src/mon/compartment/runcomp.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::{
alloc::Layout,
borrow::Cow,
collections::HashMap,
ffi::{CStr, CString},
ptr::NonNull,
sync::atomic::{AtomicU64, Ordering},
};

use dynlink::{compartment::CompartmentId, context::Context};
use monitor_api::{RuntimeThreadControl, SharedCompConfig, TlsTemplateInfo};
use monitor_api::{CompartmentFlags, RuntimeThreadControl, SharedCompConfig, TlsTemplateInfo};
use secgate::util::SimpleBuffer;
use talc::{ErrOnOom, Talc};
use twizzler_abi::syscall::{
Expand All @@ -26,17 +25,17 @@ use crate::mon::{
};

/// Compartment is ready (loaded, reloacated, runtime started and ctors run).
pub const COMP_READY: u64 = 0x1;
pub const COMP_READY: u64 = CompartmentFlags::READY.bits();
/// Compartment is a binary, not a library.
pub const COMP_IS_BINARY: u64 = 0x2;
pub const COMP_IS_BINARY: u64 = CompartmentFlags::IS_BINARY.bits();
/// Compartment runtime thread may exit.
pub const COMP_THREAD_CAN_EXIT: u64 = 0x4;
pub const COMP_THREAD_CAN_EXIT: u64 = CompartmentFlags::THREAD_CAN_EXIT.bits();
/// Compartment thread has been started once.
pub const COMP_STARTED: u64 = 0x8;
pub const COMP_STARTED: u64 = CompartmentFlags::STARTED.bits();
/// Compartment destructors have run.
pub const COMP_DESTRUCTED: u64 = 0x10;
pub const COMP_DESTRUCTED: u64 = CompartmentFlags::DESTRUCTED.bits();
/// Compartment thread has exited.
pub const COMP_EXITED: u64 = 0x20;
pub const COMP_EXITED: u64 = CompartmentFlags::EXITED.bits();

/// A runnable or running compartment.
pub struct RunComp {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/monitor/src/mon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ impl Monitor {
cmd: MonitorCompControlCmd,
) -> Option<i32> {
let src = info.source_context()?;
tracing::trace!(
tracing::debug!(
"compartment ctrl from: {:?}, thread = {:?}: {:?}",
src,
info.thread_id(),
Expand Down
1 change: 0 additions & 1 deletion src/runtime/monitor/tests/montest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ extern crate twizzler_runtime;
mod montest_lib {
#[link(name = "montest_lib")]
extern "C" {}
use secgate::GateCallInfo;
#[secgate::secure_gate(options(info, api))]
pub fn test_was_ctor_run(info: &GateCallInfo) -> bool {}

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/rt-impl/src/runtime/thread/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl Drop for InternalThread {
// Args is allocated by a box.
let _args = Box::from_raw(self.args_box as *mut ThreadSpawnArgs);
drop(_args);
tracing::warn!("TODO: drop TLS");
tracing::debug!("TODO: drop TLS");
}
}
}
2 changes: 2 additions & 0 deletions tools/xtask/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ fn maybe_build_tests_static<'a>(
Ok(Some(cargo::ops::compile(workspace, &options)?))
}

// Once we merge the runtimes fully and switch to using the dynamic runtime as default,
// we can merge a lot of this test infrastructure.
fn maybe_build_tests_dynamic<'a>(
workspace: &'a Workspace,
build_config: &crate::BuildConfig,
Expand Down
3 changes: 3 additions & 0 deletions tools/xtask/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ fn build_initrd(cli: &ImageOptions, comp: &TwizzlerCompilation) -> anyhow::Resul
}
}

// all the tests for init to run.
if let Some(ref test_comp) = comp.borrow_static_test_compilation() {
let mut testlist = String::new();
for bin in test_comp.tests.iter() {
Expand All @@ -206,6 +207,8 @@ fn build_initrd(cli: &ImageOptions, comp: &TwizzlerCompilation) -> anyhow::Resul
assert!(!cli.tests && !cli.benches);
}

// all the tests for the monitor to run. Eventually this and the above will merge into
// one thing, but that will have to wait until the dynamic runtime is default.
if let Some(ref test_comp) = comp.borrow_user_test_compilation() {
let mut testlist = String::new();
for bin in test_comp.tests.iter() {
Expand Down
2 changes: 1 addition & 1 deletion tools/xtask/src/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ pub(crate) fn do_bootstrap(cli: BootstrapOptions) -> anyhow::Result<()> {
pub fn set_dynamic() {
std::env::set_var(
"RUSTFLAGS",
"-C prefer-dynamic=y -Z staticlib-prefer-dynamic=y -C link-arg=--allow-shlib-undefined -Z macro-backtrace",
"-C prefer-dynamic=y -Z staticlib-prefer-dynamic=y -C link-arg=--allow-shlib-undefined",
);
std::env::set_var("CARGO_TARGET_DIR", "target/dynamic");
}
Expand Down

0 comments on commit dfbfa18

Please sign in to comment.