ostd/specs/mm/frame/
frame_specs.rs1use vstd::prelude::*;
2
3use vstd_extra::cast_ptr::*;
4use vstd_extra::ownership::*;
5
6use crate::mm::frame::meta::{get_slot_spec, mapping::frame_to_index, REF_COUNT_UNUSED};
7use crate::mm::frame::*;
8use crate::mm::{Paddr, PagingLevel, Vaddr};
9use crate::specs::arch::mm::{MAX_NR_PAGES, MAX_PADDR, PAGE_SIZE};
10use crate::specs::mm::frame::meta_owners::{MetaPerm, MetaSlotStorage};
11use crate::specs::mm::frame::meta_region_owners::MetaRegionOwners;
12
13use core::marker::PhantomData;
14
15verus! {
16
17pub tracked struct BorrowDebt {
25 pub ghost frame_index: usize,
27 pub ghost raw_count_at_issue: usize,
29}
30
31impl BorrowDebt {
32 pub proof fn discharge_bookkeeping(tracked self)
36 requires self.raw_count_at_issue == 1,
37 {}
38
39 pub proof fn discharge_with_manual_drop(tracked self, regions: &MetaRegionOwners)
43 requires
44 regions.slot_owners.contains_key(self.frame_index),
45 regions.slot_owners[self.frame_index].raw_count == 1,
46 {}
47}
48
49impl<'a, M: AnyFrameMeta> Frame<M> {
50 pub open spec fn from_raw_requires_safety(regions: MetaRegionOwners, paddr: Paddr) -> bool {
56 &&& regions.slot_owners.contains_key(frame_to_index(paddr))
57 &&& regions.slot_owners[frame_to_index(paddr)].self_addr == frame_to_meta(paddr)
58 &&& has_safe_slot(paddr) &&& regions.inv()
60 }
61
62 pub open spec fn from_raw_requires_bookkeeping(regions: MetaRegionOwners, paddr: Paddr) -> bool {
69 regions.slot_owners[frame_to_index(paddr)].raw_count == 1
70 }
71
72 pub open spec fn from_raw_requires(regions: MetaRegionOwners, paddr: Paddr) -> bool {
75 &&& Self::from_raw_requires_safety(regions, paddr)
76 &&& Self::from_raw_requires_bookkeeping(regions, paddr)
77 }
78
79 pub open spec fn from_raw_ensures(
80 old_regions: MetaRegionOwners,
81 new_regions: MetaRegionOwners,
82 paddr: Paddr,
83 r: Self,
84 ) -> bool {
85 &&& new_regions.inv()
86 &&& new_regions.slots.contains_key(frame_to_index(paddr))
87 &&& new_regions.slot_owners[frame_to_index(paddr)].raw_count == 0
88 &&& new_regions.slot_owners[frame_to_index(paddr)].inner_perms ==
89 old_regions.slot_owners[frame_to_index(paddr)].inner_perms
90 &&& new_regions.slot_owners[frame_to_index(paddr)].usage ==
91 old_regions.slot_owners[frame_to_index(paddr)].usage
92 &&& new_regions.slot_owners[frame_to_index(paddr)].path_if_in_pt ==
93 old_regions.slot_owners[frame_to_index(paddr)].path_if_in_pt
94 &&& new_regions.slot_owners[frame_to_index(paddr)].self_addr == r.ptr.addr()
95 &&& forall|i: usize|
96 #![trigger new_regions.slot_owners[i], old_regions.slot_owners[i]]
97 i != frame_to_index(paddr) ==> new_regions.slot_owners[i] == old_regions.slot_owners[i]
98 &&& forall|i: usize|
99 i != frame_to_index(paddr) ==>
100 new_regions.slots.contains_key(i) == old_regions.slots.contains_key(i)
101 &&& r.ptr.addr() == frame_to_meta(paddr)
102 &&& r.paddr() == paddr
103 }
104
105
106 pub open spec fn into_raw_pre_frame_inv(self) -> bool {
110 self.inv()
111 }
112
113 pub open spec fn into_raw_pre_not_unused(self, regions: MetaRegionOwners) -> bool {
115 regions.slot_owners[self.index()].inner_perms.ref_count.value() != REF_COUNT_UNUSED
116 }
117
118 pub open spec fn into_raw_post_raw_count_incremented(
122 self,
123 old_regions: MetaRegionOwners,
124 new_regions: MetaRegionOwners,
125 ) -> bool {
126 &&& new_regions.slot_owners.contains_key(self.index())
127 &&& new_regions.slot_owners[self.index()].raw_count
128 == (old_regions.slot_owners[self.index()].raw_count + 1) as usize
129 }
130
131 pub open spec fn into_raw_post_noninterference(
133 self,
134 old_regions: MetaRegionOwners,
135 new_regions: MetaRegionOwners,
136 ) -> bool {
137 &&& forall|i: usize|
138 #![trigger new_regions.slots[i], old_regions.slots[i]]
139 i != self.index() && old_regions.slots.contains_key(i)
140 ==> new_regions.slots.contains_key(i)
141 && new_regions.slots[i] == old_regions.slots[i]
142 &&& forall|i: usize|
143 #![trigger new_regions.slot_owners[i], old_regions.slot_owners[i]]
144 i != self.index() ==> new_regions.slot_owners[i] == old_regions.slot_owners[i]
145 &&& new_regions.slot_owners.dom() =~= old_regions.slot_owners.dom()
146 }
147}
148
149}