pub struct EntryOwner<C: PageTableConfig> {
pub node: Option<NodeOwner<C>>,
pub frame: Option<FrameEntryOwner>,
pub locked: Option<Ghost<Seq<FrameView<C>>>>,
pub absent: bool,
pub in_scope: bool,
pub path: TreePath<NR_ENTRIES>,
pub parent_level: PagingLevel,
}Fields§
§node: Option<NodeOwner<C>>§frame: Option<FrameEntryOwner>§locked: Option<Ghost<Seq<FrameView<C>>>>§absent: bool§in_scope: bool§path: TreePath<NR_ENTRIES>§parent_level: PagingLevelImplementations§
Source§impl<C: PageTableConfig> EntryOwner<C>
impl<C: PageTableConfig> EntryOwner<C>
Sourcepub open spec fn from_pte_regions_spec(
self,
regions: MetaRegionOwners,
) -> MetaRegionOwners
pub open spec fn from_pte_regions_spec( self, regions: MetaRegionOwners, ) -> MetaRegionOwners
{
if self.is_node() {
let index = frame_to_index(self.meta_slot_paddr().unwrap());
let old_slot = regions.slot_owners[index];
let new_slot = MetaSlotOwner {
raw_count: 0usize,
..old_slot
};
MetaRegionOwners {
slots: regions.slots.insert(index, self.node.unwrap().meta_perm.points_to),
slot_owners: regions.slot_owners.insert(index, new_slot),
}
} else {
regions
}
}Sourcepub open spec fn into_pte_regions_spec(
self,
regions: MetaRegionOwners,
) -> MetaRegionOwners
pub open spec fn into_pte_regions_spec( self, regions: MetaRegionOwners, ) -> MetaRegionOwners
{
if self.is_node() {
let index = frame_to_index(self.meta_slot_paddr().unwrap());
let old_slot = regions.slot_owners[index];
let new_slot = MetaSlotOwner {
raw_count: (old_slot.raw_count + 1) as usize,
..old_slot
};
MetaRegionOwners {
slots: regions.slots,
slot_owners: regions.slot_owners.insert(index, new_slot),
..regions
}
} else {
regions
}
}Sourcepub open spec fn into_pte_owner_spec(self) -> EntryOwner<C>
pub open spec fn into_pte_owner_spec(self) -> EntryOwner<C>
{
EntryOwner {
in_scope: false,
..self
}
}Sourcepub open spec fn from_pte_owner_spec(self) -> EntryOwner<C>
pub open spec fn from_pte_owner_spec(self) -> EntryOwner<C>
{
EntryOwner {
in_scope: true,
..self
}
}Sourcepub open spec fn pte_invariants(self, pte: C::E, regions: MetaRegionOwners) -> bool
pub open spec fn pte_invariants(self, pte: C::E, regions: MetaRegionOwners) -> bool
{
&&& self.inv()
&&& regions.inv()
&&& self.match_pte(pte, self.parent_level)
&&& self.relate_region(regions)
&&& !self.in_scope
}This is equivalent to the other invariants relations, combining the inv predicates for each
object and the well-formedness relations between them.
Source§impl<C: PageTableConfig> EntryOwner<C>
impl<C: PageTableConfig> EntryOwner<C>
Sourcepub open spec fn new_absent_spec(
path: TreePath<NR_ENTRIES>,
parent_level: PagingLevel,
) -> Self
pub open spec fn new_absent_spec( path: TreePath<NR_ENTRIES>, parent_level: PagingLevel, ) -> Self
{
EntryOwner {
node: None,
frame: None,
locked: None,
absent: true,
in_scope: true,
path,
parent_level,
}
}Sourcepub open spec fn new_frame_spec(
paddr: Paddr,
path: TreePath<NR_ENTRIES>,
parent_level: PagingLevel,
prop: PageProperty,
) -> Self
pub open spec fn new_frame_spec( paddr: Paddr, path: TreePath<NR_ENTRIES>, parent_level: PagingLevel, prop: PageProperty, ) -> Self
{
EntryOwner {
node: None,
frame: Some(FrameEntryOwner {
mapped_pa: paddr,
size: page_size(parent_level),
prop,
}),
locked: None,
absent: false,
in_scope: true,
path,
parent_level,
}
}Sourcepub open spec fn new_node_spec(node: NodeOwner<C>, path: TreePath<NR_ENTRIES>) -> Self
pub open spec fn new_node_spec(node: NodeOwner<C>, path: TreePath<NR_ENTRIES>) -> Self
{
EntryOwner {
node: Some(node),
frame: None,
locked: None,
absent: false,
in_scope: true,
path,
parent_level: (node.level + 1) as PagingLevel,
}
}Sourcepub proof fn new_absent(path: TreePath<NR_ENTRIES>, parent_level: PagingLevel) -> tracked Self
pub proof fn new_absent(path: TreePath<NR_ENTRIES>, parent_level: PagingLevel) -> tracked Self
Sourcepub proof fn new_frame(
paddr: Paddr,
path: TreePath<NR_ENTRIES>,
parent_level: PagingLevel,
prop: PageProperty,
) -> tracked Self
pub proof fn new_frame( paddr: Paddr, path: TreePath<NR_ENTRIES>, parent_level: PagingLevel, prop: PageProperty, ) -> tracked Self
Sourcepub open spec fn match_pte(self, pte: C::E, parent_level: PagingLevel) -> bool
pub open spec fn match_pte(self, pte: C::E, parent_level: PagingLevel) -> bool
{
&&& pte.paddr() % PAGE_SIZE == 0
&&& pte.paddr() < MAX_PADDR
&&& !pte.is_present() ==> { self.is_absent() }
&&& pte.is_present() && !pte.is_last(parent_level)
==> {
&&& self.is_node()
&&& meta_to_frame(self.node.unwrap().meta_perm.addr()) == pte.paddr()
}
&&& pte.is_present() && pte.is_last(parent_level)
==> {
&&& self.is_frame()
&&& self.frame.unwrap().mapped_pa == pte.paddr()
&&& self.frame.unwrap().prop == pte.prop()
}
}Sourcepub proof fn absent_match_pte(owner: Self, pte: C::E, parent_level: PagingLevel)
pub proof fn absent_match_pte(owner: Self, pte: C::E, parent_level: PagingLevel)
requires
owner.is_absent(),pte == C::E::new_absent_spec(),pte.paddr() % PAGE_SIZE == 0,pte.paddr() < MAX_PADDR,ensuresowner.match_pte(pte, parent_level),When owner is absent and pte is the absent PTE with valid paddr, match_pte holds.
Sourcepub open spec fn expected_raw_count(self) -> usize
pub open spec fn expected_raw_count(self) -> usize
{ if self.in_scope { 0 } else { 1 } }Sourcepub open spec fn relate_region(self, regions: MetaRegionOwners) -> bool
pub open spec fn relate_region(self, regions: MetaRegionOwners) -> bool
{
if self.is_node() {
let idx = frame_to_index(self.meta_slot_paddr().unwrap());
&&& regions.slot_owners[idx].inner_perms.ref_count.value() != REF_COUNT_UNUSED
&&& regions.slot_owners[idx].raw_count == self.expected_raw_count()
&&& regions.slot_owners[idx].self_addr == self.node.unwrap().meta_perm.addr()
&&& self.node.unwrap().meta_perm.points_to.value().wf(regions.slot_owners[idx])
&&& regions.slot_owners[idx].path_if_in_pt is Some
==> regions.slot_owners[idx].path_if_in_pt.unwrap() == self.path
} else if self.is_frame() {
regions
.slot_owners[frame_to_index(self.meta_slot_paddr().unwrap())]
.path_if_in_pt is Some
==> regions
.slot_owners[frame_to_index(self.meta_slot_paddr().unwrap())]
.path_if_in_pt
.unwrap() == self.path
} else {
true
}
}Sourcepub open spec fn meta_slot_paddr(self) -> Option<Paddr>
pub open spec fn meta_slot_paddr(self) -> Option<Paddr>
{
if self.is_node() {
Some(meta_to_frame(self.node.unwrap().meta_perm.addr()))
} else if self.is_frame() {
Some(self.frame.unwrap().mapped_pa)
} else {
None
}
}Sourcepub open spec fn meta_slot_paddr_neq(self, other: Self) -> bool
pub open spec fn meta_slot_paddr_neq(self, other: Self) -> bool
{
self.meta_slot_paddr() is Some
==> (other.meta_slot_paddr() is Some
==> self.meta_slot_paddr().unwrap() != other.meta_slot_paddr().unwrap())
}Sourcepub proof fn nodes_different_paths_different_addrs(
self,
other: Self,
regions: MetaRegionOwners,
)
pub proof fn nodes_different_paths_different_addrs( self, other: Self, regions: MetaRegionOwners, )
requires
self.is_node(),other.is_node(),self.relate_region(regions),self.meta_slot_paddr() is Some
==> regions
.slot_owners[frame_to_index(self.meta_slot_paddr().unwrap())]
.path_if_in_pt is Some,other.meta_slot_paddr() is Some
==> regions
.slot_owners[frame_to_index(other.meta_slot_paddr().unwrap())]
.path_if_in_pt is Some,other.relate_region(regions),self.path != other.path,ensuresself.node.unwrap().meta_perm.addr() != other.node.unwrap().meta_perm.addr(),Two nodes satisfying relate_region with the same regions have different addresses if and only if they have different paths.
Trait Implementations§
Source§impl<C: PageTableConfig> Inv for EntryOwner<C>
impl<C: PageTableConfig> Inv for EntryOwner<C>
Source§open spec fn inv(self) -> bool
open spec fn inv(self) -> bool
{
&&& self.node is Some
==> {
&&& self.frame is None
&&& self.locked is None
&&& self.node.unwrap().inv()
&&& !self.absent
}
&&& self.frame is Some
==> {
&&& self.node is None
&&& self.locked is None
&&& !self.absent
&&& self.frame.unwrap().mapped_pa % PAGE_SIZE == 0
&&& self.frame.unwrap().mapped_pa < MAX_PADDR
&&& self.frame.unwrap().size == page_size(self.parent_level)
}
&&& self.locked is Some
==> {
&&& self.frame is None
&&& self.node is None
&&& !self.absent
}
&&& self.path.inv()
}Source§impl<C: PageTableConfig> InvView for EntryOwner<C>
impl<C: PageTableConfig> InvView for EntryOwner<C>
Source§proof fn view_preserves_inv(self)
proof fn view_preserves_inv(self)
Source§impl<C: PageTableConfig, const L: usize> TreeNodeValue<L> for EntryOwner<C>
impl<C: PageTableConfig, const L: usize> TreeNodeValue<L> for EntryOwner<C>
Source§open spec fn default(lv: nat) -> Self
open spec fn default(lv: nat) -> Self
{
Self {
in_scope: false,
path: TreePath::new(Seq::empty()),
parent_level: (INC_LEVELS - lv + 1) as PagingLevel,
node: None,
frame: None,
locked: None,
absent: true,
}
}Source§proof fn default_preserves_inv()
proof fn default_preserves_inv()
Source§proof fn default_preserves_la_inv()
proof fn default_preserves_la_inv()
Source§open spec fn rel_children(self, i: int, child: Option<Self>) -> bool
open spec fn rel_children(self, i: int, child: Option<Self>) -> bool
{
if self.is_node() {
&&& child is Some
&&& child.unwrap().path.len() == self.node.unwrap().tree_level + 1
&&& child
.unwrap()
.match_pte(
self.node.unwrap().children_perm.value()[i],
self.node.unwrap().level,
)
&&& child.unwrap().path == self.path.push_tail(i as usize)
} else {
&&& child is None
}
}Source§proof fn default_preserves_rel_children(self, lv: nat)
proof fn default_preserves_rel_children(self, lv: nat)
Source§impl<C: PageTableConfig> View for EntryOwner<C>
impl<C: PageTableConfig> View for EntryOwner<C>
Source§open spec fn view(&self) -> <Self as View>::V
open spec fn view(&self) -> <Self as View>::V
{
if let Some(frame) = self.frame {
EntryView::Leaf {
leaf: LeafPageTableEntryView {
map_va: vaddr(self.path) as int,
map_to_pa: frame.mapped_pa as int,
level: self.path.len() as u8,
prop: frame.prop,
phantom: PhantomData,
},
}
} else if let Some(node) = self.node {
EntryView::Intermediate {
node: IntermediatePageTableEntryView {
map_va: vaddr(self.path) as int,
map_to_pa: meta_to_frame(node.meta_perm.addr()) as int,
level: self.path.len() as u8,
phantom: PhantomData,
},
}
} else if let Some(view) = self.locked {
EntryView::LockedSubtree {
views: view@,
}
} else {
EntryView::Absent
}
}type V = EntryView<C>
Auto Trait Implementations§
impl<C> Freeze for EntryOwner<C>
impl<C> !RefUnwindSafe for EntryOwner<C>
impl<C> Send for EntryOwner<C>
impl<C> Sync for EntryOwner<C>
impl<C> Unpin for EntryOwner<C>
impl<C> UnwindSafe for EntryOwner<C>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more