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:
Sam Leffler 2022-05-20 20:45:53 +00:00
parent 3bd8389a4c
commit ddacc3762e
11 changed files with 214 additions and 301 deletions

View File

@ -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.

View File

@ -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
}

View File

@ -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);
}
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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.

View File

@ -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,
);
}

View File

@ -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" }

View 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" }

View 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));
}
}

View File

@ -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;