feat(kernel): shared ABI decoder+proofs, no-panic gate, syscall storm, kani on shrunk kernel
This commit is contained in:
@@ -18,7 +18,7 @@ mod proofs;
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
/// Frames the kernel can track. The board's user pool must fit.
|
||||
pub const MAX_FRAMES: usize = 4096;
|
||||
pub const MAX_FRAMES: usize = if cfg!(kani) { 6 } else { 4096 };
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FrameUse {
|
||||
@@ -88,13 +88,26 @@ impl<const N: usize> FrameTable<N> {
|
||||
self.base.offset(idx)
|
||||
}
|
||||
|
||||
/// The frames that exist (`total` is clamped to `N` at construction).
|
||||
fn live(&self) -> &[Option<FrameUse>] {
|
||||
self.frames.get(..self.total).unwrap_or(&[])
|
||||
}
|
||||
|
||||
fn live_mut(&mut self) -> &mut [Option<FrameUse>] {
|
||||
self.frames.get_mut(..self.total).unwrap_or(&mut [])
|
||||
}
|
||||
|
||||
pub fn get(&self, pa: PhysicalAddress) -> Option<&FrameUse> {
|
||||
self.frames[self.index_of(pa)?].as_ref()
|
||||
self.frames.get(self.index_of(pa)?)?.as_ref()
|
||||
}
|
||||
|
||||
pub fn alloc(&mut self, usage: FrameUse) -> Option<PhysicalAddress> {
|
||||
let idx = self.frames[..self.total].iter().position(Option::is_none)?;
|
||||
self.frames[idx] = Some(usage);
|
||||
let (idx, slot) = self
|
||||
.live_mut()
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.find(|(_, f)| f.is_none())?;
|
||||
*slot = Some(usage);
|
||||
self.free -= 1;
|
||||
Some(self.address_of(idx))
|
||||
}
|
||||
@@ -110,8 +123,8 @@ impl<const N: usize> FrameTable<N> {
|
||||
}
|
||||
let mut run = 0;
|
||||
let mut start = None;
|
||||
for idx in 0..self.total {
|
||||
if self.frames[idx].is_some() {
|
||||
for (idx, f) in self.live().iter().enumerate() {
|
||||
if f.is_some() {
|
||||
run = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -122,8 +135,9 @@ impl<const N: usize> FrameTable<N> {
|
||||
}
|
||||
}
|
||||
let start = start?;
|
||||
for i in 0..count {
|
||||
self.frames[start + i] = Some(usage(i));
|
||||
let run = self.live_mut().get_mut(start..start + count)?;
|
||||
for (i, f) in run.iter_mut().enumerate() {
|
||||
*f = Some(usage(i));
|
||||
}
|
||||
self.free -= count;
|
||||
Some(self.address_of(start))
|
||||
@@ -132,7 +146,7 @@ impl<const N: usize> FrameTable<N> {
|
||||
/// Frees an allocated frame and reports what it was used for.
|
||||
pub fn free(&mut self, pa: PhysicalAddress) -> Option<FrameUse> {
|
||||
let idx = self.index_of(pa)?;
|
||||
let usage = self.frames[idx].take()?;
|
||||
let usage = self.frames.get_mut(idx)?.take()?;
|
||||
self.free += 1;
|
||||
Some(usage)
|
||||
}
|
||||
@@ -140,7 +154,11 @@ impl<const N: usize> FrameTable<N> {
|
||||
/// Changes the use of an allocated frame (e.g. moving it to another
|
||||
/// process). Fails on free frames.
|
||||
pub fn retag(&mut self, pa: PhysicalAddress, usage: FrameUse) -> bool {
|
||||
match self.index_of(pa).and_then(|i| self.frames[i].as_mut()) {
|
||||
match self
|
||||
.index_of(pa)
|
||||
.and_then(|i| self.frames.get_mut(i))
|
||||
.and_then(Option::as_mut)
|
||||
{
|
||||
Some(slot) => {
|
||||
*slot = usage;
|
||||
true
|
||||
@@ -159,22 +177,19 @@ impl<const N: usize> FrameTable<N> {
|
||||
return None;
|
||||
}
|
||||
let page = u32::try_from(va.raw() / PAGE_SIZE).ok()?;
|
||||
self.frames[..self.total]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(idx, f)| match f {
|
||||
Some(FrameUse::User {
|
||||
owner: o,
|
||||
page: p,
|
||||
perms,
|
||||
}) if *o == owner && *p == page => Some((self.address_of(idx), *perms)),
|
||||
_ => None,
|
||||
})
|
||||
self.live().iter().enumerate().find_map(|(idx, f)| match f {
|
||||
Some(FrameUse::User {
|
||||
owner: o,
|
||||
page: p,
|
||||
perms,
|
||||
}) if *o == owner && *p == page => Some((self.address_of(idx), *perms)),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Every allocated frame and its use.
|
||||
pub fn iter(&self) -> impl Iterator<Item = (PhysicalAddress, &FrameUse)> + '_ {
|
||||
self.frames[..self.total]
|
||||
self.live()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, f)| f.as_ref().map(|u| (self.address_of(idx), u)))
|
||||
@@ -185,7 +200,7 @@ impl<const N: usize> FrameTable<N> {
|
||||
&self,
|
||||
owner: ProcessId,
|
||||
) -> impl Iterator<Item = (PhysicalAddress, VirtualAddress)> + '_ {
|
||||
self.frames[..self.total]
|
||||
self.live()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(move |(idx, f)| match f {
|
||||
@@ -201,7 +216,7 @@ impl<const N: usize> FrameTable<N> {
|
||||
/// how many were freed.
|
||||
pub fn free_owned_by(&mut self, owner: ProcessId) -> usize {
|
||||
let mut freed = 0;
|
||||
for slot in &mut self.frames[..self.total] {
|
||||
for slot in self.live_mut().iter_mut() {
|
||||
let owned = matches!(
|
||||
slot,
|
||||
Some(FrameUse::User { owner: o, .. } | FrameUse::PageTable { owner: o }) if *o == owner
|
||||
|
||||
Reference in New Issue
Block a user