diff --git a/src/kernel/src/initrd.rs b/src/kernel/src/initrd.rs index 2f74299c..e1543779 100644 --- a/src/kernel/src/initrd.rs +++ b/src/kernel/src/initrd.rs @@ -59,7 +59,7 @@ pub fn init(modules: &[BootModule]) { } let obj = Arc::new(obj); obj::register_object(obj.clone()); - if e.filename().as_str() == "bootstrap" { + if e.filename().as_str() == "init" { boot_objects.init = Some(obj.clone()); } boot_objects diff --git a/src/runtime/monitor/src/lib.rs b/src/runtime/monitor/src/lib.rs index bc218f6d..f5bda84b 100644 --- a/src/runtime/monitor/src/lib.rs +++ b/src/runtime/monitor/src/lib.rs @@ -17,10 +17,7 @@ use twz_rt::{set_upcall_handler, OUR_RUNTIME}; mod compartment; mod init; mod object; -//mod runtime; pub mod secgate_test; -//mod state; -//mod thread; mod upcall; mod api; @@ -72,18 +69,6 @@ pub fn main() { fn monitor_init() -> miette::Result<()> { info!("monitor early init completed, starting init"); - let cur = monitor_api::CompartmentHandle::current(); - let info = cur.info(); - info!("current compartment info: {:?}", info); - - for lib in cur.libs() { - info!("lh: {:?}", lib); - let info = lib.info(); - info!("library: {:?}", info); - } - - panic!("test panic"); - Ok(()) } diff --git a/src/runtime/monitor/src/mon/compartment/runcomp.rs b/src/runtime/monitor/src/mon/compartment/runcomp.rs index b326145b..4216b1ce 100644 --- a/src/runtime/monitor/src/mon/compartment/runcomp.rs +++ b/src/runtime/monitor/src/mon/compartment/runcomp.rs @@ -47,32 +47,43 @@ pub struct RunComp { per_thread: HashMap, } +/// Per-thread data in a compartment. pub struct PerThread { - simple_buffer: (SimpleBuffer, MapHandle), + simple_buffer: Option<(SimpleBuffer, MapHandle)>, } impl PerThread { + /// Create a new PerThread. Note that this must succeed, so any allocation failures must be + /// handled gracefully. This means that if the thread fails to allocate a simple buffer, it + /// will just forego having one. This may cause a failure down the line, but it's the best we + /// can do without panicing. fn new(instance: ObjID, th: ObjID, space: &mut Space) -> Self { - // TODO: unwrap let handle = space .safe_create_and_map_runtime_object(instance, MapFlags::READ | MapFlags::WRITE) - .unwrap(); + .ok(); Self { - simple_buffer: (SimpleBuffer::new(unsafe { handle.object_handle() }), handle), + simple_buffer: handle + .map(|handle| (SimpleBuffer::new(unsafe { handle.object_handle() }), handle)), } } + /// Write bytes into this compartment-thread's simple buffer. pub fn write_bytes(&mut self, bytes: &[u8]) -> usize { - self.simple_buffer.0.write(bytes) + self.simple_buffer + .as_mut() + .map(|sb| sb.0.write(bytes)) + .unwrap_or(0) } - pub fn simple_buffer_id(&self) -> ObjID { - self.simple_buffer.0.handle().id + /// Get the Object ID of this compartment thread's simple buffer. + pub fn simple_buffer_id(&self) -> Option { + Some(self.simple_buffer.as_ref()?.0.handle().id) } } impl RunComp { + /// Build a new runtime compartment. pub fn new( sctx: ObjID, instance: ObjID, diff --git a/src/runtime/monitor/src/mon/mod.rs b/src/runtime/monitor/src/mon/mod.rs index be39799d..74b455c4 100644 --- a/src/runtime/monitor/src/mon/mod.rs +++ b/src/runtime/monitor/src/mon/mod.rs @@ -185,7 +185,7 @@ impl Monitor { let (ref mut space, _, ref mut comps, _, _, _) = *locks; let rc = comps.get_mut(sctx)?; let pt = rc.get_per_thread(thread, &mut *space); - Some(pt.simple_buffer_id()) + pt.simple_buffer_id() } } diff --git a/src/runtime/monitor/src/runtime.rs b/src/runtime/monitor/src/runtime.rs deleted file mode 100644 index b0772984..00000000 --- a/src/runtime/monitor/src/runtime.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::sync::{Arc, Mutex, OnceLock}; - -use twizzler_runtime_api::{AddrRange, DlPhdrInfo, Library, LibraryId}; - -use crate::state::MonitorState; - -/* -#[no_mangle] -pub fn __do_get_monitor_actions() -> &'static dyn MonitorActions { - ACTIONS.get().unwrap() -} - -struct MonitorActionsImpl { - state: Arc>, -} - -pub(crate) fn init_actions(state: Arc>) { - let _ = ACTIONS.set(MonitorActionsImpl { state }); -} - -impl MonitorActions for MonitorActionsImpl { - fn lookup_library_by_id( - &self, - id: twizzler_runtime_api::LibraryId, - ) -> Option { - let state = self.state.lock().unwrap(); - let lib = state.get_nth_library(id.0)?; - let next_id = LibraryId(id.0 + 1); - let phdrs = lib.get_phdrs_raw()?; - - Some(Library { - mapping: lib.full_obj.clone().to_inner(), - range: (lib.full_obj.data().0, unsafe { - lib.full_obj.data().0.add(lib.full_obj.data().1) - }), - dl_info: Some(DlPhdrInfo { - addr: lib.base_addr(), - name: core::ptr::null(), - phdr_start: phdrs.0 as *const _, - phdr_num: phdrs.1.try_into().ok()?, - _adds: 0, - _subs: 0, - modid: lib - .tls_id - .map(|t| t.tls_id()) - .unwrap_or(0) - .try_into() - .ok()?, - tls_data: core::ptr::null(), - }), - next_id: state.get_nth_library(next_id.0).map(|_| next_id), - id, - }) - } - - fn local_primary(&self) -> Option { - Some(LibraryId(0)) - } - - fn lookup_library_name(&self, id: LibraryId, buf: &mut [u8]) -> Option { - let state = self.state.lock().unwrap(); - let lib = state.get_nth_library(id.0)?; - if buf.len() < lib.name.len() { - return None; - } - buf[0..lib.name.len()].copy_from_slice(lib.name.as_bytes()); - Some(lib.name.len()) - } - - fn get_segment(&self, id: LibraryId, seg: usize) -> Option { - const PT_LOAD: u32 = 1; - let state = self.state.lock().unwrap(); - let lib = state.get_nth_library(id.0)?; - let phdrs = lib.get_phdrs_raw()?; - let slice = unsafe { core::slice::from_raw_parts(phdrs.0, phdrs.1) }; - let phdr = slice.iter().filter(|p| p.p_type == PT_LOAD).nth(seg)?; - Some(AddrRange { - start: lib.laddr::(phdr.p_vaddr) as usize, - len: phdr.p_memsz as usize, - }) - } -} - -static ACTIONS: OnceLock = OnceLock::new(); -*/ diff --git a/src/runtime/monitor/src/state.rs b/src/runtime/monitor/src/state.rs deleted file mode 100644 index 3021b20f..00000000 --- a/src/runtime/monitor/src/state.rs +++ /dev/null @@ -1,155 +0,0 @@ -use std::{ - collections::HashMap, - sync::{Arc, Mutex, OnceLock}, -}; - -use dynlink::{ - compartment::{Compartment, MONITOR_COMPARTMENT_ID}, - context::Context, - engines::{Backing, ContextEngine}, - library::UnloadedLibrary, - DynlinkError, DynlinkErrorKind, -}; -use secgate::GateCallInfo; -use twizzler_abi::object::{MAX_SIZE, NULLPAGE_SIZE}; -use twizzler_object::ObjID; -use twizzler_runtime_api::{LibraryId, MapFlags}; - -use crate::{bootstrap_name_res, compartment::Comp, gates::LibraryInfo, init::InitDynlinkContext}; - -pub struct MonitorState { - pub dynlink: &'static mut Context, - pub(crate) root: String, - - pub comps: HashMap, -} - -struct Engine; - -impl ContextEngine for Engine { - fn load_segments( - &mut self, - src: &Backing, - ld: &[dynlink::engines::LoadDirective], - ) -> Result, dynlink::DynlinkError> { - dynlink::engines::twizzler::load_segments(src, ld) - } - - fn load_object(&mut self, unlib: &UnloadedLibrary) -> Result { - bootstrap_name_res(&unlib.name).ok_or(DynlinkErrorKind::NewBackingFail.into()) - } - - fn select_compartment( - &mut self, - _unlib: &UnloadedLibrary, - ) -> Option { - todo!() - } -} - -impl MonitorState { - pub(crate) fn new(init: InitDynlinkContext) -> Self { - let this = Self { - dynlink: unsafe { init.ctx.as_mut().unwrap() }, - root: init.root, - comps: Default::default(), - }; - this.dynlink.replace_engine(Box::new(Engine)); - this - } - - pub(crate) fn get_monitor_compartment_mut(&mut self) -> &mut Compartment { - let mid = self.dynlink.lookup_compartment("monitor").unwrap(); - self.dynlink.get_compartment_mut(mid).unwrap() - } - - pub(crate) fn get_nth_library(&self, n: usize) -> Option<&dynlink::library::Library> { - // TODO: this sucks. - let mut all = vec![]; - // TODO - let comp_id = self.dynlink.lookup_compartment("monitor")?; - let root_id = self.dynlink.lookup_library(comp_id, &self.root)?; - self.dynlink - .with_bfs(root_id, |lib| all.push(lib.name().to_string())); - let lib = all - .get(n) - // TODO - .and_then(|x| self.dynlink.lookup_library(comp_id, x))?; - - self.dynlink.get_library(lib).ok() - } - - pub(crate) fn add_comp(&mut self, mut comp: Comp, root_id: LibraryId) { - comp.set_root_id(root_id); - self.comps.insert(comp.sctx_id, comp); - } - - pub(crate) fn lookup_comp(&self, sctx: ObjID) -> Option<&Comp> { - self.comps.get(&sctx) - } - - pub(crate) fn lookup_comp_mut(&mut self, sctx: ObjID) -> Option<&mut Comp> { - self.comps.get_mut(&sctx) - } -} - -static MONITOR_STATE: OnceLock>> = OnceLock::new(); - -pub(crate) fn set_monitor_state(state: Arc>) { - MONITOR_STATE - .set(state) - .unwrap_or_else(|_| panic!("monitor state already set")) -} - -pub(crate) fn get_monitor_state() -> &'static Arc> { - MONITOR_STATE - .get() - .unwrap_or_else(|| panic!("failed to get monitor state")) -} - -pub(crate) fn try_get_monitor_state() -> Option<&'static Arc>> { - MONITOR_STATE.get() -} - -pub fn __monitor_rt_get_library_info(info: &GateCallInfo, id: LibraryId) -> Option { - let state = get_monitor_state().lock().unwrap(); - let lib = state.dynlink.get_library(id.into()).ok()?; - let comp = state.lookup_comp(info.source_context().unwrap_or(0.into()))?; - - let compartment = state.dynlink.get_compartment(lib.compartment()).ok()?; - if compartment.id != comp.compartment_id { - //return None; - } - - let handle = lib.full_obj.object(); - - let next_lib = state - .dynlink - .libraries() - .skip_while(|l| lib.id() != l.id()) - .skip(1) - .skip_while(|l| l.compartment() != lib.compartment()) - .next(); - - Some(LibraryInfo { - objid: handle.id, - slot: handle.start as usize / MAX_SIZE, - range: twizzler_runtime_api::AddrRange { - start: handle.start as usize + NULLPAGE_SIZE, - len: MAX_SIZE - NULLPAGE_SIZE, - }, - dl_info: twizzler_runtime_api::DlPhdrInfo { - addr: lib.base_addr(), - name: core::ptr::null(), - phdr_start: lib.get_phdrs_raw()?.0 as *const _, - phdr_num: lib.get_phdrs_raw()?.1 as u32, - _adds: 0, - _subs: 0, - modid: lib.tls_id.map(|t| t.tls_id()).unwrap_or(0) as usize, - tls_data: core::ptr::null(), - }, - id, - name_len: todo!(), - compartment_id: todo!(), - }) -} diff --git a/src/runtime/monitor/src/thread.rs b/src/runtime/monitor/src/thread.rs deleted file mode 100644 index 8e83b2b0..00000000 --- a/src/runtime/monitor/src/thread.rs +++ /dev/null @@ -1,111 +0,0 @@ -use std::{collections::HashMap, mem::MaybeUninit, ptr::NonNull, sync::Mutex}; - -use monitor_api::SharedCompConfig; -use tracing::debug; -use twizzler_abi::{ - syscall::{sys_spawn, UpcallTargetSpawnOption}, - upcall::{UpcallFlags, UpcallInfo, UpcallMode, UpcallOptions, UpcallTarget}, -}; -use twizzler_object::ObjID; -use twizzler_runtime_api::{SpawnError, ThreadSpawnArgs}; -use twz_rt::RuntimeThreadControl; - -use crate::state::get_monitor_state; - -pub const SUPER_UPCALL_STACK_SIZE: usize = 8 * 1024 * 1024; // 8MB - -fn spawn_thread( - src_ctx: ObjID, - args: ThreadSpawnArgs, - thread_pointer: usize, - stack_pointer: usize, -) -> Result { - // Allocate a new stack for super entry for upcalls. - let super_stack = Box::<[u8]>::new_zeroed_slice(SUPER_UPCALL_STACK_SIZE); - - let mut state = get_monitor_state().lock().unwrap(); - let mon_comp = state.get_monitor_compartment_mut(); - let tls = mon_comp - .build_tls_region(RuntimeThreadControl::default(), |layout| unsafe { - NonNull::new(std::alloc::alloc_zeroed(layout)) - }) - .map_err(|_| SpawnError::Other)?; - - let upcall_target = UpcallTarget::new( - None, - Some(twz_rt::rr_upcall_entry), - super_stack.as_ptr() as usize, - SUPER_UPCALL_STACK_SIZE, - tls.get_thread_pointer_value(), - 0.into(), - [UpcallOptions { - flags: UpcallFlags::empty(), - mode: UpcallMode::CallSuper, - }; UpcallInfo::NR_UPCALLS], - ); - - let comp = state.comps.get(&src_ctx).unwrap(); - // Lock before spawn so we guarantee we can fill out the manager entry before the thread can - // look there. - let mut mgr = THREAD_MGR.lock().map_err(|_| SpawnError::Other)?; - let thid = unsafe { - sys_spawn(twizzler_abi::syscall::ThreadSpawnArgs { - entry: args.start, - stack_base: stack_pointer, - stack_size: args.stack_size, - tls: thread_pointer, - arg: args.arg, - flags: twizzler_abi::syscall::ThreadSpawnFlags::empty(), - vm_context_handle: None, - upcall_target: UpcallTargetSpawnOption::SetTo(upcall_target), - }) - } - .map_err(|_| SpawnError::KernelError)?; - - mgr.all.insert(thid, ManagedThread::new(thid, super_stack)); - - debug!("spawned thread {} in compartment {}", thid, comp); - - Ok(thid) -} - -// Extern function, linked to by the runtime. -#[no_mangle] -pub fn __monitor_rt_spawn_thread( - src_ctx: ObjID, - args: ThreadSpawnArgs, - thread_pointer: usize, - stack_pointer: usize, -) -> Result { - spawn_thread(src_ctx, args, thread_pointer, stack_pointer) -} - -// Extern function, linked to by the runtime. -#[no_mangle] -pub fn __monitor_rt_get_comp_config(src_ctx: ObjID) -> *const SharedCompConfig { - println!("got monitor comp config"); - let state = get_monitor_state().lock().unwrap(); - let comp = state.comps.get(&src_ctx).unwrap(); - comp.get_comp_config() -} - -#[allow(dead_code)] -struct ManagedThread { - id: ObjID, - super_stack: Box<[MaybeUninit]>, -} - -impl ManagedThread { - fn new(id: ObjID, super_stack: Box<[MaybeUninit]>) -> Self { - Self { id, super_stack } - } -} - -#[derive(Default)] -struct ThreadManager { - all: HashMap, -} - -lazy_static::lazy_static! { -static ref THREAD_MGR: Mutex = Mutex::new(ThreadManager::default()); -}