pub struct GlobalMemOwner {
pub regions: MetaRegionOwners,
pub pt: PageTableOwner<UserPtConfig>,
pub tlb: TlbModel,
pub memory: Map<Paddr, FrameContents>,
}Expand description
§Global memory invariants
A GlobalMemOwner object ties together the components that are used in different layers
of the OSTD system. It is the object about which we state the invariants of the
memory system as a whole.
§Verification Structure
Operations in mm take pieces of the global state as mutable arguments,
and guarantee that their invariants are preserved. This guarantees that, at the end of each
operation, the overall internal_invariants of the system
hold. We then prove that the internal invariants imply the top-level properties that we want the
memory system to obey.
Fields§
§regions: MetaRegionOwnersMetaRegionOwners is the fundamental data structure of the frame module, tracking the allocation
of metadata slots and their permissions.
pt: PageTableOwner<UserPtConfig>PageTableOwner tracks the tree structure of the page table. It can be converted to a
[CursorOwner] for traversal and updates.
A well-formed CursorOwner can be converted back into a PageTableOwner with consistent mappings,
ensuring that its internal invariants are preserved.
tlb: TlbModelTlbModel tracks the mappings in the TLB. It can flush mappings and it can load new ones from the page table.
memory: Map<Paddr, FrameContents>FrameContents tracks the contents of a frame for use in the [VirtMem] library.
Implementations§
Source§impl GlobalMemOwner
impl GlobalMemOwner
Sourcepub closed spec fn page_table_mappings(self) -> Set<Mapping>
pub closed spec fn page_table_mappings(self) -> Set<Mapping>
The set of mappings in the page table is determined by
PageTableOwner::view_rec.
Sourcepub open spec fn page_table_mappings_disjoint_vaddrs(self) -> bool
pub open spec fn page_table_mappings_disjoint_vaddrs(self) -> bool
{
let pt_mappings = self.page_table_mappings();
forall |m1: Mapping, m2: Mapping| (
pt_mappings has m1 && pt_mappings has m2 && m1 != m2
==> Mapping::disjoint_vaddrs(m1, m2)
)
}Top-level property: the page table mappings are disjoint in the virtual address space.
Sourcepub open spec fn page_table_mappings_well_formed(self) -> bool
pub open spec fn page_table_mappings_well_formed(self) -> bool
{
let pt_mappings = self.page_table_mappings();
forall |m: Mapping| pt_mappings has m ==> #[trigger] m.inv()
}Top-level property: the page table mappings are well-formed.
See Mapping::inv.
Sourcepub open spec fn tlb_mappings_disjoint_vaddrs(self) -> bool
pub open spec fn tlb_mappings_disjoint_vaddrs(self) -> bool
{
let tlb_mappings = self.tlb.mappings;
forall |m1: Mapping, m2: Mapping| (
tlb_mappings has m1 && tlb_mappings has m2 && m1 != m2
==> Mapping::disjoint_vaddrs(m1, m2)
)
}Top-level property: the TLB mappings are disjoint in the virtual address space.
Sourcepub open spec fn tlb_mappings_disjoint_paddrs(self) -> bool
pub open spec fn tlb_mappings_disjoint_paddrs(self) -> bool
{
let tlb_mappings = self.tlb.mappings;
forall |m1: Mapping, m2: Mapping| (
tlb_mappings has m1 && tlb_mappings has m2 && m1 != m2
==> Mapping::disjoint_paddrs(m1, m2)
)
}Top-level property: the TLB mappings are disjoint in the physical address space.
Sourcepub open spec fn tlb_mappings_well_formed(self) -> bool
pub open spec fn tlb_mappings_well_formed(self) -> bool
{
let tlb_mappings = self.tlb.mappings;
forall |m: Mapping| tlb_mappings has m ==> #[trigger] m.inv()
}Top-level property: the TLB mappings are well-formed.
Sourcepub open spec fn invariants(self) -> bool
pub open spec fn invariants(self) -> bool
{
&&& self.page_table_mappings_disjoint_vaddrs()
&&& self.page_table_mappings_well_formed()
}Top-level properties: the page table mappings are disjoint in the
virtual address space and well-formed. Disjointness in the physical
address space is intentionally not claimed — shared frame mappings
(Phase 3 of the paths_in_pt refactor) legitimately map the same
paddr at multiple vaddrs.
Sourcepub open spec fn internal_invariants(self) -> bool
pub open spec fn internal_invariants(self) -> bool
{
&&& self.regions.inv()
&&& self.pt.inv()
&&& self.pt.metaregion_sound(self.regions)
&&& self.tlb.consistent_with_pt(self.pt.view())
}Internal invariants for GlobalMemOwner: the page table is consistent with the TLB
and with the allocated regions, and the internal invariants of each component hold.
Note that some API functions break the consistency between the page table and the TLB,
making it the responsibility of the caller to restore it by flushing the TLB.
Sourcepub proof fn internal_invariants_imply_top_level_properties(self)
pub proof fn internal_invariants_imply_top_level_properties(self)
self.internal_invariants(),ensuresself.invariants(),If the internal invariants hold, then the top-level properties hold.
Auto Trait Implementations§
impl !RefUnwindSafe for GlobalMemOwner
impl !UnwindSafe for GlobalMemOwner
impl Freeze for GlobalMemOwner
impl Send for GlobalMemOwner
impl Sync for GlobalMemOwner
impl Unpin for GlobalMemOwner
impl UnsafeUnpin for GlobalMemOwner
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.