pub struct Cursor<'a, A: InAtomicMode>(pub Cursor<'a, UserPtConfig, A>);Expand description
The cursor for querying over the VM space without modifying it.
It exclusively owns a sub-tree of the page table, preventing others from reading or modifying the same sub-tree. Two read-only cursors can not be created from the same virtual address range either.
Tuple Fields§
§0: Cursor<'a, UserPtConfig, A>Implementations§
Source§impl<'rcu, A: InAtomicMode> Cursor<'rcu, A>
impl<'rcu, A: InAtomicMode> Cursor<'rcu, A>
Sourcepub open spec fn query_success_requires(self) -> bool
pub open spec fn query_success_requires(self) -> bool
{ self.0.barrier_va.start <= self.0.va < self.0.barrier_va.end }Sourcepub open spec fn query_success_ensures(
self,
view: CursorView<UserPtConfig>,
range: Range<Vaddr>,
item: Option<MappedItem>,
) -> bool
pub open spec fn query_success_ensures( self, view: CursorView<UserPtConfig>, range: Range<Vaddr>, item: Option<MappedItem>, ) -> bool
{
if view.present() {
&&& item is Some
&&& view.query_item_spec(item->0) == Some(range)
} else {
&&& range.start == self.0.va
&&& item is None
}
}Source§impl<'rcu, A: InAtomicMode> Cursor<'rcu, A>
impl<'rcu, A: InAtomicMode> Cursor<'rcu, A>
Sourcepub exec fn query(&mut self) -> r : Result<(Range<Vaddr>, Option<MappedItem>), Error>
pub exec fn query(&mut self) -> r : Result<(Range<Vaddr>, Option<MappedItem>), Error>
Tracked(owner): Tracked<&mut CursorOwner<'rcu, UserPtConfig>>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(guards): Tracked<&mut Guards>,requiresold(self).0.invariants(*old(owner), *old(regions), *old(guards)),old(self).0.query_panic_condition(*old(owner), *old(regions)) ==> may_panic(),ensuresfinal(self).0.invariants(*final(owner), *final(regions), *final(guards)),!old(self).0.query_panic_condition(*old(owner), *old(regions)),old(owner).in_locked_range() ==> r is Ok,r matches Ok(
state,
) ==> final(self).0.query_some_condition(*final(owner))
==> final(self).0.query_some_ensures(*final(owner), state),r matches Ok(
state,
) ==> !final(self).0.query_some_condition(*final(owner))
==> final(self).0.query_none_ensures(*final(owner), state),old(owner)@.mappings == final(owner)@.mappings,Queries the mapping at the current virtual address.
If the cursor is pointing to a valid virtual address that is locked, it will return the virtual address range and the mapped item.
§Preconditions
- All system invariants must hold
- Liveness: The function will return an error if the cursor is not within the locked range
§Postconditions
- If there is a mapped item at the current virtual address ([
query_some_condition]), it is returned along with the virtual address range that it maps ([query_success_ensures]). - The mapping that is returned corresponds to the abstract mapping given by
query_item_spec. - If there is no mapped item at the current virtual address ([
query_none_condition]), it returnsNone, and the virtual address range of the cursor’s current position.
§Safety
- This function preserves all memory invariants.
- The locking mechanism prevents data races.
Sourcepub exec fn find_next(&mut self, len: usize) -> res : Option<Vaddr>
pub exec fn find_next(&mut self, len: usize) -> res : Option<Vaddr>
Tracked(owner): Tracked<&mut CursorOwner<'rcu, UserPtConfig>>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(guards): Tracked<&mut Guards>,requiresold(self).0.invariants(*old(owner), *old(regions), *old(guards)),old(self).0.find_next_panic_condition(len) ==> may_panic(),ensures!old(self).0.find_next_panic_condition(len),final(self).0.invariants(*final(owner), *final(regions), *final(guards)),res is Some
==> {
&&& res->0 == final(self).0.va
&&& final(owner).level <= final(owner).guard_level
&&& final(owner).in_locked_range()
},Moves the cursor forward to the next mapped virtual address.
If there is mapped virtual address following the current address within
next len bytes, it will return that mapped address. In this case,
the cursor will stop at the mapped address.
Otherwise, it will return None. And the cursor may stop at any
address after len bytes.
§Verified Properties
§Preconditions
- Safety Invariants: The page table cursor safety invariants ([crate::mm::page_table::Cursor::invariants]) must hold before the call.
- Liveness: In order to avoid a panic, the length must be page-aligned and less than or equal to the remaining range of the cursor.
§Postconditions
- Safety Invariants: Page table cursor safety invariants are preserved.
- Correctness: If there is a mapped address after the current address within the next
lenbytes, it will move the cursor to the next mapped address and return it. - Correctness: If the metadata region was well-formed before the call, it will be well-formed after.
§Panics
This method panics if the length is longer than the remaining range of the cursor.
§Safety
This function preserves all memory invariants. Because it panics rather than move the cursor to an invalid address, it ensures that the cursor is safe to use after the call.
Sourcepub exec fn jump(&mut self, va: Vaddr) -> res : Result<(), Error>
pub exec fn jump(&mut self, va: Vaddr) -> res : Result<(), Error>
Tracked(owner): Tracked<&mut CursorOwner<'rcu, UserPtConfig>>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(guards): Tracked<&mut Guards>,requiresold(self).0.invariants(*old(owner), *old(regions), *old(guards)),old(self).0.jump_panic_condition(va) ==> may_panic(),ensures!old(self).0.jump_panic_condition(va),final(self).0.invariants(*final(owner), *final(regions), *final(guards)),final(self).0.barrier_va.start <= va < final(self).0.barrier_va.end
==> {
&&& res is Ok
&&& final(self).0.va == va
},!(final(self).0.barrier_va.start <= va < final(self).0.barrier_va.end) ==> res is Err,Jumps to the virtual address.
If the target address is out of the range, this method will return Err.
§Panics
This method panics if the address has bad alignment.
§Verified Properties
§Preconditions
- Safety Invariants: The page table cursor safety invariants ([crate::mm::page_table::Cursor::invariants]) must hold before the call.
- Liveness: The function will panic if the target
vais not aligned to the base page size.
§Postconditions
- Safety Invariants: Page table cursor safety invariants are preserved.
- Correctness: If the target
vais within the cursor’s locked range, the result will beOkand the cursor’s virtual address will be set tova. - Correctness: If the target
vais outside the locked range, the result isErr. - Correctness: If the metadata region was well-formed before the call, it will be well-formed after.
§Safety
This function preserves all memory invariants. Because it throws an error rather than move the cursor to an invalid address, it ensures that the cursor is safe to use after the call. The locking mechanism prevents data races.
Auto Trait Implementations§
impl<'a, A> !RefUnwindSafe for Cursor<'a, A>
impl<'a, A> !UnwindSafe for Cursor<'a, A>
impl<'a, A> Freeze for Cursor<'a, A>
impl<'a, A> Send for Cursor<'a, A>where
A: Sync,
impl<'a, A> Sync for Cursor<'a, A>where
A: Sync,
impl<'a, A> Unpin for Cursor<'a, A>
impl<'a, A> UnsafeUnpin for Cursor<'a, A>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: From<T>,
impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: From<T>,
fn obeys_from_spec() -> bool
fn from_spec(v: T) -> VERUS_SPEC__A
§impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: Into<T>,
impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: Into<T>,
fn obeys_into_spec() -> bool
fn into_spec(self) -> T
§impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
fn obeys_into_spec() -> bool
fn into_spec(self) -> U
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<A> SpecEq<&A> for Awhere
A: ?Sized,
impl<A> SpecEq<&mut A> for Awhere
A: ?Sized,
impl<A> SpecEq<A> for Awhere
A: ?Sized,
impl<A> SpecEq<Ghost<A>> for A
impl<A> SpecEq<Tracked<A>> for A
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.