ostd/specs/mm/page_table/node/
mod.rs1pub mod entry_owners;
2pub mod entry_view;
3pub mod owners;
4
5pub use entry_owners::*;
6pub use entry_view::*;
7pub use owners::*;
8
9use core::marker::PhantomData;
10use vstd::prelude::*;
11use vstd::simple_pptr::*;
12
13use vstd_extra::cast_ptr::Repr;
14use vstd_extra::drop_tracking::*;
15
16use crate::mm::frame::Frame;
17use crate::mm::page_table::{PageTableConfig, PageTableGuard, PageTablePageMeta};
18use crate::specs::mm::frame::meta_owners::{MetaSlotStorage, StoredPageTablePageMeta};
19
20verus! {
21
22pub type GuardPerm<'rcu, C: PageTableConfig> = PointsTo<PageTableGuard<'rcu, C>>;
23
24pub tracked struct Guards<'rcu, C: PageTableConfig> {
25 pub guards: Map<usize, Option<GuardPerm<'rcu, C>>>,
26}
27
28impl<'rcu, C: PageTableConfig> Guards<'rcu, C> {
29 pub open spec fn locked(self, addr: usize) -> bool {
30 self.guards.contains_key(addr)
31 }
32
33 pub open spec fn unlocked(self, addr: usize) -> bool {
34 !self.guards.contains_key(addr)
35 }
36
37 pub open spec fn lock_held(self, addr: usize) -> bool {
38 self.guards.contains_key(addr) && self.guards[addr] is None
39 }
40
41 pub proof fn take(tracked &mut self, addr: usize) -> (tracked guard: GuardPerm<'rcu, C>)
42 requires
43 old(self).locked(addr),
44 old(self).guards[addr] is Some,
45 ensures
46 self.lock_held(addr),
47 guard == old(self).guards[addr].unwrap(),
48 {
49 let tracked guard = self.guards.tracked_remove(addr).tracked_unwrap();
50 self.guards.tracked_insert(addr, None);
51 guard
52 }
53
54 pub proof fn put(tracked &mut self, addr: usize, tracked guard: GuardPerm<'rcu, C>)
55 requires
56 old(self).lock_held(addr),
57 ensures
58 self.locked(addr),
59 self.guards[addr] == Some(guard),
60 {
61 let _ = self.guards.tracked_remove(addr);
62 self.guards.tracked_insert(addr, Some(guard));
63 }
64}
65
66impl<'rcu, C: PageTableConfig> TrackDrop for PageTableGuard<'rcu, C> {
67 type State = Guards<'rcu, C>;
68
69 open spec fn constructor_requires(self, s: Self::State) -> bool {
70 s.lock_held(self.inner.inner@.ptr.addr())
71 }
72
73 open spec fn constructor_ensures(self, s0: Self::State, s1: Self::State) -> bool {
74 s1.guards == s0.guards.remove(self.inner.inner@.ptr.addr())
75 }
76
77 proof fn constructor_spec(self, tracked s: &mut Self::State)
78 {
79 s.guards.tracked_remove(self.inner.inner@.ptr.addr());
80 }
81
82 open spec fn drop_requires(self, s: Self::State) -> bool {
83 s.unlocked(self.inner.inner@.ptr.addr())
84 }
85
86 open spec fn drop_ensures(self, s0: Self::State, s1: Self::State) -> bool {
87 s1.guards == s0.guards.insert(self.inner.inner@.ptr.addr(), None)
88 }
89
90 proof fn drop_spec(self, tracked s: &mut Self::State)
91 {
92 s.guards.tracked_insert(self.inner.inner@.ptr.addr(), None);
93 }
94}
95
96impl<C: PageTableConfig> PageTablePageMeta<C> {
97 pub open spec fn into_spec(self) -> StoredPageTablePageMeta {
98 StoredPageTablePageMeta {
99 nr_children: self.nr_children,
100 stray: self.stray,
101 level: self.level,
102 lock: self.lock,
103 }
104 }
105
106 #[verifier::when_used_as_spec(into_spec)]
107 pub fn into(self) -> (res: StoredPageTablePageMeta)
108 ensures
109 res == self.into_spec(),
110 {
111 StoredPageTablePageMeta {
112 nr_children: self.nr_children,
113 stray: self.stray,
114 level: self.level,
115 lock: self.lock,
116 }
117 }
118}
119
120impl StoredPageTablePageMeta {
121 pub open spec fn into_spec<C: PageTableConfig>(self) -> PageTablePageMeta<C> {
122 PageTablePageMeta::<C> {
123 nr_children: self.nr_children,
124 stray: self.stray,
125 level: self.level,
126 lock: self.lock,
127 _phantom: PhantomData,
128 }
129 }
130
131 #[verifier::when_used_as_spec(into_spec)]
132 pub fn into<C: PageTableConfig>(self) -> (res: PageTablePageMeta<C>)
133 ensures
134 res == self.into_spec::<C>(),
135 {
136 PageTablePageMeta::<C> {
137 nr_children: self.nr_children,
138 stray: self.stray,
139 level: self.level,
140 lock: self.lock,
141 _phantom: PhantomData,
142 }
143 }
144}
145
146pub uninterp spec fn drop_tree_spec<C: PageTableConfig>(_page: Frame<PageTablePageMeta<C>>) -> Frame<PageTablePageMeta<C>>;
147
148impl<C: PageTableConfig> Repr<MetaSlotStorage> for PageTablePageMeta<C> {
149 type Perm = ();
150
151 uninterp spec fn wf(r: MetaSlotStorage, perm: ()) -> bool;
152
153 uninterp spec fn to_repr_spec(self, perm: ()) -> (MetaSlotStorage, ());
154
155 #[verifier::external_body]
156 fn to_repr(self, Tracked(perm): Tracked<&mut ()>) -> MetaSlotStorage {
157 unimplemented!()
158 }
159
160 uninterp spec fn from_repr_spec(r: MetaSlotStorage, perm: ()) -> Self;
161
162 #[verifier::external_body]
163 fn from_repr(r: MetaSlotStorage, Tracked(perm): Tracked<&()>) -> Self {
164 unimplemented!()
165 }
166
167 #[verifier::external_body]
168 fn from_borrowed<'a>(r: &'a MetaSlotStorage, Tracked(perm): Tracked<&'a ()>) -> &'a Self {
169 unimplemented!()
170 }
171
172 proof fn from_to_repr(self, perm: ()) {
173 admit()
174 }
175
176 proof fn to_from_repr(r: MetaSlotStorage, perm: ()) {
177 admit()
178 }
179
180 proof fn to_repr_wf(self, perm: ()) {
181 admit()
182 }
183}
184
185}