feat(kernel): shared ABI decoder+proofs, no-panic gate, syscall storm, kani on shrunk kernel
This commit is contained in:
@@ -8,21 +8,26 @@
|
||||
/// always exists before it does.
|
||||
pub fn descendants<const N: usize>(parents: &[Option<u16>; N], root: usize) -> [bool; N] {
|
||||
let mut marked = [false; N];
|
||||
if root >= N {
|
||||
let Some(r) = marked.get_mut(root) else {
|
||||
return marked;
|
||||
}
|
||||
marked[root] = true;
|
||||
};
|
||||
*r = true;
|
||||
// Each pass extends the marked set by at least one generation of
|
||||
// children; a chain in an N-node forest is at most N - 1 long.
|
||||
for _ in 0..N {
|
||||
let mut changed = false;
|
||||
for i in 0..N {
|
||||
if !marked[i]
|
||||
&& let Some(p) = parents[i].map(usize::from)
|
||||
&& p < N
|
||||
&& marked[p]
|
||||
let parent_marked = parents
|
||||
.get(i)
|
||||
.copied()
|
||||
.flatten()
|
||||
.and_then(|p| marked.get(usize::from(p)).copied())
|
||||
.unwrap_or(false);
|
||||
if let Some(m) = marked.get_mut(i)
|
||||
&& !*m
|
||||
&& parent_marked
|
||||
{
|
||||
marked[i] = true;
|
||||
*m = true;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,15 +101,20 @@ impl CapabilityTable {
|
||||
}
|
||||
}
|
||||
|
||||
fn slot(&self, slot: CapSlot) -> Option<&Capability> {
|
||||
self.slots.get(slot.value() as usize)?.as_ref()
|
||||
}
|
||||
|
||||
/// Generation of an occupied slot.
|
||||
pub fn slot_generation(&self, slot: CapSlot) -> Option<Generation> {
|
||||
self.slots[slot.value() as usize].as_ref()?;
|
||||
self.slot(slot)?;
|
||||
self.generations.current(slot.value() as usize)
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, slot: CapSlot) -> Result<&mut Capability, KernelError> {
|
||||
self.slots[slot.value() as usize]
|
||||
.as_mut()
|
||||
self.slots
|
||||
.get_mut(slot.value() as usize)
|
||||
.and_then(Option::as_mut)
|
||||
.ok_or(KernelError::InvalidSlot(slot))
|
||||
}
|
||||
|
||||
@@ -121,27 +126,28 @@ impl CapabilityTable {
|
||||
}
|
||||
|
||||
pub fn get(&self, slot: CapSlot) -> Result<&Capability, KernelError> {
|
||||
let idx = slot.value() as usize;
|
||||
self.slots[idx]
|
||||
.as_ref()
|
||||
.ok_or(KernelError::InvalidSlot(slot))
|
||||
self.slot(slot).ok_or(KernelError::InvalidSlot(slot))
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, cap: Capability) -> Result<CapSlot, KernelError> {
|
||||
let idx = (0..MAX_CAPS_PER_PROCESS)
|
||||
.find(|&i| self.slots[i].is_none() && self.generations.is_usable(i))
|
||||
let generations = &self.generations;
|
||||
let (idx, free) = self
|
||||
.slots
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.find(|(i, s)| s.is_none() && generations.is_usable(*i))
|
||||
.ok_or(KernelError::NoFreeSlot)?;
|
||||
|
||||
self.slots[idx] = Some(cap);
|
||||
CapSlot::new(idx as u8).ok_or(KernelError::NoFreeSlot)
|
||||
let slot = CapSlot::new(idx as u8).ok_or(KernelError::NoFreeSlot)?;
|
||||
*free = Some(cap);
|
||||
Ok(slot)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, slot: CapSlot) -> Result<(), KernelError> {
|
||||
let idx = slot.value() as usize;
|
||||
if self.slots[idx].is_none() {
|
||||
let taken = self.slots.get_mut(idx).and_then(Option::take);
|
||||
if taken.is_none() {
|
||||
return Err(KernelError::InvalidSlot(slot));
|
||||
}
|
||||
self.slots[idx] = None;
|
||||
self.generations.advance(idx);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user