mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-09-17 15:38:18 +00:00
kata-os-model: misc fixups
Fallout from rootserver memory reclamation work: - add CDL_Object::next_free_slot - add CONFIG_NOISY_UNTYPEDS feature for spammy debug msgs - add CONFIG_NOISY_CREATE_OBJECT msgs - assert if bootinfo/untyped_cnode setup is wrong instead of logging msgs and then failing later - bury ugly BIT usage in is_obj_inside_untyped - revise handoff_cap api for future use in memory reclamation - remove some unneeded type coercions - streamline printing seL4_CPath's - simplify get_object & get_asid Change-Id: Ib2c3d717dd41b307cb7afd4821dee4b6be173d57 GitOrigin-RevId: 99f4b79e1df257d373accf96190a77a65ba3305f
This commit is contained in:
@@ -649,6 +649,15 @@ impl<'a> CDL_Object {
|
|||||||
pub fn num_slots(&self) -> seL4_Word {
|
pub fn num_slots(&self) -> seL4_Word {
|
||||||
self.slots.num
|
self.slots.num
|
||||||
}
|
}
|
||||||
|
// Returns the next available slot past those specified in the spec.
|
||||||
|
// Note we cannot use num_slots since there may be gaps in the
|
||||||
|
// numbering due to empty slots.
|
||||||
|
#[inline]
|
||||||
|
pub fn next_free_slot(&self) -> seL4_Word {
|
||||||
|
self.slots_slice().iter()
|
||||||
|
.max_by_key(|slot| slot.slot)
|
||||||
|
.map_or(0, |slot| slot.slot + 1)
|
||||||
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn slot(&self, index: seL4_Word) -> CDL_CapSlot {
|
pub fn slot(&self, index: seL4_Word) -> CDL_CapSlot {
|
||||||
#[allow(unaligned_references)]
|
#[allow(unaligned_references)]
|
||||||
|
@@ -31,6 +31,7 @@ CONFIG_PRINTING = []
|
|||||||
CONFIG_SMP_SUPPORT = []
|
CONFIG_SMP_SUPPORT = []
|
||||||
CONFIG_VTX = []
|
CONFIG_VTX = []
|
||||||
# Enable inclusion of noisy logging in various areas
|
# Enable inclusion of noisy logging in various areas
|
||||||
|
CONFIG_NOISY_UNTYPEDS = []
|
||||||
CONFIG_NOISY_CREATE_OBJECT = []
|
CONFIG_NOISY_CREATE_OBJECT = []
|
||||||
CONFIG_NOISY_INIT_CNODE = []
|
CONFIG_NOISY_INIT_CNODE = []
|
||||||
CONFIG_NOISY_INIT_VSPACE = []
|
CONFIG_NOISY_INIT_VSPACE = []
|
||||||
|
@@ -5,7 +5,7 @@ use capdl::CDL_FrameFill_BootInfoEnum_t::*;
|
|||||||
use capdl::CDL_FrameFillType_t::*;
|
use capdl::CDL_FrameFillType_t::*;
|
||||||
use capdl::CDL_ObjectType::*;
|
use capdl::CDL_ObjectType::*;
|
||||||
use crate::KataOsModel;
|
use crate::KataOsModel;
|
||||||
use log::{debug, info, trace};
|
use log::{debug, trace};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use sel4_sys::seL4_ASIDControl_MakePool;
|
use sel4_sys::seL4_ASIDControl_MakePool;
|
||||||
@@ -72,12 +72,9 @@ impl<'a> KataOsModel<'a> {
|
|||||||
{
|
{
|
||||||
let free_slot = self.free_slot_start + free_slot_index;
|
let free_slot = self.free_slot_start + free_slot_index;
|
||||||
|
|
||||||
// trace!(
|
#[cfg(feature = "CONFIG_NOISY_CREATE_OBJECT")]
|
||||||
// "Creating object {} in slot {} from untyped {:#x}...",
|
trace!("Creating object {} in slot {} from untyped {:#x}...",
|
||||||
// obj.name(),
|
obj.name(), free_slot, self.state.get_untyped_cptr(ut_index));
|
||||||
// free_slot,
|
|
||||||
// self.state.get_untyped_cptr(ut_index)
|
|
||||||
// );
|
|
||||||
|
|
||||||
// NB: create_object may use free_slot + 1 and free_slot + 2
|
// NB: create_object may use free_slot + 1 and free_slot + 2
|
||||||
while let Err(e) =
|
while let Err(e) =
|
||||||
@@ -112,18 +109,18 @@ impl<'a> KataOsModel<'a> {
|
|||||||
// NB: can instantiate multiple frames but only one
|
// NB: can instantiate multiple frames but only one
|
||||||
// CNode can receive the untypeds since we must move
|
// CNode can receive the untypeds since we must move
|
||||||
// 'em from the rootserver (since they are "derived").
|
// 'em from the rootserver (since they are "derived").
|
||||||
// XXX maybe just complain & ignore
|
assert!(!is_objid_valid(bootinfo_frame),
|
||||||
trace!("Found bootinfo Frame at {}", obj_id);
|
"Duplicate bootinfo Frame at {}, prev {}",
|
||||||
assert!(!is_objid_valid(bootinfo_frame));
|
obj_id, bootinfo_frame);
|
||||||
bootinfo_frame = obj_id;
|
bootinfo_frame = obj_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Look for a CNode associated with any bootinfo frame.
|
// Look for a CNode associated with any bootinfo frame.
|
||||||
CDL_CNode => {
|
CDL_CNode => {
|
||||||
if obj.cnode_has_untyped_memory() {
|
if obj.cnode_has_untyped_memory() {
|
||||||
if is_objid_valid(untyped_cnode) {
|
assert!(!is_objid_valid(untyped_cnode),
|
||||||
info!("Duplicate bootinfo cnode at {}, prev {}", obj_id, untyped_cnode);
|
"Duplicate bootinfo cnode at {}, prev {}",
|
||||||
}
|
obj_id, untyped_cnode);
|
||||||
untyped_cnode = obj_id;
|
untyped_cnode = obj_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,16 +213,18 @@ impl<'a> KataOsModel<'a> {
|
|||||||
if !ut.is_device() {
|
if !ut.is_device() {
|
||||||
let index = ut.size_bits();
|
let index = ut.size_bits();
|
||||||
|
|
||||||
// trace!("Untyped {:3} (cptr={:#x}) (addr={:#x}) is of size {:2}. Placing in slot {}...",
|
#[cfg(feature = "CONFIG_NOISY_UNTYPEDS")]
|
||||||
// untyped_index, untyped_start + untyped_index, ut.paddr, index, count[index]);
|
trace!("Untyped {:3} (cptr={:#x}) (addr={:#x}) is of size {:2}. Placing in slot {}...",
|
||||||
|
untyped_index, untyped_start + untyped_index, ut.paddr, index, count[index]);
|
||||||
|
|
||||||
self.state
|
self.state
|
||||||
.set_untyped_cptr(count[index], untyped_start + untyped_index);
|
.set_untyped_cptr(count[index], untyped_start + untyped_index);
|
||||||
count[index] += 1;
|
count[index] += 1;
|
||||||
num_normal_untypes += 1;
|
num_normal_untypes += 1;
|
||||||
} else {
|
} else {
|
||||||
// trace!("Untyped {:3} (cptr={:#x}) (addr={:#x}) is of size {:2}. Skipping as it is device",
|
#[cfg(feature = "CONFIG_NOISY_UNTYPEDS")]
|
||||||
// untyped_index, untyped_start + untyped_index, ut.paddr, ut.size_bits());
|
trace!("Untyped {:3} (cptr={:#x}) (addr={:#x}) is of size {:2}. Skipping as it is device",
|
||||||
|
untyped_index, untyped_start + untyped_index, ut.paddr, ut.size_bits());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num_normal_untypes
|
num_normal_untypes
|
||||||
@@ -292,7 +291,7 @@ impl<'a> KataOsModel<'a> {
|
|||||||
obj_size_bits: usize,
|
obj_size_bits: usize,
|
||||||
ut: &seL4_UntypedDesc,
|
ut: &seL4_UntypedDesc,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
ut.paddr <= obj_addr && obj_addr + obj_size_bits <= ut.paddr + BIT(ut.size_bits())
|
ut.paddr <= obj_addr && obj_addr + BIT(obj_size_bits) <= ut.paddr + BIT(ut.size_bits())
|
||||||
}
|
}
|
||||||
fn get_address(ut_slot: seL4_CPtr) -> Result<seL4_Page_GetAddress, seL4_Error> {
|
fn get_address(ut_slot: seL4_CPtr) -> Result<seL4_Page_GetAddress, seL4_Error> {
|
||||||
// Create a temporary frame to get the address. We load this at slot + 2
|
// Create a temporary frame to get the address. We load this at slot + 2
|
||||||
@@ -316,7 +315,7 @@ impl<'a> KataOsModel<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_obj_inside_untyped(paddr, BIT(obj_size_bits), &untypedList[i]) {
|
if is_obj_inside_untyped(paddr, obj_size_bits, &untypedList[i]) {
|
||||||
// See above, loop looking for a Frame in the untyped object
|
// See above, loop looking for a Frame in the untyped object
|
||||||
// that matches our object's address. If we run out of space
|
// that matches our object's address. If we run out of space
|
||||||
// in the untyped the kernel will return seL4_NotEnoughMemory
|
// in the untyped the kernel will return seL4_NotEnoughMemory
|
||||||
|
@@ -229,7 +229,7 @@ impl<'a> KataOsModel<'a> {
|
|||||||
// as part of the work done by init_cspsace.
|
// as part of the work done by init_cspsace.
|
||||||
|
|
||||||
if is_objid_valid(self.untyped_cnode) {
|
if is_objid_valid(self.untyped_cnode) {
|
||||||
self.handoff_untypeds(self.untyped_cnode)?;
|
self.handoff_untypeds()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -885,15 +885,16 @@ impl<'a> KataOsModel<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handoff_untypeds(&mut self, cnode_obj_id: CDL_ObjID) -> seL4_Result {
|
pub fn handoff_untypeds(&mut self) -> seL4_Result {
|
||||||
let num_untypeds = self.bootinfo.untyped.end - self.bootinfo.untyped.start;
|
assert!(is_objid_valid(self.untyped_cnode), "No handoff CNode found");
|
||||||
|
|
||||||
// NB: UntypedMemory caps are appended to the CAmkES-generated slots
|
// UntypedMemory caps are appended to the CAmkES-generated slots
|
||||||
let dest_start = self.spec.obj_slice()[cnode_obj_id]
|
// in the CNode identified for handoff. CAmkES is assumed to have
|
||||||
.slots_slice()
|
// sized the CNode to handle moving the untyped memory slabs.
|
||||||
.iter()
|
let cnode = self.get_object(self.untyped_cnode);
|
||||||
.max_by_key(|slot| slot.slot)
|
let dest_root = self.get_orig_cap(self.untyped_cnode);
|
||||||
.map_or(0, |slot| slot.slot + 1);
|
let dest_start = cnode.next_free_slot();
|
||||||
|
let num_untypeds = self.bootinfo.untyped.end - self.bootinfo.untyped.start;
|
||||||
|
|
||||||
trace!("Hand-off {} untypeds from {} to {}",
|
trace!("Hand-off {} untypeds from {} to {}",
|
||||||
num_untypeds,
|
num_untypeds,
|
||||||
@@ -901,26 +902,27 @@ impl<'a> KataOsModel<'a> {
|
|||||||
dest_start);
|
dest_start);
|
||||||
// NB: we let kernel tell us if the CNode is too small.
|
// NB: we let kernel tell us if the CNode is too small.
|
||||||
for ut in 0..num_untypeds {
|
for ut in 0..num_untypeds {
|
||||||
self.handoff_cap(cnode_obj_id,
|
self.handoff_cap(self.untyped_cnode,
|
||||||
/*src_index=*/ self.bootinfo.untyped.start + ut,
|
/*src_index=*/ self.bootinfo.untyped.start + ut,
|
||||||
|
/*dest_root=*/ dest_root,
|
||||||
/*dest_index=*/ dest_start + ut)?;
|
/*dest_index=*/ dest_start + ut)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handoff_cap(
|
fn handoff_cap(
|
||||||
&mut self,
|
&self,
|
||||||
cnode_obj_id: CDL_ObjID,
|
cnode_obj_id: CDL_ObjID,
|
||||||
src_index: seL4_CPtr,
|
src_index: seL4_CPtr,
|
||||||
|
dest_root: seL4_CPtr,
|
||||||
dest_index: seL4_CPtr
|
dest_index: seL4_CPtr
|
||||||
) -> seL4_Result {
|
) -> seL4_Result {
|
||||||
let cnode = &self.spec.obj_slice()[cnode_obj_id];
|
let cnode = self.get_object(cnode_obj_id);
|
||||||
assert_eq!(cnode.r#type(), CDL_CNode);
|
assert_eq!(cnode.r#type(), CDL_CNode);
|
||||||
|
|
||||||
let src_root = seL4_CapInitThreadCNode;
|
let src_root = seL4_CapInitThreadCNode;
|
||||||
let src_depth = seL4_WordBits as u8;
|
let src_depth = seL4_WordBits as u8;
|
||||||
|
|
||||||
let dest_root = self.get_orig_cap(cnode_obj_id);
|
|
||||||
let dest_depth: u8 = cnode.size_bits.try_into().unwrap();
|
let dest_depth: u8 = cnode.size_bits.try_into().unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -991,11 +993,11 @@ impl<'a> KataOsModel<'a> {
|
|||||||
CDL_SchedControlCap => (false, self.get_sched_ctrl_cap(target_cap_obj)),
|
CDL_SchedControlCap => (false, self.get_sched_ctrl_cap(target_cap_obj)),
|
||||||
CDL_DomainCap => {
|
CDL_DomainCap => {
|
||||||
// there's only one cap
|
// there's only one cap
|
||||||
(false, seL4_CapDomain as seL4_CPtr)
|
(false, seL4_CapDomain)
|
||||||
}
|
}
|
||||||
CDL_ASIDControlCap => {
|
CDL_ASIDControlCap => {
|
||||||
// there's only one cap
|
// there's only one cap
|
||||||
(false, seL4_CapASIDControl as seL4_CPtr)
|
(false, seL4_CapASIDControl)
|
||||||
}
|
}
|
||||||
_ => (false, self.get_orig_cap(target_cap_obj)),
|
_ => (false, self.get_orig_cap(target_cap_obj)),
|
||||||
};
|
};
|
||||||
@@ -1004,22 +1006,22 @@ impl<'a> KataOsModel<'a> {
|
|||||||
if mode == InitCnodeCmode::MOVE && move_cap {
|
if mode == InitCnodeCmode::MOVE && move_cap {
|
||||||
if is_ep_cap || is_irq_handler_cap {
|
if is_ep_cap || is_irq_handler_cap {
|
||||||
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
||||||
debug!(" Populate {:?} slot {} by moving {}:{}:{} -> {}:{}:{}",
|
debug!(" Populate {:?} slot {} by moving {:?} -> {:?}",
|
||||||
target_cap_type, cnode_slot.slot,
|
target_cap_type, cnode_slot.slot,
|
||||||
src_root, src_index, src_depth,
|
(src_root, src_index, src_depth),
|
||||||
dest_root, dest_index, dest_depth,
|
(dest_root, dest_index, dest_depth),
|
||||||
);
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
seL4_CNode_Move(
|
seL4_CNode_Move(
|
||||||
dest_root, dest_index, dest_depth, src_root, src_index, src_depth,
|
dest_root, dest_index, dest_depth, src_root, src_index, src_depth,
|
||||||
)
|
)
|
||||||
}?
|
}?;
|
||||||
} else {
|
} else {
|
||||||
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
||||||
debug!(" Populate {:?} slot {} by mutating {}:{}:{} -> {}:{}:{}",
|
debug!(" Populate {:?} slot {} by mutating {:?} -> {:?}",
|
||||||
target_cap_type, cnode_slot.slot,
|
target_cap_type, cnode_slot.slot,
|
||||||
src_root, src_index, src_depth,
|
(src_root, src_index, src_depth),
|
||||||
dest_root, dest_index, dest_depth,
|
(dest_root, dest_index, dest_depth),
|
||||||
);
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
seL4_CNode_Mutate(
|
seL4_CNode_Mutate(
|
||||||
@@ -1052,10 +1054,10 @@ impl<'a> KataOsModel<'a> {
|
|||||||
// NB: the mapped frame cap is stored in the dup table.
|
// NB: the mapped frame cap is stored in the dup table.
|
||||||
let mapped_frame_cap = self.get_dup_cap(frame_cap.obj_id);
|
let mapped_frame_cap = self.get_dup_cap(frame_cap.obj_id);
|
||||||
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
||||||
debug!(" Map {:?} slot {} by moving {}:{}:{} -> {}:{}:{}",
|
debug!(" Map {:?} slot {} by moving {:?} -> {:?}",
|
||||||
target_cap_type, cnode_slot.slot,
|
target_cap_type, cnode_slot.slot,
|
||||||
src_root, mapped_frame_cap, src_depth,
|
(src_root, mapped_frame_cap, src_depth),
|
||||||
dest_root, dest_index, dest_depth,
|
(dest_root, dest_index, dest_depth),
|
||||||
);
|
);
|
||||||
// Move the cap to the frame used for the mapping into the
|
// Move the cap to the frame used for the mapping into the
|
||||||
// destination slot.
|
// destination slot.
|
||||||
@@ -1071,10 +1073,10 @@ impl<'a> KataOsModel<'a> {
|
|||||||
}?;
|
}?;
|
||||||
} else {
|
} else {
|
||||||
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
#[cfg(feature = "CONFIG_NOISY_INIT_CNODE")]
|
||||||
debug!(" Populate {:?} slot {} by minting {}:{}:{} -> {}:{}:{} {:?} data {:#x}",
|
debug!(" Populate {:?} slot {} by minting {:?} -> {:?} {:?} data {:#x}",
|
||||||
target_cap_type, cnode_slot.slot,
|
target_cap_type, cnode_slot.slot,
|
||||||
src_root, src_index, src_depth,
|
(src_root, src_index, src_depth),
|
||||||
dest_root, dest_index, dest_depth,
|
(dest_root, dest_index, dest_depth),
|
||||||
target_cap_rights, target_cap_data,
|
target_cap_rights, target_cap_data,
|
||||||
);
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -1095,13 +1097,10 @@ impl<'a> KataOsModel<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_object(&self, object_id: CDL_ObjID) -> &'a CDL_Object {
|
fn get_object(&self, object_id: CDL_ObjID) -> &'a CDL_Object {
|
||||||
&(unsafe { core::slice::from_raw_parts(self.spec.objects, self.spec.num) }[object_id])
|
&self.spec.obj_slice()[object_id]
|
||||||
}
|
}
|
||||||
fn get_asid(&self, asid_num: usize) -> Option<CDL_ObjID> {
|
fn get_asid(&self, asid_num: usize) -> Option<CDL_ObjID> {
|
||||||
Some(
|
Some(self.spec.asid_slot_slice()[asid_num])
|
||||||
unsafe { core::slice::from_raw_parts(self.spec.asid_slots, self.spec.num_asid_slots) }
|
|
||||||
[asid_num],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Top-level CSpace management: a one-level CSpace impl for now
|
// Top-level CSpace management: a one-level CSpace impl for now
|
||||||
@@ -1146,7 +1145,7 @@ impl<'a> KataOsModel<'a> {
|
|||||||
// interrupt notifications and fault endpoints when MCS is enabled.
|
// interrupt notifications and fault endpoints when MCS is enabled.
|
||||||
fn mint_cap(
|
fn mint_cap(
|
||||||
&mut self,
|
&mut self,
|
||||||
object_id: CDL_ObjID,
|
obj_id: CDL_ObjID,
|
||||||
badge: seL4_Word,
|
badge: seL4_Word,
|
||||||
) -> Result<seL4_CPtr, seL4_Error> {
|
) -> Result<seL4_CPtr, seL4_Error> {
|
||||||
let seL4_AllRights = seL4_CapRights::new(
|
let seL4_AllRights = seL4_CapRights::new(
|
||||||
@@ -1159,7 +1158,7 @@ impl<'a> KataOsModel<'a> {
|
|||||||
/*dest_index=*/ free_slot,
|
/*dest_index=*/ free_slot,
|
||||||
/*dest_depth*/ seL4_WordBits as u8,
|
/*dest_depth*/ seL4_WordBits as u8,
|
||||||
/*src_root=*/ seL4_CapInitThreadCNode,
|
/*src_root=*/ seL4_CapInitThreadCNode,
|
||||||
/*src_index=*/ self.get_orig_cap(object_id),
|
/*src_index=*/ self.get_orig_cap(obj_id),
|
||||||
/*src_depth=*/ seL4_WordBits as u8,
|
/*src_depth=*/ seL4_WordBits as u8,
|
||||||
seL4_AllRights,
|
seL4_AllRights,
|
||||||
badge,
|
badge,
|
||||||
|
Reference in New Issue
Block a user