From d129db345f55791707e5e8a61b3e4598d18b4ca1 Mon Sep 17 00:00:00 2001 From: Berkus Decker Date: Sun, 13 Dec 2020 19:40:55 +0200 Subject: [PATCH] wip derivation node --- nucleus/src/arch/aarch64/caps.rs | 75 ++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/nucleus/src/arch/aarch64/caps.rs b/nucleus/src/arch/aarch64/caps.rs index 337ab8b..b5fcd02 100644 --- a/nucleus/src/arch/aarch64/caps.rs +++ b/nucleus/src/arch/aarch64/caps.rs @@ -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 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 { + 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