wip derivation node
This commit is contained in:
parent
6de2ef38a7
commit
d129db345f
|
@ -297,22 +297,25 @@ register_bitfields! {
|
|||
register_bitfields! {
|
||||
u128,
|
||||
CapDerivationNode [
|
||||
FirstBadged OFFSET(0) NUMBITS(1) [
|
||||
Disable = 0,
|
||||
Enable = 1
|
||||
],
|
||||
Revocable OFFSET(1) NUMBITS(1) [
|
||||
Disable = 0,
|
||||
Enable = 1
|
||||
],
|
||||
// -- 2 bits still free here --
|
||||
// Next CTE node address -- per cteInsert this is address of the entire CTE slot
|
||||
// cap derivation slots are supposedly aligned in u128 boundary (16 bytes) this means we can
|
||||
// drop bottom 4 bits from it in these fields.
|
||||
Next OFFSET(0) NUMBITS(44) [], // 16-bytes-aligned, size of canonical phys address is 48 bits
|
||||
// -- 18 bits still free here --
|
||||
Revocable OFFSET(62) NUMBITS(1) [
|
||||
Disable = 0,
|
||||
Enable = 1
|
||||
],
|
||||
FirstBadged OFFSET(63) NUMBITS(1) [
|
||||
Disable = 0,
|
||||
Enable = 1
|
||||
],
|
||||
Next OFFSET(4) NUMBITS(44) [], // 16-bytes-aligned, size of canonical phys address is 48 bits
|
||||
// -- 16 bits still free here --
|
||||
// -- New word doundary --
|
||||
// -- 4 bits still free here --
|
||||
// Prev CTE node address -- per cteInsert this is address of the entire CTE slot
|
||||
Prev OFFSET(64) NUMBITS(44) []
|
||||
// -- 20 bits still free here --
|
||||
Prev OFFSET(68) NUMBITS(44) []
|
||||
// -- 16 bits still free here --
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -513,6 +516,8 @@ pub struct DerivationTreeNode(LocalRegisterCopy<u128, CapDerivationNode::Registe
|
|||
pub enum DerivationTreeError {
|
||||
/// Previous link is invalid.
|
||||
InvalidPrev,
|
||||
/// Next link is invalid.
|
||||
InvalidNext,
|
||||
}
|
||||
|
||||
// In seL4, the MDB is stored as a doubly-linked list, representing the **preorder-DFS** through
|
||||
|
@ -525,17 +530,26 @@ pub enum DerivationTreeError {
|
|||
// To reduce the complexity of operations described above, we replace the MDB’s linked list with
|
||||
// a more suitable search data structure.
|
||||
// -- nevill-master-thesis Using Capabilities for OS Resource Management
|
||||
// sel4: mdb_node_t
|
||||
impl DerivationTreeNode {
|
||||
const ADDR_BIT_SHIFT: usize = 4;
|
||||
|
||||
fn empty() -> Self {
|
||||
Self(LocalRegisterCopy::new(0))
|
||||
}
|
||||
|
||||
// Unlike mdb_node_new we do not pass revocable and firstBadged flags here, they are enabled
|
||||
// using builder interface set_first_badged() and set_revocable().
|
||||
fn new(prevPtr: PhysAddr, nextPtr: PhysAddr) -> Self {
|
||||
Self::empty().set_prev(prevPtr).set_next(nextPtr)
|
||||
}
|
||||
|
||||
/// Get previous link in derivation tree.
|
||||
/// Previous link exists if this is a derived capability.
|
||||
///
|
||||
/// SAFETY: it is UB to get prev reference from a null Prev pointer.
|
||||
pub unsafe fn get_prev(&self) -> CapTableEntry {
|
||||
let ptr = self.0.read(CapDerivationNode::Prev) as *const CapTableEntry;
|
||||
let ptr = (self.0.read(CapDerivationNode::Prev) << ADDR_BIT_SHIFT) as *const CapTableEntry;
|
||||
(*ptr).clone()
|
||||
}
|
||||
|
||||
|
@ -549,6 +563,39 @@ impl DerivationTreeNode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_prev(&mut self, prevPtr: PhysAddr) -> Self {
|
||||
self.0
|
||||
.write(CapDerivationNode::Prev(prevPtr >> ADDR_BIT_SHIFT));
|
||||
self
|
||||
}
|
||||
|
||||
/// Get next link in derivation tree.
|
||||
/// Next link exists if this capability has derived capabilities or siblings.
|
||||
///
|
||||
/// SAFETY: it is UB to get next reference from a null Next pointer.
|
||||
pub unsafe fn get_next(&self) -> CapTableEntry {
|
||||
let ptr = (self.0.read(CapDerivationNode::Next) << ADDR_BIT_SHIFT) as *const CapTableEntry;
|
||||
(*ptr).clone()
|
||||
}
|
||||
|
||||
/// Try to get next link in derivation tree.
|
||||
/// Next link exists if this capability has derived capabilities or siblings.
|
||||
pub fn try_get_next(&self) -> Result<CapTableEntry, DerivationTreeError> {
|
||||
if self.0.read(CapDerivationNode::Next) == 0 {
|
||||
Err(DerivationTreeError::InvalidNext)
|
||||
} else {
|
||||
Ok(unsafe { self.get_next() })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_next(&mut self, nextPtr: PhysAddr) -> Self {
|
||||
self.0
|
||||
.write(CapDerivationNode::Next(nextPtr >> ADDR_BIT_SHIFT));
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder interface to modify firstBadged flag
|
||||
/// @todo Describe the firstBadged flag and what it does.
|
||||
fn set_first_badged(mut self, enable: bool) -> Self {
|
||||
self.0.modify(if enable {
|
||||
CapDerivationNode::FirstBadged::Enable
|
||||
|
@ -558,6 +605,8 @@ impl DerivationTreeNode {
|
|||
self
|
||||
}
|
||||
|
||||
/// Builder interface to modify revocable flag
|
||||
/// @todo Describe the revocable flag and what it does.
|
||||
fn set_revocable(mut self, enable: bool) -> Self {
|
||||
self.0.modify(if enable {
|
||||
CapDerivationNode::Revocable::Enable
|
||||
|
|
Loading…
Reference in New Issue