1use vstd::prelude::*;
9
10use super::*;
11use crate::mm::{
12 io::{VmIoOwner, VmReader, VmWriter},
13 kspace::{
14 paddr_to_vaddr_spec, KERNEL_BASE_VADDR, KERNEL_END_VADDR, LINEAR_MAPPING_BASE_VADDR,
15 VMALLOC_BASE_VADDR,
16 },
17 paddr_to_vaddr,
18};
19use crate::specs::arch::kspace::{lemma_max_paddr_range, lemma_paddr_to_vaddr_properties};
20use crate::specs::mm::frame::meta_owners::MetaSlotStorage;
21use crate::specs::mm::virt_mem_newer::VirtPtr;
22use vstd_extra::ownership::OwnerOf;
23
24verus! {
25
26pub trait AnyUFrameMeta: AnyFrameMeta {
32
33}
34
35pub type UFrame = Frame<MetaSlotStorage>;
45
46pub trait UntypedMem {
53 fn reader(&self) -> VmReader<'_>;
55
56 fn writer(&self) -> VmWriter<'_>;
58}
59
60#[verus_verify]
61impl<M: AnyUFrameMeta + OwnerOf> Segment<M> {
62 #[inline(always)]
63 #[verus_spec(r =>
64 with
65 -> owner: Tracked<VmIoOwner<'_>>,
66 requires
67 self.inv(),
68 ensures
69 r.inv(),
70 owner@.inv(),
71 r.wf(owner@),
72 r.cursor.vaddr == paddr_to_vaddr_spec(self.start_paddr_spec()),
73 r.remain_spec() == self.size_spec(),
74 owner@.is_kernel,
75 )]
76 pub fn reader(&self) -> VmReader<'_> {
77 proof_decl! {
78 let ghost id: nat;
79 let tracked owner: VmIoOwner<'_>;
80 }
81 proof {
82 lemma_max_paddr_range();
83 }
84
85 let vaddr = paddr_to_vaddr(self.start_paddr());
86 let len = self.size();
87 let ghost range = vaddr..(vaddr + len) as usize;
88 let ptr = VirtPtr { vaddr, range: Ghost(range) };
89 proof {
90 lemma_paddr_to_vaddr_properties(self.start_paddr_spec());
91 assert(KERNEL_BASE_VADDR > 0) by (compute_only);
92 assert(vaddr > 0);
93 assert(VMALLOC_BASE_VADDR <= KERNEL_END_VADDR) by (compute_only);
94 assert(ptr.inv());
95 }
96
97 let reader = unsafe {
98 #[verus_spec(with Ghost(id) => Tracked(owner))]
99 VmReader::from_kernel_space(ptr, len)
100 };
101
102 proof_with!(|= Tracked(owner));
103 reader
104 }
105
106 #[inline(always)]
107 #[verus_spec(r =>
108 with
109 -> owner: Tracked<VmIoOwner<'_>>,
110 requires
111 self.inv(),
112 ensures
113 r.inv(),
114 owner@.inv(),
115 r.wf(owner@),
116 r.cursor.vaddr == paddr_to_vaddr_spec(self.start_paddr_spec()),
117 r.avail_spec() == self.size_spec(),
118 owner@.is_kernel,
119 !owner@.is_fallible,
120 )]
121 pub fn writer(&self) -> VmWriter<'_> {
122 proof_decl! {
123 let ghost id: nat;
124 let tracked owner: VmIoOwner<'_>;
125 }
126 proof {
127 lemma_max_paddr_range();
128 }
129
130 let vaddr = paddr_to_vaddr(self.start_paddr());
131 let len = self.size();
132 let ghost range = vaddr..(vaddr + len) as usize;
133 let ptr = VirtPtr { vaddr, range: Ghost(range) };
134 proof {
135 lemma_paddr_to_vaddr_properties(self.start_paddr_spec());
136 assert(KERNEL_BASE_VADDR > 0) by (compute_only);
137 assert(vaddr > 0);
138 assert(VMALLOC_BASE_VADDR <= KERNEL_END_VADDR) by (compute_only);
139 assert(ptr.inv());
140 }
141
142 let writer = unsafe {
143 #[verus_spec(with Ghost(id), Tracked(false) => Tracked(owner))]
144 VmWriter::from_kernel_space(ptr, len)
145 };
146
147 proof_with!(|= Tracked(owner));
148 writer
149 }
150}
151
152}