ostd/mm/frame/
frame_ref.rs1use core::{marker::PhantomData, ops::Deref, ptr::NonNull};
3
4use vstd::prelude::*;
5use vstd::simple_pptr::PPtr;
6use vstd_extra::cast_ptr::Repr;
7use vstd_extra::drop_tracking::*;
8use vstd_extra::prelude::*;
9
10use crate::mm::frame::MetaPerm;
11use crate::mm::frame::meta::mapping::{frame_to_index, frame_to_meta, meta_to_frame};
12use crate::mm::frame::meta::{AnyFrameMeta, MetaSlot, has_safe_slot};
13use crate::mm::{Paddr, PagingLevel, Vaddr};
14use crate::specs::arch::mm::{MAX_PADDR, PAGE_SIZE};
15use crate::specs::mm::frame::meta_owners::MetaSlotStorage;
16use crate::specs::mm::frame::meta_region_owners::MetaRegionOwners;
17
18use super::Frame;
19
20verus! {
21
22pub struct FrameRef<'a, M: AnyFrameMeta + Repr<MetaSlotStorage>> {
24 pub inner: ManuallyDrop<Frame<M>>,
25 pub _marker: PhantomData<&'a Frame<M>>,
26}
27
28impl<M: AnyFrameMeta + Repr<MetaSlotStorage>> Deref for FrameRef<'_, M> {
29 type Target = Frame<M>;
30
31 #[verus_spec(ensures returns &self.inner.0)]
32 fn deref(&self) -> &Self::Target {
33 &self.inner
34 }
35}
36
37#[verus_verify]
38impl<M: AnyFrameMeta + Repr<MetaSlotStorage>> FrameRef<'_, M> {
39 #[verus_spec(r =>
52 with
53 Tracked(regions): Tracked<&mut MetaRegionOwners>,
54 requires
55 Frame::<M>::from_raw_requires_safety(*old(regions), raw),
56 old(regions).slots.contains_key(frame_to_index(raw)),
57 ensures
58 final(regions).inv(),
59 r.inner.0.ptr.addr() == frame_to_meta(raw),
60 final(regions).slot_owners =~= old(regions).slot_owners,
61 final(regions).slots == old(regions).slots,
62 final(regions).frame_obligations =~= old(regions).frame_obligations,
63 )]
64 pub(in crate::mm) unsafe fn borrow_paddr(raw: Paddr) -> Self {
65 proof {
66 broadcast use crate::mm::frame::meta::mapping::group_page_meta;
67
68 old(regions).inv_implies_correct_addr(raw);
69 }
70
71 let ghost idx = frame_to_index(raw);
72 let ghost regions0 = *regions;
73
74 proof_decl! {
75 let tracked from_raw_obl: vstd_extra::drop_tracking::DropObligation<usize>;
76 }
77 let frame = unsafe {
82 #[verus_spec(with Tracked(regions) => Tracked(from_raw_obl))]
83 Frame::from_raw(raw)
84 };
85
86 let inner = ManuallyDrop::new(frame, Tracked(regions));
87
88 proof {
89 assert(regions.frame_obligations =~= regions0.frame_obligations);
92 }
93
94 Self { inner, _marker: PhantomData }
95 }
96}
97
98pub unsafe trait NonNullPtr: 'static + Sized + TrackDrop<State = MetaRegionOwners> {
114 type Target;
117
118 type Ref<'a>;
120
121 fn ALIGN_BITS() -> u32;
123
124 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target>
133 requires
134 self.constructor_requires(*old(regions)),
135 ;
136
137 unsafe fn from_raw(ptr: PPtr<Self::Target>) -> Self;
150
151 unsafe fn raw_as_ref<'a>(
158 raw: PPtr<Self::Target>,
159 Tracked(regions): Tracked<&mut MetaRegionOwners>,
160 ) -> Self::Ref<'a>
161 requires
162 old(regions).inv(),
163 old(regions).slot_owners.contains_key(frame_to_index(meta_to_frame(raw.addr()))),
164 ;
165
166 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target>;
168}
169
170pub assume_specification[ usize::trailing_zeros ](_0: usize) -> u32
171;
172
173unsafe impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + 'static> NonNullPtr for Frame<M> {
176 type Target = PhantomData<Self>;
177
178 type Ref<'a> = FrameRef<'a, M>;
179
180 fn ALIGN_BITS() -> u32 {
181 core::mem::align_of::<MetaSlot>().trailing_zeros()
182 }
183
184 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target> {
185 let ptr = self.ptr;
186 proof {
187 let tracked _ = regions.tracked_mint_frame_obligation(self.index());
193 }
194 let _ = ManuallyDrop::new(self, Tracked(regions));
195 PPtr::<Self::Target>::from_addr(ptr.addr())
196 }
197
198 unsafe fn from_raw(raw: PPtr<Self::Target>) -> Self {
199 Self { ptr: PPtr::<MetaSlot>::from_addr(raw.addr()), _marker: PhantomData }
200 }
201
202 unsafe fn raw_as_ref<'a>(
203 raw: PPtr<Self::Target>,
204 Tracked(regions): Tracked<&mut MetaRegionOwners>,
205 ) -> Self::Ref<'a> {
206 let frame = Frame::<M> {
207 ptr: PPtr::<MetaSlot>::from_addr(raw.addr()),
208 _marker: PhantomData,
209 };
210 proof {
211 let tracked _ = regions.tracked_mint_frame_obligation(frame.index());
212 }
213 let dropped = ManuallyDrop::<Frame<M>>::new(frame, Tracked(regions));
214 Self::Ref { inner: dropped, _marker: PhantomData }
215 }
216
217 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target> {
218 PPtr::from_addr(ptr_ref.inner.ptr.addr())
219 }
220}
221
222}