From 0aceb8fc27e54ae31cd4787c98496809bf0101a9 Mon Sep 17 00:00:00 2001 From: Berkus Decker Date: Wed, 2 Dec 2020 01:08:40 +0200 Subject: [PATCH] [wip] implement cap_table and some tests --- nucleus/src/arch/aarch64/caps.rs | 70 +++++++++++++++++++++++++------- nucleus/src/main.rs | 3 ++ 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/nucleus/src/arch/aarch64/caps.rs b/nucleus/src/arch/aarch64/caps.rs index 4787629..bc9d8e4 100644 --- a/nucleus/src/arch/aarch64/caps.rs +++ b/nucleus/src/arch/aarch64/caps.rs @@ -492,7 +492,7 @@ impl CapNodeCapability { pub struct DerivationTreeNode(LocalRegisterCopy); /// Errors that may happen in capability derivation tree operations. -#[derive(Debug, Snafu)] +#[derive(Debug, PartialEq, Snafu)] pub enum DerivationTreeError { /// Previous link is invalid. InvalidPrev, @@ -541,6 +541,15 @@ impl DerivationTreeNode { } } +/// Errors in capability operations. +#[derive(Debug, Snafu)] +pub enum CapError { + /// Unable to create capability, exact reason TBD. + CannotCreate, + /// Capability has a type incompatible with the requested operation. + InvalidCapabilityType, +} + // -- cte_t from seL4 // structures.h:140 // /* Capability table entry (CTE) */ @@ -562,6 +571,12 @@ impl fmt::Debug for CapTableEntry { } } +impl Default for CapTableEntry { + fn default() -> Self { + Self::empty() + } +} + impl CapTableEntry { /// Temporary for testing: fn empty() -> CapTableEntry { @@ -572,15 +587,6 @@ impl CapTableEntry { } } -/// Errors in capability operations. -#[derive(Debug, Snafu)] -pub enum CapError { - /// Unable to create capability, exact reason TBD. - CannotCreate, - /// Capability has a type incompatible with the requested operation. - InvalidCapabilityType, -} - // @note src and dest are swapped here, compared to seL4 api /* struct CapNodePath { @@ -594,7 +600,7 @@ struct CapNodeRootedPath { } // @todo just use CapNodeCap -//struct CapNodeConfig { +//struct CapNodeConfig { <-- for each CapTable we would need these.. // guard: u32, // guard_size: u32, //} @@ -640,18 +646,52 @@ impl CapNode { } }*/ -//struct CapSpace {} -- capspace is collection of capnodes in a single address space? -//impl CapNode for CapSpace {} +/// Structure holding a number of capabilities. +// In seL4 the capnode is capability to an object called CapTable btw: +// case seL4_CapTableObject: +// return cap_cnode_cap_new(userSize, 0, 0, CTE_REF(regionBase)); +struct CapTable +where + [CapTableEntry; 1 << SIZE_BITS]: Sized, +{ + items: [CapTableEntry; 1 << SIZE_BITS], +} + +/// Conceptually a thread’s CapSpace is the portion of the directed graph that is reachable +/// starting with the CapNode capability that is its CapSpace root. +struct CapSpace { + // cap_space_root: CapNodePath, +} +//impl CapNode for CapSpace {} -- ? #[cfg(test)] mod tests { - // use super::*; + use super::*; + + #[test_case] + fn create_empty_cap_table() { + let table = CapTable::<5> { + items: Default::default(), + }; + assert_eq!(table.items[0].capability, NullCapability::new().into()); + assert_eq!(table.items[31].capability, NullCapability::new().into()); + } #[test_case] fn first_capability_derivation_has_no_prev_link() { let entry = CapTableEntry::empty(); - assert_eq!(entry.derivation_node.try_get_prev(), Err(DerivationTreeError::InvalidPrev)); + assert!(entry + .derivation_node + .try_get_prev() + .contains_err(&DerivationTreeError::InvalidPrev)); } + + // Impl strategy + // 1. Make capabilities list + // 2. Fill it with capabilities + // 3. Test capability manipulation functions - mint/clone/revoke + // 4. Validate capability path, capability contents and capability derivation chain at each step + // 5. Start with Untyped capabilities and implement Retype() } // @todo Use bitmatch over cap Type field? diff --git a/nucleus/src/main.rs b/nucleus/src/main.rs index 841b8e2..459c6cb 100644 --- a/nucleus/src/main.rs +++ b/nucleus/src/main.rs @@ -15,6 +15,7 @@ #![feature(allocator_api)] #![feature(ptr_internals)] #![feature(format_args_nl)] +#![feature(result_contains_err)] #![feature(nonnull_slice_from_raw_parts)] #![feature(custom_test_frameworks)] #![test_runner(crate::tests::test_runner)] @@ -24,6 +25,8 @@ #![allow(dead_code)] // While working on features, some code may remain unused // repr128 is not yet stable #![feature(repr128)] +#![feature(const_generics)] +#![feature(const_evaluatable_checked)] // see https://github.com/rust-lang/rust/issues/68436 #![allow(incomplete_features)] #[cfg(not(target_arch = "aarch64"))]