mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-07-31 05:30:34 +00:00
Add kata-os-common::camkes support.
Add a new "camkes" submodule that consolidates KataOS CAmkES component integration boilerplate. Each component is expected to declare: static mut CAMKES: Camkes = Camkes::new("ProcessManager"); and then (typically) use "pre_init" to setup the logger, heap, and the slot allocator. More fine-grained control is provided by: fn init_logger(self: &Cmakes, level: Log::LevelFilter); fn init_allocator(self: &Camkes, heap: &'static mut [u8]); fn init_slot_allocator(self: &Camkes, first_slot: seL4_CPtr, last_slot: seL4_CPtr); When receiving capabilities use "init_recv_path" to setup the IPCBuffer receive path and "assert_recv_path" & "check_recv_path" calls to verify noting has clobbered the setting. The debug_assert_slot_* macros are wrapped in Camkes:: functions and a "top_level_path" function for constructing seL4_CPath objects. Altogether this normally allows a component to be written without direct use of the CAmkES global static identifiers SELF_CNODE*. Change-Id: Ia1351e411a5355789cf74bc0fcfe0e41a418b7d4 GitOrigin-RevId: fb81a8e0687ed9321c9961410edd5dbd54093ce5
This commit is contained in:
parent
3bd8389a4c
commit
ddacc3762e
@ -12,51 +12,23 @@
|
||||
#![no_std]
|
||||
|
||||
use core::slice;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_os_common::slot_allocator;
|
||||
use log::trace;
|
||||
|
||||
use sel4_sys::seL4_CPtr;
|
||||
|
||||
use slot_allocator::KATA_CSPACE_SLOTS;
|
||||
use kata_os_common::camkes::Camkes;
|
||||
|
||||
extern "C" {
|
||||
static SELF_CNODE_FIRST_SLOT: seL4_CPtr;
|
||||
static SELF_CNODE_LAST_SLOT: seL4_CPtr;
|
||||
|
||||
static cpio_archive: *const u8; // CPIO archive of built-in files
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
// NB: set to Trace for early-boot msgs
|
||||
log::set_max_level(log::LevelFilter::Debug);
|
||||
static mut CAMKES: Camkes = Camkes::new("DebugConsole");
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
// TODO(b/200946906): Review per-component heap allocations, including this one.
|
||||
const HEAP_SIZE: usize = 1 << 20;
|
||||
static mut HEAP_MEMORY: [u8; HEAP_SIZE] = [0; HEAP_SIZE];
|
||||
unsafe {
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
HEAP_MEMORY.len()
|
||||
);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
KATA_CSPACE_SLOTS.init(
|
||||
/*first_slot=*/ SELF_CNODE_FIRST_SLOT,
|
||||
/*size=*/ SELF_CNODE_LAST_SLOT - SELF_CNODE_FIRST_SLOT
|
||||
);
|
||||
trace!("setup cspace slots: first slot {} free {}",
|
||||
KATA_CSPACE_SLOTS.base_slot(),
|
||||
KATA_CSPACE_SLOTS.free_slots());
|
||||
}
|
||||
CAMKES.pre_init(
|
||||
log::LevelFilter::Debug,
|
||||
&mut HEAP_MEMORY,
|
||||
);
|
||||
}
|
||||
|
||||
/// Entry point for DebugConsole. Runs the shell with UART IO.
|
||||
|
@ -6,56 +6,37 @@
|
||||
|
||||
use core::ops::Range;
|
||||
use core::slice;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::slot_allocator;
|
||||
use kata_memory_interface::MemoryManagerError;
|
||||
use kata_memory_interface::MemoryManagerInterface;
|
||||
use kata_memory_interface::ObjDescBundle;
|
||||
use kata_memory_interface::RawMemoryStatsData;
|
||||
use kata_memory_manager::KataMemoryManager;
|
||||
use kata_os_common::camkes::Camkes;
|
||||
use kata_os_common::sel4_sys;
|
||||
use log::{info, trace};
|
||||
|
||||
use slot_allocator::KATA_CSPACE_SLOTS;
|
||||
use log::trace;
|
||||
|
||||
use sel4_sys::seL4_BootInfo;
|
||||
use sel4_sys::seL4_CNode_Delete;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_GetCapReceivePath;
|
||||
use sel4_sys::seL4_SetCapReceivePath;
|
||||
use sel4_sys::seL4_Word;
|
||||
use sel4_sys::seL4_WordBits;
|
||||
|
||||
static mut CAMKES: Camkes = Camkes::new("MemoryManager");
|
||||
|
||||
// NB: KATA_MEMORY cannot be used before setup is completed with a call to init()
|
||||
static mut KATA_MEMORY: KataMemoryManager = KataMemoryManager::empty();
|
||||
|
||||
extern "C" {
|
||||
// Each CAmkES-generated CNode has a writable self-reference to itself in
|
||||
// the slot SELF_CNODE. This is used to pass CNode containers of dynamically
|
||||
// allocated objects between clients & the MemoryManager.
|
||||
static SELF_CNODE: seL4_CPtr;
|
||||
|
||||
// Each CAmkES-component has a CNode setup at a well-known slot in SELF_CNODE.
|
||||
// Each CAmkES-component has a CNode setup at a well-known top-level slot.
|
||||
// We re-use that slot to receive CNode caps passed with alloc & free requests.
|
||||
static MEMORY_RECV_CNODE: seL4_CPtr;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
// NB: set to max; the LoggerInterface will filter
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
CAMKES.init_logger(log::LevelFilter::Trace);
|
||||
|
||||
// TODO(sleffler): temp until we integrate with seL4
|
||||
static mut HEAP_MEMORY: [u8; 8 * 1024] = [0; 8 * 1024];
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
HEAP_MEMORY.len()
|
||||
);
|
||||
CAMKES.init_allocator(&mut HEAP_MEMORY);
|
||||
|
||||
extern "C" {
|
||||
fn sel4runtime_bootinfo() -> *const seL4_BootInfo;
|
||||
@ -77,18 +58,12 @@ pub unsafe extern "C" fn pre_init() {
|
||||
);
|
||||
}
|
||||
|
||||
KATA_CSPACE_SLOTS.init(
|
||||
/*first_slot=*/ bootinfo.empty.start,
|
||||
/*size=*/ bootinfo.empty.end - bootinfo.empty.start
|
||||
);
|
||||
trace!("setup cspace slots: first slot {} free {}",
|
||||
KATA_CSPACE_SLOTS.base_slot(),
|
||||
KATA_CSPACE_SLOTS.free_slots());
|
||||
CAMKES.init_slot_allocator(bootinfo.empty.start, bootinfo.empty.end);
|
||||
|
||||
// Delete the CAmkES-setup CNode; we're going to reuse the
|
||||
// well-known slot once it is empty (see memory__init below).
|
||||
seL4_CNode_Delete(SELF_CNODE, MEMORY_RECV_CNODE, seL4_WordBits as u8)
|
||||
.expect("recv_node");
|
||||
let path = Camkes::top_level_path(MEMORY_RECV_CNODE);
|
||||
seL4_CNode_Delete(path.0, path.1, path.2 as u8).expect("recv_node");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -100,30 +75,19 @@ pub unsafe extern "C" fn memory__init() {
|
||||
// NB: this must be done here (rather than someplace like pre_init)
|
||||
// so it's in the context of the MemoryInterface thread (so we write
|
||||
// the correct ipc buffer).
|
||||
seL4_SetCapReceivePath(SELF_CNODE, MEMORY_RECV_CNODE, seL4_WordBits);
|
||||
trace!("Cap receive path {}:{}:{}", SELF_CNODE, MEMORY_RECV_CNODE, seL4_WordBits);
|
||||
CAMKES.init_recv_path(&Camkes::top_level_path(MEMORY_RECV_CNODE));
|
||||
}
|
||||
|
||||
// MemoryInterface glue stubs.
|
||||
|
||||
// Clears any capability the specified path points to.
|
||||
fn clear_path(&(root, index, depth): &(seL4_CPtr, seL4_CPtr, seL4_Word)) {
|
||||
// TODO(sleffler): assert since future receives are likely to fail?
|
||||
if let Err(e) = unsafe { seL4_CNode_Delete(root, index, depth as u8) } {
|
||||
// NB: no error is returned if the slot is empty.
|
||||
info!("Failed to clear receive path {:?}: {:?}",
|
||||
(root, index, depth), e);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memory_alloc(
|
||||
c_raw_data_len: u32,
|
||||
c_raw_data: *const u8,
|
||||
) -> MemoryManagerError {
|
||||
let recv_path = seL4_GetCapReceivePath();
|
||||
let recv_path = CAMKES.get_current_recv_path();
|
||||
// NB: make sure noone clobbers the setup done in memory__init
|
||||
assert_eq!(recv_path, (SELF_CNODE, MEMORY_RECV_CNODE, seL4_WordBits));
|
||||
CAMKES.assert_recv_path();
|
||||
|
||||
let raw_slice = slice::from_raw_parts(c_raw_data, c_raw_data_len as usize);
|
||||
let ret_status = match postcard::from_bytes::<ObjDescBundle>(raw_slice) {
|
||||
@ -136,7 +100,7 @@ pub unsafe extern "C" fn memory_alloc(
|
||||
Err(_) => MemoryManagerError::MmeDeserializeFailed,
|
||||
};
|
||||
// NB: must clear ReceivePath for next request
|
||||
clear_path(&recv_path);
|
||||
CAMKES.clear_recv_path();
|
||||
ret_status
|
||||
}
|
||||
|
||||
@ -145,9 +109,9 @@ pub unsafe extern "C" fn memory_free(
|
||||
c_raw_data_len: u32,
|
||||
c_raw_data: *const u8,
|
||||
) -> MemoryManagerError {
|
||||
let recv_path = seL4_GetCapReceivePath();
|
||||
let recv_path = CAMKES.get_current_recv_path();
|
||||
// NB: make sure noone clobbers the setup done in memory__init
|
||||
assert_eq!(recv_path, (SELF_CNODE, MEMORY_RECV_CNODE, seL4_WordBits));
|
||||
CAMKES.assert_recv_path();
|
||||
|
||||
let raw_slice = slice::from_raw_parts(c_raw_data, c_raw_data_len as usize);
|
||||
let ret_status = match postcard::from_bytes::<ObjDescBundle>(raw_slice) {
|
||||
@ -160,7 +124,7 @@ pub unsafe extern "C" fn memory_free(
|
||||
Err(_) => MemoryManagerError::MmeDeserializeFailed,
|
||||
};
|
||||
// NB: must clear ReceivePath for next request
|
||||
clear_path(&recv_path);
|
||||
CAMKES.clear_recv_path();
|
||||
ret_status
|
||||
}
|
||||
|
||||
|
@ -8,46 +8,18 @@ use cstr_core::CStr;
|
||||
use kata_ml_coordinator::MLCoordinator;
|
||||
use kata_ml_coordinator::ModelIdx;
|
||||
use kata_ml_interface::MlCoordError;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_os_common::slot_allocator::KATA_CSPACE_SLOTS;
|
||||
use kata_os_common::camkes::Camkes;
|
||||
use kata_timer_interface::*;
|
||||
use log::{error, trace};
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use log::error;
|
||||
use spin::Mutex;
|
||||
|
||||
static mut CAMKES: Camkes = Camkes::new("MlCoordinator");
|
||||
static mut ML_COORD: Mutex<MLCoordinator> = Mutex::new(MLCoordinator::new());
|
||||
|
||||
extern "C" {
|
||||
static SELF_CNODE_FIRST_SLOT: seL4_CPtr;
|
||||
static SELF_CNODE_LAST_SLOT: seL4_CPtr;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
|
||||
// TODO(sleffler): temp until we integrate with seL4
|
||||
static mut HEAP_MEMORY: [u8; 4 * 1024] = [0; 4 * 1024];
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
HEAP_MEMORY.len()
|
||||
);
|
||||
|
||||
KATA_CSPACE_SLOTS.init(
|
||||
/*first_slot=*/ SELF_CNODE_FIRST_SLOT,
|
||||
/*size=*/ SELF_CNODE_LAST_SLOT - SELF_CNODE_FIRST_SLOT,
|
||||
);
|
||||
trace!(
|
||||
"setup cspace slots: first slot {} free {}",
|
||||
KATA_CSPACE_SLOTS.base_slot(),
|
||||
KATA_CSPACE_SLOTS.free_slots()
|
||||
);
|
||||
CAMKES.pre_init(log::LevelFilter::Trace, &mut HEAP_MEMORY);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -56,7 +28,7 @@ pub unsafe extern "C" fn mlcoord__init() {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn run() {
|
||||
pub unsafe extern "C" fn run() {
|
||||
loop {
|
||||
timer_service_wait();
|
||||
let completed = timer_service_completed_timers();
|
||||
@ -64,10 +36,8 @@ pub extern "C" fn run() {
|
||||
for i in 0..31 {
|
||||
let idx: u32 = 1 << i;
|
||||
if completed & idx != 0 {
|
||||
unsafe {
|
||||
if let Err(e) = ML_COORD.lock().timer_completed(i as ModelIdx) {
|
||||
error!("Error when trying to run periodic model: {:?}", e);
|
||||
}
|
||||
if let Err(e) = ML_COORD.lock().timer_completed(i as ModelIdx) {
|
||||
error!("Error when trying to run periodic model: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,83 +7,34 @@
|
||||
use core::slice;
|
||||
use cstr_core::CStr;
|
||||
use kata_memory_interface::ObjDescBundle;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::camkes::Camkes;
|
||||
use kata_os_common::slot_allocator;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_proc_interface::*;
|
||||
use kata_proc_manager::KATA_PROC;
|
||||
use log::{info, trace};
|
||||
use log::trace;
|
||||
|
||||
use sel4_sys::seL4_CNode_Delete;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_GetCapReceivePath;
|
||||
use sel4_sys::seL4_SetCapReceivePath;
|
||||
use sel4_sys::seL4_Word;
|
||||
use sel4_sys::seL4_WordBits;
|
||||
|
||||
use slot_allocator::KATA_CSPACE_SLOTS;
|
||||
|
||||
// TODO(sleffler): belongs in sel4-sys
|
||||
#[allow(non_camel_case_types)]
|
||||
type seL4_Path = (seL4_CPtr, seL4_CPtr, seL4_Word);
|
||||
|
||||
extern "C" {
|
||||
// Each CAmkES-generated CNode has a writable self-reference to itself in
|
||||
// the slot SELF_CNODE.
|
||||
static SELF_CNODE: seL4_CPtr;
|
||||
|
||||
static SELF_CNODE_FIRST_SLOT: seL4_CPtr;
|
||||
static SELF_CNODE_LAST_SLOT: seL4_CPtr;
|
||||
}
|
||||
static mut CAMKES: Camkes = Camkes::new("ProcessManager");
|
||||
|
||||
// TODO(sleffler): 0 is valid
|
||||
static mut PKG_MGMT_RECV_SLOT: seL4_CPtr = 0;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
// NB: set to max; the LoggerInterface will filter
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
|
||||
static mut HEAP_MEMORY: [u8; 16 * 1024] = [0; 16 * 1024];
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
HEAP_MEMORY.len()
|
||||
);
|
||||
CAMKES.pre_init(log::LevelFilter::Trace, &mut HEAP_MEMORY);
|
||||
|
||||
// Complete KATA_PROC setup. This is as early as we can do it given that
|
||||
// it needs the GlobalAllocator.
|
||||
// Complete KATA_PROC setup now that Global allocator is setup.
|
||||
KATA_PROC.init();
|
||||
trace!("ProcessManager has capacity for {} bundles", KATA_PROC.capacity());
|
||||
|
||||
KATA_CSPACE_SLOTS.init(
|
||||
/*first_slot=*/ SELF_CNODE_FIRST_SLOT,
|
||||
/*size=*/ SELF_CNODE_LAST_SLOT - SELF_CNODE_FIRST_SLOT
|
||||
);
|
||||
trace!("setup cspace slots: first slot {} free {}",
|
||||
KATA_CSPACE_SLOTS.base_slot(),
|
||||
KATA_CSPACE_SLOTS.free_slots());
|
||||
|
||||
PKG_MGMT_RECV_SLOT = KATA_CSPACE_SLOTS.alloc(1).unwrap();
|
||||
}
|
||||
|
||||
fn debug_check_empty(tag: &str, path: &seL4_Path) {
|
||||
sel4_sys::debug_assert_slot_empty!(path.1,
|
||||
"{}: expected slot {:?} empty but has cap type {:?}",
|
||||
tag, path, sel4_sys::cap_identify(path.1));
|
||||
}
|
||||
|
||||
|
||||
fn init_recv_path(tag: &str, path: &seL4_Path) {
|
||||
unsafe { seL4_SetCapReceivePath(path.0, path.1, path.2); }
|
||||
info!("{}: cap receive path {:?}", tag, path);
|
||||
debug_check_empty("init_recv_path", path);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pkg_mgmt__init() {
|
||||
// Point the receive path to the well-known slot for receiving
|
||||
@ -92,14 +43,7 @@ pub unsafe extern "C" fn pkg_mgmt__init() {
|
||||
// NB: this must be done here (rather than someplace like pre_init)
|
||||
// so it's in the context of the PackageManagementInterface thread
|
||||
// (so we write the correct ipc buffer).
|
||||
init_recv_path("pkg_mgmt",
|
||||
&(SELF_CNODE, PKG_MGMT_RECV_SLOT, seL4_WordBits));
|
||||
}
|
||||
|
||||
// Clears any capability the specified path points to.
|
||||
fn clear_path(path: &seL4_Path) {
|
||||
assert!(unsafe { seL4_CNode_Delete(path.0, path.1, path.2 as u8) }.is_ok());
|
||||
debug_check_empty("clear_path", path);
|
||||
CAMKES.init_recv_path(&Camkes::top_level_path(PKG_MGMT_RECV_SLOT));
|
||||
}
|
||||
|
||||
// PackageManagerInterface glue stubs.
|
||||
@ -109,16 +53,14 @@ pub unsafe extern "C" fn pkg_mgmt_install(
|
||||
c_request: *const u8,
|
||||
c_raw_data: *mut RawBundleIdData,
|
||||
) -> ProcessManagerError {
|
||||
let recv_path = seL4_GetCapReceivePath();
|
||||
let recv_path = CAMKES.get_current_recv_path();
|
||||
// NB: make sure noone clobbers the setup done in pkg_mgmt__init
|
||||
assert_eq!(recv_path, (SELF_CNODE, PKG_MGMT_RECV_SLOT, seL4_WordBits));
|
||||
CAMKES.assert_recv_path();
|
||||
|
||||
let request_slice = slice::from_raw_parts(c_request, c_request_len as usize);
|
||||
let ret_status = match postcard::from_bytes::<ObjDescBundle>(request_slice) {
|
||||
Ok(mut pkg_contents) => {
|
||||
sel4_sys::debug_assert_slot_cnode!(recv_path.1,
|
||||
"Expected cnode in slot {} but has cap type {:?}",
|
||||
recv_path.1, sel4_sys::cap_identify(recv_path.1));
|
||||
Camkes::debug_assert_slot_cnode("pkg_mgmt_install", &recv_path);
|
||||
pkg_contents.cnode = recv_path.1;
|
||||
match KATA_PROC.install(&pkg_contents) {
|
||||
Ok(bundle_id) => match postcard::to_slice(&bundle_id, &mut (*c_raw_data)[..]) {
|
||||
@ -130,25 +72,17 @@ pub unsafe extern "C" fn pkg_mgmt_install(
|
||||
}
|
||||
Err(e) => e.into(),
|
||||
};
|
||||
clear_path(&recv_path);
|
||||
CAMKES.clear_recv_path();
|
||||
ret_status
|
||||
}
|
||||
|
||||
fn check_pkg_mgmt_empty(tag: &str) -> seL4_Path {
|
||||
unsafe {
|
||||
let recv_path = seL4_GetCapReceivePath();
|
||||
// NB: make sure noone clobbers the setup done in pkg_mgmt__init
|
||||
assert_eq!(recv_path, (SELF_CNODE, PKG_MGMT_RECV_SLOT, seL4_WordBits));
|
||||
debug_check_empty(tag, &recv_path);
|
||||
recv_path
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pkg_mgmt_uninstall(
|
||||
c_bundle_id: *const cstr_core::c_char
|
||||
) -> ProcessManagerError {
|
||||
let recv_path = check_pkg_mgmt_empty("pkg_mgmt_uninstall");
|
||||
let recv_path = CAMKES.get_current_recv_path();
|
||||
CAMKES.assert_recv_path();
|
||||
Camkes::debug_assert_slot_empty("pkg_mgmt_uninstall", &recv_path);
|
||||
let ret_status = match CStr::from_ptr(c_bundle_id).to_str() {
|
||||
Ok(bundle_id) => match KATA_PROC.uninstall(bundle_id) {
|
||||
Ok(_) => ProcessManagerError::Success,
|
||||
@ -156,7 +90,7 @@ pub unsafe extern "C" fn pkg_mgmt_uninstall(
|
||||
},
|
||||
Err(_) => ProcessManagerError::BundleIdInvalid,
|
||||
};
|
||||
debug_check_empty("pkg_mgmt_uninstall", &recv_path);
|
||||
Camkes::debug_assert_slot_empty("pkg_mgmt_uninstall", &recv_path);
|
||||
ret_status
|
||||
}
|
||||
|
||||
|
@ -5,64 +5,32 @@
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use core::slice;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::camkes::Camkes;
|
||||
use kata_os_common::cspace_slot::CSpaceSlot;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_os_common::slot_allocator::KATA_CSPACE_SLOTS;
|
||||
use kata_security_coordinator::KATA_SECURITY;
|
||||
use kata_security_interface::*;
|
||||
use kata_storage_interface::KEY_VALUE_DATA_SIZE;
|
||||
use log::{info, trace};
|
||||
use log::trace;
|
||||
|
||||
use SecurityRequestError::*;
|
||||
|
||||
use sel4_sys::seL4_CNode_Delete;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_GetCapReceivePath;
|
||||
use sel4_sys::seL4_SetCap;
|
||||
use sel4_sys::seL4_SetCapReceivePath;
|
||||
use sel4_sys::seL4_Word;
|
||||
use sel4_sys::seL4_WordBits;
|
||||
|
||||
extern "C" {
|
||||
// Each CAmkES-generated CNode has a writable self-reference to itself in
|
||||
// the slot SELF_CNODE.
|
||||
static SELF_CNODE: seL4_CPtr;
|
||||
|
||||
static SELF_CNODE_FIRST_SLOT: seL4_CPtr;
|
||||
static SELF_CNODE_LAST_SLOT: seL4_CPtr;
|
||||
}
|
||||
|
||||
static mut CAMKES: Camkes = Camkes::new("SecurityCoordinator");
|
||||
static mut SECURITY_RECV_SLOT: seL4_CPtr = 0;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
// NB: set to max; the LoggerInterface will filter
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
|
||||
static mut HEAP_MEMORY: [u8; 8 * 1024] = [0; 8 * 1024];
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
HEAP_MEMORY.len()
|
||||
);
|
||||
// NB: set to max; the LoggerInterface will filter
|
||||
CAMKES.pre_init(log::LevelFilter::Trace, &mut HEAP_MEMORY);
|
||||
|
||||
// Complete KATA_SECURITY setup. This is as early as we can do it given that
|
||||
// it needs the GlobalAllocator.
|
||||
// Complete KATA_SECURITY setup after Global allocator is setup.
|
||||
KATA_SECURITY.init();
|
||||
|
||||
KATA_CSPACE_SLOTS.init(
|
||||
/*first_slot=*/ SELF_CNODE_FIRST_SLOT,
|
||||
/*size=*/ SELF_CNODE_LAST_SLOT - SELF_CNODE_FIRST_SLOT
|
||||
);
|
||||
trace!("setup cspace slots: first slot {} free {}",
|
||||
KATA_CSPACE_SLOTS.base_slot(),
|
||||
KATA_CSPACE_SLOTS.free_slots());
|
||||
|
||||
SECURITY_RECV_SLOT = KATA_CSPACE_SLOTS.alloc(1).unwrap();
|
||||
}
|
||||
|
||||
@ -75,26 +43,9 @@ pub unsafe extern "C" fn security__init() {
|
||||
// NB: this must be done here (rather than someplace like pre_init)
|
||||
// so it's in the context of the SecurityCoordinatorInterface thread
|
||||
// (so we write the correct ipc buffer).
|
||||
let path = (SELF_CNODE, SECURITY_RECV_SLOT, seL4_WordBits);
|
||||
seL4_SetCapReceivePath(path.0, path.1, path.2);
|
||||
info!("security cap receive path {:?}", path);
|
||||
debug_check_empty("security__init", &path);
|
||||
}
|
||||
|
||||
fn debug_check_empty(tag: &str, path: &(seL4_CPtr, seL4_CPtr, seL4_Word)) {
|
||||
sel4_sys::debug_assert_slot_empty!(path.1,
|
||||
"{}: expected slot {:?} empty but has cap type {:?}",
|
||||
tag, path, sel4_sys::cap_identify(path.1));
|
||||
}
|
||||
|
||||
// Clears any capability the specified path points to.
|
||||
fn _clear_path(path: &(seL4_CPtr, seL4_CPtr, seL4_Word)) {
|
||||
// TODO(sleffler): assert since future receives are likely to fail?
|
||||
if let Err(e) = unsafe { seL4_CNode_Delete(path.0, path.1, path.2 as u8) } {
|
||||
// NB: no error is returned if the slot is empty.
|
||||
info!("Failed to clear receive path {:?}: {:?}", path, e);
|
||||
}
|
||||
debug_check_empty("clear_path", path);
|
||||
let path = &Camkes::top_level_path(SECURITY_RECV_SLOT);
|
||||
CAMKES.init_recv_path(path);
|
||||
Camkes::debug_assert_slot_empty("security__init", path);
|
||||
}
|
||||
|
||||
fn serialize_failure(e: postcard::Error) -> SecurityRequestError {
|
||||
@ -123,10 +74,8 @@ fn install_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let recv_path = unsafe { seL4_GetCapReceivePath() };
|
||||
sel4_sys::debug_assert_slot_cnode!(recv_path.1,
|
||||
"install_request: expected cnode in slot {:?} but found cap type {:?}",
|
||||
recv_path, sel4_sys::cap_identify(recv_path.1));
|
||||
let recv_path = unsafe { CAMKES.get_current_recv_path() };
|
||||
Camkes::debug_assert_slot_cnode("install_request", &recv_path);
|
||||
|
||||
let mut request = postcard::from_bytes::<InstallRequest>(request_buffer)
|
||||
.map_err(deserialize_failure)?; // XXX clear_path
|
||||
|
@ -7,29 +7,18 @@
|
||||
extern crate alloc;
|
||||
use core::slice;
|
||||
use cstr_core::CStr;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::camkes::Camkes;
|
||||
use kata_storage_interface::KeyValueData;
|
||||
use kata_storage_interface::StorageManagerError;
|
||||
use kata_storage_interface::StorageManagerInterface;
|
||||
use kata_storage_manager::KATA_STORAGE;
|
||||
use log::trace;
|
||||
|
||||
static mut CAMKES: Camkes = Camkes::new("StorageManager");
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
// NB: set to max; the LoggerInterface will filter
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
|
||||
// TODO(sleffler): temp until we integrate with seL4
|
||||
static mut HEAP_MEMORY: [u8; 8 * 1024] = [0; 8 * 1024];
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
HEAP_MEMORY.len()
|
||||
);
|
||||
CAMKES.pre_init(log::LevelFilter::Trace, &mut HEAP_MEMORY);
|
||||
}
|
||||
|
||||
// StorageInterface glue stubs.
|
||||
|
@ -3,26 +3,19 @@
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use core::time::Duration;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::camkes::Camkes;
|
||||
use kata_os_common::sel4_sys::seL4_Word;
|
||||
use kata_timer_interface::{TimerId, TimerServiceError};
|
||||
use kata_timer_service::TIMER_SRV;
|
||||
use log::trace;
|
||||
|
||||
static mut CAMKES: Camkes = Camkes::new("TimerService");
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
|
||||
// TODO(jesionowski): temp until we integrate with seL4
|
||||
static mut HEAP_MEMORY: [u8; 4 * 1024] = [0; 4 * 1024];
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
HEAP_MEMORY.len()
|
||||
CAMKES.pre_init(
|
||||
log::LevelFilter::Debug,
|
||||
&mut HEAP_MEMORY,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ camkes_support = []
|
||||
|
||||
[dependencies]
|
||||
allocator = { path = "src/allocator" }
|
||||
camkes = { path = "src/camkes" }
|
||||
capdl = { path = "src/capdl" }
|
||||
cspace-slot = { path = "src/cspace-slot" }
|
||||
logger = { path = "src/logger" }
|
||||
|
13
apps/system/components/kata-os-common/src/camkes/Cargo.toml
Normal file
13
apps/system/components/kata-os-common/src/camkes/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
cargo-features = ["edition2021"]
|
||||
|
||||
[package]
|
||||
name = "camkes"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
allocator = { path = "../allocator" }
|
||||
logger = { path = "../logger" }
|
||||
sel4-sys = { path = "../sel4-sys" }
|
||||
slot-allocator = { path = "../slot-allocator" }
|
126
apps/system/components/kata-os-common/src/camkes/src/lib.rs
Normal file
126
apps/system/components/kata-os-common/src/camkes/src/lib.rs
Normal file
@ -0,0 +1,126 @@
|
||||
//! Kata OS CAmkES component helpers
|
||||
|
||||
#![no_std]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use allocator;
|
||||
use logger::KataLogger;
|
||||
use slot_allocator::KATA_CSPACE_SLOTS;
|
||||
use log::trace;
|
||||
use sel4_sys;
|
||||
|
||||
use sel4_sys::seL4_CNode_Delete;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_GetCapReceivePath;
|
||||
use sel4_sys::seL4_SetCapReceivePath;
|
||||
use sel4_sys::seL4_Word;
|
||||
use sel4_sys::seL4_WordBits;
|
||||
|
||||
pub type seL4_CPath = (seL4_CPtr, seL4_CPtr, seL4_Word);
|
||||
|
||||
extern "C" {
|
||||
// CAmkES components marked with
|
||||
// attribute integer kataos = 1;
|
||||
// automatically get a self-reference to their top-level CNode and
|
||||
// the slot #'s of the first & last free slots in the CNode.
|
||||
static SELF_CNODE: seL4_CPtr;
|
||||
static SELF_CNODE_FIRST_SLOT: seL4_CPtr;
|
||||
static SELF_CNODE_LAST_SLOT: seL4_CPtr;
|
||||
}
|
||||
|
||||
pub struct Camkes {
|
||||
name: &'static str, // Component name
|
||||
recv_path: seL4_CPath, // IPCBuffer receive path
|
||||
}
|
||||
|
||||
impl Camkes {
|
||||
pub const fn new(name: &'static str) -> Self {
|
||||
Camkes {
|
||||
name,
|
||||
recv_path: (seL4_CPtr::MAX, seL4_CPtr::MAX, seL4_Word::MAX),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_logger(self: &Camkes, level: log::LevelFilter) {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
log::set_max_level(level);
|
||||
}
|
||||
|
||||
pub fn init_allocator(self: &Camkes, heap: &'static mut [u8]) {
|
||||
unsafe {
|
||||
allocator::ALLOCATOR.init(heap.as_mut_ptr() as usize, heap.len());
|
||||
}
|
||||
trace!("setup heap: start_addr {:p} size {}", heap.as_ptr(), heap.len());
|
||||
}
|
||||
|
||||
pub fn init_slot_allocator(self: &Camkes, first_slot: seL4_CPtr, last_slot: seL4_CPtr) {
|
||||
unsafe {
|
||||
KATA_CSPACE_SLOTS.init(first_slot, last_slot - first_slot);
|
||||
trace!("setup cspace slots: first slot {} free {}",
|
||||
KATA_CSPACE_SLOTS.base_slot(),
|
||||
KATA_CSPACE_SLOTS.free_slots());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pre_init(
|
||||
self: &Camkes,
|
||||
level: log::LevelFilter,
|
||||
heap: &'static mut [u8],
|
||||
) {
|
||||
self.init_logger(level);
|
||||
self.init_allocator(heap);
|
||||
unsafe { self.init_slot_allocator(SELF_CNODE_FIRST_SLOT, SELF_CNODE_LAST_SLOT); }
|
||||
}
|
||||
|
||||
pub fn top_level_path(slot: seL4_CPtr) -> seL4_CPath {
|
||||
unsafe { (SELF_CNODE, slot, seL4_WordBits) }
|
||||
}
|
||||
|
||||
// Initializes the IPCBuffer receive path with |path|.
|
||||
pub fn init_recv_path(self: &mut Camkes, path: &seL4_CPath) {
|
||||
self.recv_path = *path;
|
||||
unsafe { seL4_SetCapReceivePath(path.0, path.1, path.2); }
|
||||
trace!("Cap receive path {:?}", path);
|
||||
}
|
||||
|
||||
// Returns the path specified with init_recv_path.
|
||||
pub fn get_recv_path(self: &Camkes) -> seL4_CPath { self.recv_path }
|
||||
|
||||
// Returns the current receive path from the IPCBuffer.
|
||||
pub fn get_current_recv_path(self: &Camkes) -> seL4_CPath {
|
||||
unsafe { seL4_GetCapReceivePath() }
|
||||
}
|
||||
|
||||
// Clears any capability the receive path path points to.
|
||||
pub fn clear_recv_path(self: &Camkes) {
|
||||
let path = &self.recv_path;
|
||||
// Assert since future receives are likely to fail
|
||||
unsafe { seL4_CNode_Delete(path.0, path.1, path.2 as u8) }.expect(self.name);
|
||||
}
|
||||
|
||||
// Check the current receive path in the IPCBuffer against what was
|
||||
// setup with init_recv_path.
|
||||
pub fn check_recv_path(self: &Camkes) -> bool {
|
||||
self.get_current_recv_path() == self.get_recv_path()
|
||||
}
|
||||
|
||||
// Like check_recv_path but asserts if there is an inconsistency.
|
||||
pub fn assert_recv_path(self: &Camkes) {
|
||||
assert!(self.check_recv_path(),
|
||||
"Current receive path {:?} does not match init'd path {:?}",
|
||||
self.get_current_recv_path(), self.recv_path);
|
||||
}
|
||||
|
||||
// Wrappers for sel4_sys::debug_assert macros.
|
||||
pub fn debug_assert_slot_empty(tag: &str, path: &seL4_CPath) {
|
||||
sel4_sys::debug_assert_slot_empty!(path.1,
|
||||
"{}: expected slot {:?} empty but has cap type {:?}",
|
||||
tag, path, sel4_sys::cap_identify(path.1));
|
||||
}
|
||||
pub fn debug_assert_slot_cnode(tag: &str, path: &seL4_CPath) {
|
||||
sel4_sys::debug_assert_slot_cnode!(path.1,
|
||||
"{}: expected cnode in slot {:?} but found cap type {:?}",
|
||||
tag, path, sel4_sys::cap_identify(path.1));
|
||||
}
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
#![no_std]
|
||||
|
||||
pub extern crate capdl;
|
||||
pub extern crate model;
|
||||
pub extern crate allocator;
|
||||
pub extern crate logger;
|
||||
pub extern crate panic;
|
||||
#[cfg(feature = "camkes_support")]
|
||||
pub extern crate camkes;
|
||||
pub extern crate capdl;
|
||||
#[cfg(feature = "camkes_support")]
|
||||
pub extern crate cspace_slot;
|
||||
pub extern crate slot_allocator;
|
||||
pub extern crate logger;
|
||||
pub extern crate model;
|
||||
pub extern crate panic;
|
||||
pub extern crate sel4_sys;
|
||||
pub extern crate slot_allocator;
|
||||
|
Loading…
Reference in New Issue
Block a user