pub struct PageTableOwner<C: PageTableConfig>(pub OwnerSubtree<C>);Tuple Fields§
§0: OwnerSubtree<C>Implementations§
Source§impl<C: PageTableConfig> PageTableOwner<C>
impl<C: PageTableConfig> PageTableOwner<C>
Sourcepub uninterp fn new_cursor_owner_spec<'rcu>(self) -> (Self, CursorOwner<'rcu, C>)
pub uninterp fn new_cursor_owner_spec<'rcu>(self) -> (Self, CursorOwner<'rcu, C>)
Source§impl<C: PageTableConfig> PageTableOwner<C>
impl<C: PageTableConfig> PageTableOwner<C>
Sourcepub open spec fn view_rec(self, path: TreePath<NR_ENTRIES>) -> Set<Mapping>
pub open spec fn view_rec(self, path: TreePath<NR_ENTRIES>) -> Set<Mapping>
{
if self.0.value.is_frame() {
let vaddr = vaddr(path);
let pt_level = INC_LEVELS - path.len();
let page_size = page_size(pt_level as PagingLevel);
set![
Mapping { va_range : Range { start : vaddr, end : (vaddr + page_size) as
Vaddr }, pa_range : Range { start : self.0.value.frame.unwrap().mapped_pa,
end : (self.0.value.frame.unwrap().mapped_pa + page_size) as Paddr, },
page_size : page_size, property : self.0.value.frame.unwrap().prop, }
]
} else if self.0.value.is_node() && path.len() < INC_LEVELS - 1 {
Set::new(|m: Mapping| {
exists |i: int| {
0 <= i < self.0.children.len() && self.0.children[i] is Some
&& PageTableOwner(self.0.children[i].unwrap())
.view_rec(path.push_tail(i as usize))
.contains(m)
}
})
} else {
set![]
}
}Sourcepub proof fn view_rec_contains(self, path: TreePath<NR_ENTRIES>, m: Mapping)
pub proof fn view_rec_contains(self, path: TreePath<NR_ENTRIES>, m: Mapping)
requires
self.0.inv(),path.len() < INC_LEVELS - 1,path.len() == self.0.level,self.view_rec(path).contains(m),self.0.value.is_node(),ensuresexists |i: int| {
0 <= i < self.0.children.len() && self.0.children[i] is Some
&& PageTableOwner(self.0.children[i].unwrap())
.view_rec(path.push_tail(i as usize))
.contains(m)
},Sourcepub proof fn view_rec_contains_choose(
self,
path: TreePath<NR_ENTRIES>,
m: Mapping,
) -> i : int
pub proof fn view_rec_contains_choose( self, path: TreePath<NR_ENTRIES>, m: Mapping, ) -> i : int
requires
self.0.inv(),path.len() < INC_LEVELS - 1,path.len() == self.0.level,self.view_rec(path).contains(m),self.0.value.is_node(),ensures0 <= i < self.0.children.len() && self.0.children[i] is Some
&& PageTableOwner(self.0.children[i].unwrap())
.view_rec(path.push_tail(i as usize))
.contains(m),Sourcepub proof fn view_rec_vaddr_range(self, path: TreePath<NR_ENTRIES>, m: Mapping)
pub proof fn view_rec_vaddr_range(self, path: TreePath<NR_ENTRIES>, m: Mapping)
requires
self.0.inv(),path.len() <= INC_LEVELS - 1,path.len() == self.0.level,self.view_rec(path).contains(m),ensuresvaddr(path) <= m.va_range.start < m.va_range.end
<= vaddr(path) + page_size(path.len() as PagingLevel),Sourcepub proof fn view_rec_disjoint_vaddrs(
self,
path: TreePath<NR_ENTRIES>,
m1: Mapping,
m2: Mapping,
)
pub proof fn view_rec_disjoint_vaddrs( self, path: TreePath<NR_ENTRIES>, m1: Mapping, m2: Mapping, )
requires
self.0.inv(),path.len() <= INC_LEVELS - 1,path.len() == self.0.level,self.view_rec(path).contains(m1),self.view_rec(path).contains(m2),m1 != m2,ensuresm1.va_range.end <= m2.va_range.start || m2.va_range.end <= m1.va_range.start,Sourcepub proof fn view_rec_absent_empty(self, path: TreePath<NR_ENTRIES>)
pub proof fn view_rec_absent_empty(self, path: TreePath<NR_ENTRIES>)
requires
self.0.inv(),self.0.value.is_absent(),path.len() <= INC_LEVELS - 1,ensuresself.view_rec(path) =~= set![],An absent entry contributes no mappings - view_rec returns the empty set.
Sourcepub open spec fn relate_region_pred(
regions: MetaRegionOwners,
) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
pub open spec fn relate_region_pred( regions: MetaRegionOwners, ) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
{ |entry: EntryOwner<C>, path: TreePath<NR_ENTRIES>| entry.relate_region(regions) }Sourcepub open spec fn relate_region(self, regions: MetaRegionOwners) -> bool
pub open spec fn relate_region(self, regions: MetaRegionOwners) -> bool
{ self.0.tree_predicate_map(self.0.value.path, Self::relate_region_pred(regions)) }Sourcepub open spec fn path_tracked_pred(
regions: MetaRegionOwners,
) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
pub open spec fn path_tracked_pred( regions: MetaRegionOwners, ) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
{
|entry: EntryOwner<C>, path: TreePath<NR_ENTRIES>| {
entry.meta_slot_paddr() is Some
==> {
&&& regions
.slot_owners
.contains_key(frame_to_index(entry.meta_slot_paddr().unwrap()))
&&& regions
.slot_owners[frame_to_index(entry.meta_slot_paddr().unwrap())]
.path_if_in_pt is Some
}
}
}Predicate: all nodes in the tree have their paths tracked in regions
Sourcepub open spec fn relate_region_tracked_pred(
regions: MetaRegionOwners,
) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
pub open spec fn relate_region_tracked_pred( regions: MetaRegionOwners, ) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
{
|entry: EntryOwner<C>, path: TreePath<NR_ENTRIES>| {
&&& entry.meta_slot_paddr() is Some
&&& regions
.slot_owners
.contains_key(frame_to_index(entry.meta_slot_paddr().unwrap()))
&&& regions
.slot_owners[frame_to_index(entry.meta_slot_paddr().unwrap())]
.path_if_in_pt is Some
&&& regions
.slot_owners[frame_to_index(entry.meta_slot_paddr().unwrap())]
.path_if_in_pt
.unwrap() == path
}
}Sourcepub open spec fn path_correct_pred() -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
pub open spec fn path_correct_pred() -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
{ |entry: EntryOwner<C>, path: TreePath<NR_ENTRIES>| { entry.path == path } }Sourcepub open spec fn is_prefix_of<const N: usize>(
prefix: TreePath<N>,
path: TreePath<N>,
) -> bool
pub open spec fn is_prefix_of<const N: usize>( prefix: TreePath<N>, path: TreePath<N>, ) -> bool
{
&&& prefix.len() <= path.len()
&&& forall |i: int| 0 <= i < prefix.len() ==> prefix.index(i) == path.index(i)
}Spec function: path1 is a prefix of path2
Sourcepub proof fn prefix_transitive<const N: usize>(
p1: TreePath<N>,
p2: TreePath<N>,
p3: TreePath<N>,
)
pub proof fn prefix_transitive<const N: usize>( p1: TreePath<N>, p2: TreePath<N>, p3: TreePath<N>, )
requires
Self::is_prefix_of(p1, p2),Self::is_prefix_of(p2, p3),ensuresSelf::is_prefix_of(p1, p3),Transitivity of is_prefix_of
Sourcepub proof fn prefix_push_different_indices(
prefix: TreePath<NR_ENTRIES>,
path: TreePath<NR_ENTRIES>,
i: usize,
j: usize,
)
pub proof fn prefix_push_different_indices( prefix: TreePath<NR_ENTRIES>, path: TreePath<NR_ENTRIES>, i: usize, j: usize, )
requires
prefix.inv(),path.inv(),i != j,Self::is_prefix_of(prefix.push_tail(i), path),ensures!Self::is_prefix_of(prefix.push_tail(j), path),Sourcepub open spec fn is_at_pred(
entry: EntryOwner<C>,
path: TreePath<NR_ENTRIES>,
) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
pub open spec fn is_at_pred( entry: EntryOwner<C>, path: TreePath<NR_ENTRIES>, ) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
{
|entry0: EntryOwner<C>, path0: TreePath<NR_ENTRIES>| {
path0 == path ==> entry0 == entry
}
}Sourcepub open spec fn path_in_tree_pred(
path: TreePath<NR_ENTRIES>,
) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
pub open spec fn path_in_tree_pred( path: TreePath<NR_ENTRIES>, ) -> FnSpec<(EntryOwner<C>, TreePath<NR_ENTRIES>), bool>
{
|entry: EntryOwner<C>, path0: TreePath<NR_ENTRIES>| {
Self::is_prefix_of(path0, path) ==> (!entry.is_node() ==> path == path0)
}
}Sourcepub proof fn is_at_pred_eq(
path: TreePath<NR_ENTRIES>,
entry1: EntryOwner<C>,
entry2: EntryOwner<C>,
)
pub proof fn is_at_pred_eq( path: TreePath<NR_ENTRIES>, entry1: EntryOwner<C>, entry2: EntryOwner<C>, )
requires
entry1.inv(),OwnerSubtree::implies(Self::is_at_pred(entry1, path), Self::is_at_pred(entry2, path)),ensuresentry1 == entry2,Sourcepub proof fn is_at_holds_when_on_wrong_path(
subtree: OwnerSubtree<C>,
root_path: TreePath<NR_ENTRIES>,
dest_path: TreePath<NR_ENTRIES>,
entry: EntryOwner<C>,
)
pub proof fn is_at_holds_when_on_wrong_path( subtree: OwnerSubtree<C>, root_path: TreePath<NR_ENTRIES>, dest_path: TreePath<NR_ENTRIES>, entry: EntryOwner<C>, )
requires
subtree.inv(),dest_path.inv(),!Self::is_prefix_of(root_path, dest_path),root_path.len() <= INC_LEVELS - 1,root_path.len() == subtree.level,ensuressubtree.tree_predicate_map(root_path, Self::is_at_pred(entry, dest_path)),Sourcepub proof fn path_in_tree_holds_when_on_wrong_path(
subtree: OwnerSubtree<C>,
root_path: TreePath<NR_ENTRIES>,
dest_path: TreePath<NR_ENTRIES>,
)
pub proof fn path_in_tree_holds_when_on_wrong_path( subtree: OwnerSubtree<C>, root_path: TreePath<NR_ENTRIES>, dest_path: TreePath<NR_ENTRIES>, )
requires
subtree.inv(),dest_path.inv(),!Self::is_prefix_of(root_path, dest_path),root_path.len() <= INC_LEVELS - 1,root_path.len() == subtree.level,ensuressubtree.tree_predicate_map(root_path, Self::path_in_tree_pred(dest_path)),Counterintuitive: the predicate is vacuously true when the path is not a prefix of the target path, because it is actually a liveness property: if we keep following the path, we will eventually reach it. This covers when we are not following it.
Sourcepub proof fn is_at_eq_rec(
subtree: OwnerSubtree<C>,
root_path: TreePath<NR_ENTRIES>,
dest_path: TreePath<NR_ENTRIES>,
entry1: EntryOwner<C>,
entry2: EntryOwner<C>,
)
pub proof fn is_at_eq_rec( subtree: OwnerSubtree<C>, root_path: TreePath<NR_ENTRIES>, dest_path: TreePath<NR_ENTRIES>, entry1: EntryOwner<C>, entry2: EntryOwner<C>, )
requires
subtree.inv(),dest_path.inv(),root_path.inv(),Self::is_prefix_of(root_path, dest_path),root_path.len() <= INC_LEVELS - 1,root_path.len() == subtree.level,subtree.tree_predicate_map(root_path, Self::path_in_tree_pred(dest_path)),subtree.tree_predicate_map(root_path, Self::is_at_pred(entry1, dest_path)),subtree.tree_predicate_map(root_path, Self::is_at_pred(entry2, dest_path)),ensuresentry1 == entry2,Sourcepub proof fn view_rec_inversion(
self,
path: TreePath<NR_ENTRIES>,
regions: MetaRegionOwners,
m: Mapping,
) -> entry : EntryOwner<C>
pub proof fn view_rec_inversion( self, path: TreePath<NR_ENTRIES>, regions: MetaRegionOwners, m: Mapping, ) -> entry : EntryOwner<C>
requires
self.0.inv(),path.len() == self.0.level,self.view_rec(path).contains(m),self.0.tree_predicate_map(path, Self::path_correct_pred()),self.0.tree_predicate_map(path, Self::relate_region_tracked_pred(regions)),ensuresSelf::is_prefix_of(path, entry.path),regions.slot_owners[frame_to_index(m.pa_range.start)].path_if_in_pt == Some(entry.path),m.va_range.start == vaddr(entry.path),m.page_size == page_size((INC_LEVELS - entry.path.len()) as PagingLevel),entry.is_frame(),m.property == entry.frame.unwrap().prop,self.0.tree_predicate_map(path, Self::is_at_pred(entry, entry.path)),self.0.tree_predicate_map(path, Self::path_in_tree_pred(entry.path)),entry.inv(),Sourcepub proof fn view_rec_inversion_unique(
self,
path: TreePath<NR_ENTRIES>,
regions: MetaRegionOwners,
m1: Mapping,
m2: Mapping,
)
pub proof fn view_rec_inversion_unique( self, path: TreePath<NR_ENTRIES>, regions: MetaRegionOwners, m1: Mapping, m2: Mapping, )
requires
self.0.inv(),path.len() <= INC_LEVELS - 1,path.len() == self.0.level,self.view_rec(path).contains(m1),self.view_rec(path).contains(m2),m1.pa_range.start == m2.pa_range.start,m1.inv(),m2.inv(),self.0.tree_predicate_map(path, Self::path_tracked_pred(regions)),self.0.tree_predicate_map(path, Self::path_correct_pred()),self.0.tree_predicate_map(path, Self::relate_region_tracked_pred(regions)),ensuresm1 == m2,Trait Implementations§
Source§impl<C: PageTableConfig> Inv for PageTableOwner<C>
impl<C: PageTableConfig> Inv for PageTableOwner<C>
Source§impl<C: PageTableConfig> View for PageTableOwner<C>
impl<C: PageTableConfig> View for PageTableOwner<C>
Auto Trait Implementations§
impl<C> Freeze for PageTableOwner<C>
impl<C> !RefUnwindSafe for PageTableOwner<C>
impl<C> Send for PageTableOwner<C>
impl<C> Sync for PageTableOwner<C>
impl<C> Unpin for PageTableOwner<C>
impl<C> UnwindSafe for PageTableOwner<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