ostd/mm/frame/
frame_ref.rs1use core::{marker::PhantomData, ops::Deref, ptr::NonNull};
3
4use vstd::prelude::*;
5
6use vstd_extra::drop_tracking::*;
7use vstd_extra::ownership::*;
8
9use crate::mm::frame::meta::mapping::{frame_to_index, frame_to_meta, meta_to_frame};
10use crate::mm::frame::meta::{has_safe_slot, AnyFrameMeta, MetaSlot};
11use crate::mm::frame::MetaPerm;
12use crate::mm::{Paddr, PagingLevel, Vaddr};
13use crate::specs::arch::mm::{MAX_PADDR, PAGE_SIZE};
14use crate::specs::mm::frame::frame_specs::BorrowDebt;
15use crate::specs::mm::frame::meta_region_owners::MetaRegionOwners;
16
17use super::Frame;
18
19use vstd::simple_pptr::PPtr;
20
21verus! {
22
23pub struct FrameRef<'a, M: AnyFrameMeta> {
25 pub inner: ManuallyDrop<Frame<M>>,
26 pub _marker: PhantomData<&'a Frame<M>>,
27}
28
29impl<M: AnyFrameMeta> Deref for FrameRef<'_, M> {
30 type Target = Frame<M>;
31
32 #[verus_spec(ensures returns &self.inner.0)]
33 fn deref(&self) -> &Self::Target {
34 &self.inner
35 }
36}
37
38#[verus_verify]
39impl<M: AnyFrameMeta> FrameRef<'_, M> {
40 #[verus_spec(r =>
54 with
55 Tracked(regions): Tracked<&mut MetaRegionOwners>,
56 Tracked(perm): Tracked<&MetaPerm<M>>
57 requires
58 Frame::<M>::from_raw_requires_safety(*old(regions), raw),
59 old(regions).slot_owners[frame_to_index(raw)].raw_count <= 1,
60 perm.points_to.is_init(),
61 perm.points_to.addr() == frame_to_meta(raw),
62 perm.points_to.value().wf(old(regions).slot_owners[frame_to_index(raw)]),
63 ensures
64 regions.inv(),
65 r.inner.0.ptr.addr() == frame_to_meta(raw),
66 regions.slot_owners[frame_to_index(raw)].raw_count == 1,
68 regions.slot_owners[frame_to_index(raw)].inner_perms
70 == old(regions).slot_owners[frame_to_index(raw)].inner_perms,
71 regions.slot_owners[frame_to_index(raw)].self_addr
72 == old(regions).slot_owners[frame_to_index(raw)].self_addr,
73 regions.slot_owners[frame_to_index(raw)].usage
74 == old(regions).slot_owners[frame_to_index(raw)].usage,
75 regions.slot_owners[frame_to_index(raw)].path_if_in_pt
76 == old(regions).slot_owners[frame_to_index(raw)].path_if_in_pt,
77 forall |i: usize|
79 #![trigger regions.slot_owners[i]]
80 i != frame_to_index(raw) ==> regions.slot_owners[i]
81 == old(regions).slot_owners[i],
82 regions.slot_owners.dom() =~= old(regions).slot_owners.dom(),
83 regions.slots == old(regions).slots.insert(frame_to_index(raw), perm.points_to),
85 )]
86 pub(in crate::mm) fn borrow_paddr(raw: Paddr) -> Self {
87 proof {
88 broadcast use crate::mm::frame::meta::mapping::group_page_meta;
89 old(regions).inv_implies_correct_addr(raw);
90 }
91
92 proof_decl! {
93 let tracked debt: BorrowDebt;
94 }
95
96 #[verus_spec(with Tracked(regions), Tracked(perm) => Tracked(debt))]
97 let frame = Frame::from_raw(raw);
98
99 proof {
100 Frame::lemma_from_raw_manuallydrop_general(raw, frame, *old(regions), *regions, debt);
101 }
102
103 Self { inner: ManuallyDrop::new(frame, Tracked(regions)), _marker: PhantomData }
104 }
105}
106
107pub unsafe trait NonNullPtr: 'static + Sized + TrackDrop<State = MetaRegionOwners> {
123 type Target;
126
127 type Ref<'a>;
129
130 fn ALIGN_BITS() -> u32;
132
133 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target>
142 requires
143 self.constructor_requires(*old(regions)),
144 ;
145
146 unsafe fn from_raw(ptr: PPtr<Self::Target>) -> Self;
159
160 unsafe fn raw_as_ref<'a>(
167 raw: PPtr<Self::Target>,
168 Tracked(regions): Tracked<&mut MetaRegionOwners>,
169 ) -> Self::Ref<'a>
170 requires
171 old(regions).inv(),
172 old(regions).slot_owners.contains_key(frame_to_index(meta_to_frame(raw.addr()))),
173 old(regions).slot_owners[frame_to_index(meta_to_frame(raw.addr()))].raw_count
174 == 0,
175 ;
178
179 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target>;
181}
182
183pub assume_specification[ usize::trailing_zeros ](_0: usize) -> u32
184;
185
186unsafe impl<M: AnyFrameMeta + ?Sized + 'static> NonNullPtr for Frame<M> {
189 type Target = PhantomData<Self>;
190
191 type Ref<'a> = FrameRef<'a, M>;
192
193 fn ALIGN_BITS() -> u32 {
194 core::mem::align_of::<MetaSlot>().trailing_zeros()
195 }
196
197 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target> {
198 let ptr = self.ptr;
199 assert(self.constructor_requires(*old(regions)));
200 let _ = ManuallyDrop::new(self, Tracked(regions));
201 PPtr::<Self::Target>::from_addr(ptr.addr())
202 }
203
204 unsafe fn from_raw(raw: PPtr<Self::Target>) -> Self {
205 Self { ptr: PPtr::<MetaSlot>::from_addr(raw.addr()), _marker: PhantomData }
206 }
207
208 unsafe fn raw_as_ref<'a>(
209 raw: PPtr<Self::Target>,
210 Tracked(regions): Tracked<&mut MetaRegionOwners>,
211 ) -> Self::Ref<'a> {
212 let dropped = ManuallyDrop::<Frame<M>>::new(
213 Frame { ptr: PPtr::<MetaSlot>::from_addr(raw.addr()), _marker: PhantomData },
214 Tracked(regions),
215 );
216 Self::Ref { inner: dropped, _marker: PhantomData }
217 }
218
219 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target> {
220 PPtr::from_addr(ptr_ref.inner.ptr.addr())
221 }
222}
223
224}