ostd/mm/frame/
frame_ref.rs1use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull};
3
4use vstd::prelude::*;
5
6use vstd_extra::external::manually_drop::*;
7use vstd_extra::ownership::*;
8use vstd_extra::undroppable::*;
9
10use crate::mm::frame::meta::mapping::{frame_to_index, frame_to_meta, meta_to_frame};
11use crate::mm::frame::meta::{AnyFrameMeta, MetaSlot};
12use crate::mm::frame::MetaPerm;
13use crate::mm::{Paddr, PagingLevel, Vaddr};
14use crate::specs::arch::mm::{MAX_PADDR, PAGE_SIZE};
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: NeverDrop<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 manually_drop_deref_spec(&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 =>
49 with
50 Tracked(regions): Tracked<&mut MetaRegionOwners>,
51 Tracked(perm): Tracked<&MetaPerm<M>>,
52 requires
53 raw % PAGE_SIZE() == 0,
54 raw < MAX_PADDR(),
55 !old(regions).slots.contains_key(frame_to_index(raw)),
56 old(regions).inv(),
57 ensures
58 regions.inv(),
59 manually_drop_deref_spec(&r.inner.0).ptr.addr() == frame_to_meta(raw),
60 )]
61 #[verifier::external_body]
62 pub fn borrow_paddr(raw: Paddr) -> Self {
63 #[verus_spec(with Tracked(regions), Tracked(perm))]
64 let frame = Frame::from_raw(raw);
65
66 Self {
67 inner: NeverDrop::new(frame, Tracked(regions)),
68 _marker: PhantomData,
69 }
70 }
71}
72
73pub unsafe trait NonNullPtr: 'static + Sized {
89 type Target;
92
93 type Ref<'a>;
95
96 fn ALIGN_BITS() -> u32;
98
99 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target>;
108
109 unsafe fn from_raw(ptr: PPtr<Self::Target>) -> Self;
122
123 unsafe fn raw_as_ref<'a>(
130 raw: PPtr<Self::Target>,
131 Tracked(regions): Tracked<&mut MetaRegionOwners>,
132 ) -> Self::Ref<'a>
133 requires
134 old(regions).inv(),
135 old(regions).slots.contains_key(frame_to_index(meta_to_frame(raw.addr()))),
136 !old(regions).dropped_slots.contains_key(frame_to_index(meta_to_frame(raw.addr()))),
137 ;
138
139 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target>;
141}
142
143pub assume_specification[ usize::trailing_zeros ](_0: usize) -> u32;
144
145unsafe impl<M: AnyFrameMeta + ?Sized + 'static> NonNullPtr for Frame<M> {
148 type Target = PhantomData<Self>;
149
150 type Ref<'a> = FrameRef<'a, M>;
151
152 fn ALIGN_BITS() -> u32 {
153 core::mem::align_of::<MetaSlot>().trailing_zeros()
154 }
155
156 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target> {
157 let ptr = self.ptr;
158 assert(self.constructor_requires(*old(regions))) by { admit() };
159 let _ = NeverDrop::new(self, Tracked(regions));
160 PPtr::<Self::Target>::from_addr(ptr.addr())
161 }
162
163 unsafe fn from_raw(raw: PPtr<Self::Target>) -> Self {
164 Self { ptr: PPtr::<MetaSlot>::from_addr(raw.addr()), _marker: PhantomData }
165 }
166
167 unsafe fn raw_as_ref<'a>(
168 raw: PPtr<Self::Target>,
169 Tracked(regions): Tracked<&mut MetaRegionOwners>,
170 ) -> Self::Ref<'a> {
171 let dropped = NeverDrop::<Frame<M>>::new(
172 Frame { ptr: PPtr::<MetaSlot>::from_addr(raw.addr()), _marker: PhantomData },
173 Tracked(regions),
174 );
175 Self::Ref { inner: dropped, _marker: PhantomData }
176 }
177
178 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target> {
179 PPtr::from_addr(ptr_ref.inner.ptr.addr())
180 }
181}
182
183}