1use vstd::prelude::*;
49use vstd_extra::ownership::*;
50
51use crate::mm::vm_space::vm_space_specs::VmSpaceOwner;
52use crate::mm::{MAX_USERSPACE_VADDR, Vaddr};
53use crate::specs::mm::io::VmIoOwner;
54
55use super::{VmIoEntry, VmIoKind, VmSpaceId, axiom_vm_io_entry_new};
56
57verus! {
58
59pub axiom fn vm_space_reader_embedded<'a>(
66 tracked vm_space: &VmSpaceOwner,
67 vaddr: Vaddr,
68 len: usize,
69) -> (tracked res: Option<VmIoOwner>)
70 requires
71 vm_space.inv(),
72 ensures
73 res matches Some(o) ==> o.inv(),
74 res matches Some(o) ==> o.mem_view is None,
75 res is Some ==> (vaddr as nat) + (len as nat) <= MAX_USERSPACE_VADDR as nat,
76;
77
78pub axiom fn vm_space_writer_embedded<'a>(
80 tracked vm_space: &VmSpaceOwner,
81 vaddr: Vaddr,
82 len: usize,
83) -> (tracked res: Option<VmIoOwner>)
84 requires
85 vm_space.inv(),
86 ensures
87 res matches Some(o) ==> o.inv(),
88 res matches Some(o) ==> o.mem_view is None,
89 res is Some ==> (vaddr as nat) + (len as nat) <= MAX_USERSPACE_VADDR as nat,
90;
91
92pub axiom fn vm_reader_from_kernel_space_embedded(vaddr: Vaddr, len: usize) -> (tracked res:
99 VmIoOwner)
100 ensures
101 res.inv(),
102 res.read_view_initialized(),
103;
104
105pub axiom fn vm_writer_from_kernel_space_embedded(vaddr: Vaddr, len: usize) -> (tracked res:
111 VmIoOwner)
112 ensures
113 res.inv(),
114 res.has_write_view(),
115;
116
117pub axiom fn vm_reader_read_embedded(
125 tracked source_owner: &mut VmIoOwner,
126 tracked dest_owner: &mut VmIoOwner,
127) -> (tracked consumed_w: VmIoOwner)
128 requires
129 old(source_owner).inv(),
130 old(dest_owner).inv(),
131 old(source_owner).read_view_initialized(),
132 old(dest_owner).has_write_view(),
133 ensures
134 final(source_owner).inv(),
135 final(dest_owner).inv(),
136 final(source_owner).read_view_initialized(),
137 final(dest_owner).has_write_view(),
138 final(source_owner).range.start >= old(source_owner).range.start,
140 final(source_owner).range.end == old(source_owner).range.end,
141 final(dest_owner).range.start >= old(dest_owner).range.start,
142 final(dest_owner).range.end == old(dest_owner).range.end,
143 consumed_w.inv(),
144 consumed_w.has_write_view(),
145 consumed_w.range.start >= old(dest_owner).range.start,
147 consumed_w.range.end <= final(dest_owner).range.start,
148;
149
150pub axiom fn vm_reader_limit_embedded(tracked owner: &mut VmIoOwner, max_remain: usize)
155 requires
156 old(owner).inv(),
157 ensures
158 final(owner).inv(),
159 *final(owner) == *old(owner),
160;
161
162pub axiom fn vm_reader_skip_embedded(tracked owner: &mut VmIoOwner, nbytes: usize)
166 requires
167 old(owner).inv(),
168 ensures
169 final(owner).inv(),
170 *final(owner) == *old(owner),
171;
172
173pub axiom fn vm_writer_write_embedded(
179 tracked source_owner: &mut VmIoOwner,
180 tracked dest_owner: &mut VmIoOwner,
181)
182 requires
183 old(source_owner).inv(),
184 old(dest_owner).inv(),
185 old(source_owner).read_view_initialized(),
186 old(dest_owner).has_write_view(),
187 ensures
188 final(source_owner).inv(),
189 final(dest_owner).inv(),
190 final(source_owner).read_view_initialized(),
191 final(dest_owner).has_write_view(),
192 final(source_owner).range.start >= old(source_owner).range.start,
194 final(source_owner).range.end == old(source_owner).range.end,
195 final(dest_owner).range.start >= old(dest_owner).range.start,
196 final(dest_owner).range.end == old(dest_owner).range.end,
197;
198
199pub axiom fn vm_writer_fill_zeros_embedded(tracked owner: &mut VmIoOwner, len: usize)
205 requires
206 old(owner).inv(),
207 ensures
208 final(owner).inv(),
209 final(owner).mem_view == old(owner).mem_view,
210 final(owner).range == old(owner).range,
211;
212
213pub axiom fn vm_writer_limit_embedded(tracked owner: &mut VmIoOwner, max_avail: usize)
215 requires
216 old(owner).inv(),
217 ensures
218 final(owner).inv(),
219 *final(owner) == *old(owner),
220;
221
222pub axiom fn vm_writer_skip_embedded(tracked owner: &mut VmIoOwner, nbytes: usize)
224 requires
225 old(owner).inv(),
226 ensures
227 final(owner).inv(),
228 *final(owner) == *old(owner),
229;
230
231pub enum VmIoMethod {
236 ReaderLimit(usize),
237 ReaderSkip(usize),
238 WriterFillZeros(usize),
239 WriterLimit(usize),
240 WriterSkip(usize),
241}
242
243pub(super) proof fn new_vm_io_step<'a>(
247 tracked vm_space: &VmSpaceOwner,
248 vs: Option<VmSpaceId>,
249 vaddr: Vaddr,
250 len: usize,
251 kind: VmIoKind,
252) -> (tracked res: Option<VmIoEntry>)
253 requires
254 vm_space.inv(),
255 vs is Some, ensures
258 res matches Some(e) ==> e.inv(),
259 res matches Some(e) ==> e.kind == kind,
260 res matches Some(e) ==> e.vaddr == vaddr,
261 res matches Some(e) ==> e.len == len,
262 res matches Some(e) ==> e.vm_space == vs,
263 res matches Some(_) ==> (vaddr as nat) + (len as nat) <= MAX_USERSPACE_VADDR as nat,
264{
265 let tracked owner_opt = match kind {
266 VmIoKind::Reader => vm_space_reader_embedded(vm_space, vaddr, len),
267 VmIoKind::Writer => vm_space_writer_embedded(vm_space, vaddr, len),
268 };
269 match owner_opt {
270 Option::Some(owner) => {
271 let tracked entry = axiom_vm_io_entry_new(vs, kind, vaddr, len, owner);
272 Option::Some(entry)
273 },
274 Option::None => Option::None,
275 }
276}
277
278pub(super) proof fn new_kernel_vm_io_step(vaddr: Vaddr, len: usize, kind: VmIoKind) -> (tracked res:
283 VmIoEntry)
284 ensures
285 res.inv(),
286 res.kind == kind,
287 res.vaddr == vaddr,
288 res.len == len,
289 res.vm_space is None,
290{
291 let tracked owner = match kind {
292 VmIoKind::Reader => vm_reader_from_kernel_space_embedded(vaddr, len),
293 VmIoKind::Writer => vm_writer_from_kernel_space_embedded(vaddr, len),
294 };
295 axiom_vm_io_entry_new(Option::<VmSpaceId>::None, kind, vaddr, len, owner)
296}
297
298pub(super) proof fn drop_vm_io_step(tracked _entry: VmIoEntry) {
301}
302
303pub(super) proof fn vm_io_method_step(tracked entry: &mut VmIoEntry, method: VmIoMethod)
309 requires
310 old(entry).inv(),
311 ensures
312 final(entry).vm_space == old(entry).vm_space,
313 final(entry).kind == old(entry).kind,
314 final(entry).vaddr == old(entry).vaddr,
315 final(entry).len == old(entry).len,
316 final(entry).inv(),
317{
318 match method {
319 VmIoMethod::ReaderLimit(max) => vm_reader_limit_embedded(&mut entry.owner, max),
320 VmIoMethod::ReaderSkip(n) => vm_reader_skip_embedded(&mut entry.owner, n),
321 VmIoMethod::WriterFillZeros(len) => vm_writer_fill_zeros_embedded(&mut entry.owner, len),
322 VmIoMethod::WriterLimit(max) => vm_writer_limit_embedded(&mut entry.owner, max),
323 VmIoMethod::WriterSkip(n) => vm_writer_skip_embedded(&mut entry.owner, n),
324 }
325}
326
327pub(super) proof fn read_step(
333 tracked source: &mut VmIoEntry,
334 tracked dest: &mut VmIoEntry,
335) -> (tracked res: VmIoEntry)
336 requires
337 old(source).inv(),
338 old(dest).inv(),
339 old(source).is_kernel_reader(),
340 old(dest).is_kernel_writer(),
341 ensures
342 final(source).vm_space == old(source).vm_space,
343 final(source).kind == old(source).kind,
344 final(source).vaddr == old(source).vaddr,
345 final(source).len == old(source).len,
346 final(source).inv(),
347 final(dest).vm_space == old(dest).vm_space,
348 final(dest).kind == old(dest).kind,
349 final(dest).vaddr == old(dest).vaddr,
350 final(dest).len == old(dest).len,
351 final(dest).inv(),
352 res.inv(),
354 res.kind == VmIoKind::Writer,
355 res.vm_space is None,
356{
357 let tracked val_owner = vm_reader_read_embedded(&mut source.owner, &mut dest.owner);
358 axiom_vm_io_entry_new(Option::<VmSpaceId>::None, VmIoKind::Writer, 0usize, 0usize, val_owner)
359}
360
361pub(super) proof fn write_step(tracked source: &mut VmIoEntry, tracked dest: &mut VmIoEntry)
365 requires
366 old(source).inv(),
367 old(dest).inv(),
368 old(source).is_kernel_reader(),
369 old(dest).is_kernel_writer(),
370 ensures
371 final(source).vm_space == old(source).vm_space,
372 final(source).kind == old(source).kind,
373 final(source).vaddr == old(source).vaddr,
374 final(source).len == old(source).len,
375 final(source).inv(),
376 final(dest).vm_space == old(dest).vm_space,
377 final(dest).kind == old(dest).kind,
378 final(dest).vaddr == old(dest).vaddr,
379 final(dest).len == old(dest).len,
380 final(dest).inv(),
381{
382 vm_writer_write_embedded(&mut source.owner, &mut dest.owner);
383}
384
385}