ostd/specs/mm/page_table/node/
child.rs1use vstd::prelude::*;
2use vstd_extra::ownership::*;
3
4use crate::specs::mm::frame::{mapping::meta_to_index, meta_region_owners::MetaRegionOwners};
5
6use crate::arch::mm::PagingConsts;
7use crate::mm::{
8 Paddr, PagingConstsTrait, PagingLevel, Vaddr, frame::*, page_prop::PageProperty, page_table::*,
9};
10
11verus! {
12
13impl<C: PageTableConfig> OwnerOf for Child<C> {
14 type Owner = EntryOwner<C>;
15
16 open spec fn wf(self, owner: Self::Owner) -> bool {
17 match self {
18 Self::PageTable(node) => {
19 &&& owner.is_node()
20 &&& node.ptr.addr() == owner.node().slot_vaddr()
21 &&& node.index() == meta_to_index(node.ptr.addr())
22 &&& node.ptr_inv()
23 },
24 Self::Frame(paddr, level, prop) => {
25 &&& owner.is_frame()
26 &&& owner.frame().mapped_pa == paddr
27 &&& owner.frame().prop == prop
28 &&& level == owner.parent_level
29 },
30 Self::None => owner.is_absent(),
31 }
32 }
33}
34
35impl<'a, C: PageTableConfig> OwnerOf for ChildRef<'a, C> {
36 type Owner = EntryOwner<C>;
37
38 open spec fn wf(self, owner: Self::Owner) -> bool {
39 match self {
40 Self::PageTable(node) => {
41 &&& owner.is_node()
42 &&& node.inner@.ptr.addr() == owner.node().slot_vaddr()
43 &&& node.inner@.ptr_inv()
44 &&& node.inner@.external_meta_wf(owner.node().frame_permission.resource(), ())
45 },
46 Self::Frame(paddr, level, prop) => {
47 &&& owner.is_frame()
48 &&& owner.frame().mapped_pa == paddr
49 &&& owner.frame().prop == prop
50 },
51 Self::None => owner.is_absent(),
52 }
53 }
54}
55
56impl<C: PageTableConfig> Child<C> {
57 pub open spec fn from_pte_spec(
58 pte: C::E,
59 level: PagingLevel,
60 regions: MetaRegionOwners,
61 ) -> Self {
62 if !pte.is_present() {
63 Self::None
64 } else if pte.is_last(level) {
65 Self::Frame(pte.paddr(), level, pte.prop())
66 } else {
67 Self::PageTable(
68 PageTableNode::from_raw_spec(
69 pte.paddr(),
70 regions.slots[crate::specs::mm::frame::mapping::frame_to_index(pte.paddr())],
71 None,
72 ),
73 )
74 }
75 }
76
77 pub open spec fn invariants(self, owner: EntryOwner<C>, regions: MetaRegionOwners) -> bool {
78 &&& owner.inv_base()
79 &&& regions.inv()
80 &&& self.wf(owner)
81 &&& match self {
82 Self::Frame(paddr, level, prop) => C::E::new_page_req(paddr, level, prop),
83 _ => true,
84 }
85 &&& owner.metaregion_sound(regions)
86 }
87}
88
89impl<C: PageTableConfig> ChildRef<'_, C> {
90 pub open spec fn invariants(self, owner: EntryOwner<C>, regions: MetaRegionOwners) -> bool {
91 &&& owner.inv()
92 &&& regions.inv()
93 &&& self.wf(owner)
94 &&& owner.metaregion_sound(regions)
95 }
96}
97
98impl<C: PageTableConfig> EntryOwner<C> {
99 pub open spec fn into_pte_owner_spec(self) -> EntryOwner<C> {
100 self
101 }
102
103 pub open spec fn from_pte_owner_spec(self) -> EntryOwner<C> {
104 self
105 }
106
107 pub open spec fn pte_invariants(self, pte: C::E, regions: MetaRegionOwners) -> bool {
110 &&& self.inv()
111 &&& regions.inv()
112 &&& self.match_pte(pte, self.parent_level)
113 &&& self.metaregion_sound(regions)
114 }
115}
116
117}