pub trait PageTableEntryTrait:
Clone
+ Copy
+ Debug
+ Default
+ Sized
+ Pod
+ PodOnce
+ Send
+ Sync
+ 'static {
Show 22 methods
// Required methods
spec fn new_absent_spec() -> Self;
exec fn new_absent() -> res : Self;
spec fn is_present_spec(&self) -> bool;
exec fn is_present(&self) -> bool;
spec fn new_page_spec(
paddr: Paddr,
level: PagingLevel,
prop: PageProperty,
) -> Self;
spec fn new_page_req(
paddr: Paddr,
level: PagingLevel,
prop: PageProperty,
) -> bool;
exec fn new_page(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> res : Self;
spec fn new_pt_spec(paddr: Paddr) -> Self;
exec fn new_pt(paddr: Paddr) -> res : Self;
spec fn paddr_spec(&self) -> Paddr;
exec fn paddr(&self) -> res : Paddr;
spec fn prop_spec(&self) -> PageProperty;
exec fn prop(&self) -> PageProperty;
spec fn set_prop_req(self, prop: PageProperty) -> bool;
exec fn set_prop(&mut self, prop: PageProperty);
spec fn is_last_spec(&self, level: PagingLevel) -> bool;
exec fn is_last(&self, level: PagingLevel) -> bool;
spec fn as_usize_spec(self) -> usize;
proof fn lemma_page_table_entry_properties();
proof fn lemma_paddr_is_page_aligned(self);
// Provided methods
exec fn as_usize(self) -> usize { ... }
fn from_usize(pte_raw: usize) -> Self { ... }
}Expand description
A trait that abstracts architecture-specific page table entries (PTEs).
Note that a default PTE should be a PTE that points to nothing.
Required Methods§
Sourcespec fn new_absent_spec() -> Self
spec fn new_absent_spec() -> Self
Sourceexec fn new_absent() -> res : Self
exec fn new_absent() -> res : Self
res.paddr() % PAGE_SIZE == 0,res.paddr() < MAX_PADDR,!res.is_present(),returnsSelf::new_absent(),Create a set of new invalid page table flags that indicates an absent page.
Note that currently the implementation requires an all zero PTE to be an absent PTE.
Sourcespec fn is_present_spec(&self) -> bool
spec fn is_present_spec(&self) -> bool
Sourceexec fn is_present(&self) -> bool
exec fn is_present(&self) -> bool
self.is_present_spec(),Returns if the PTE points to something.
For PTEs created by Self::new_absent, this method should return
false. For PTEs created by Self::new_page or Self::new_pt
and modified with Self::set_prop, this method should return true.
Sourcespec fn new_page_spec(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> Self
spec fn new_page_spec(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> Self
Sourcespec fn new_page_req(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> bool
spec fn new_page_req(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> bool
The preconditions for creating a new page-mapping PTE.
Sourceexec fn new_page(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> res : Self
exec fn new_page(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> res : Self
paddr < MAX_PADDR,Self::new_page_req(paddr, level, prop),ensuresres.paddr() == paddr & !((PAGE_SIZE - 1) as usize),paddr % PAGE_SIZE == 0 ==> res.paddr() == paddr,res.paddr() % PAGE_SIZE == 0,res.paddr() < MAX_PADDR,res.is_present(),res.is_last(level),res.prop() == prop,returnsSelf::new_page(paddr, level, prop),Creates a new PTE that maps to a page.
Sourcespec fn new_pt_spec(paddr: Paddr) -> Self
spec fn new_pt_spec(paddr: Paddr) -> Self
Sourceexec fn new_pt(paddr: Paddr) -> res : Self
exec fn new_pt(paddr: Paddr) -> res : Self
paddr < MAX_PADDR,ensuresres.paddr() == paddr & !((PAGE_SIZE - 1) as usize),paddr % PAGE_SIZE == 0 ==> res.paddr() == paddr,res.paddr() % PAGE_SIZE == 0,res.paddr() < MAX_PADDR,res.is_present(),forall |level: PagingLevel| !res.is_last(level),returnsSelf::new_pt(paddr),Create a new PTE that map to a child page table.
Sourcespec fn paddr_spec(&self) -> Paddr
spec fn paddr_spec(&self) -> Paddr
Returns the physical address from the PTE.
The physical address recorded in the PTE is either:
- the physical address of the next-level page table, or
- the physical address of the page that the PTE maps to.
Sourcespec fn set_prop_req(self, prop: PageProperty) -> bool
spec fn set_prop_req(self, prop: PageProperty) -> bool
The preconditions for setting the page property of a PTE.
Sourceexec fn set_prop(&mut self, prop: PageProperty)
exec fn set_prop(&mut self, prop: PageProperty)
old(self).set_prop_req(prop),ensures!old(self).is_present() ==> *old(self) == *final(self),old(self).is_present()
==> {
&&& final(self).prop() == prop
&&& final(self).paddr() == old(self).paddr()
&&& final(self).is_present()
&&& forall |level: PagingLevel| {
old(self).is_last(level) ==> final(self).is_last(level)
}
},Sourcespec fn is_last_spec(&self, level: PagingLevel) -> bool
spec fn is_last_spec(&self, level: PagingLevel) -> bool
Sourceexec fn is_last(&self, level: PagingLevel) -> bool
exec fn is_last(&self, level: PagingLevel) -> bool
self.is_last_spec(level),Returns if the PTE maps a page rather than a child page table.
The method needs to know the level of the page table where the PTE resides, since architectures like x86-64 have a huge bit only in intermediate levels.
Sourcespec fn as_usize_spec(self) -> usize
spec fn as_usize_spec(self) -> usize
Sourceproof fn lemma_page_table_entry_properties()
proof fn lemma_page_table_entry_properties()
Self::new_absent().paddr() % PAGE_SIZE == 0,Self::new_absent().paddr() < MAX_PADDR,!Self::new_absent().is_present(),forall |level: PagingLevel| 1 < level ==> !Self::new_absent().is_last(level),forall |paddr: Paddr, level: PagingLevel, prop: PageProperty| {
Self::new_page_req(paddr, level, prop)
&& (prop.cache is Writeback || prop.cache is Writethrough
|| prop.cache is Uncacheable)
==> {
&&& Self::new_page(paddr, level, prop).is_present()
&&& (paddr < MAX_PADDR
==> Self::new_page(paddr, level, prop).paddr()
== paddr & !((PAGE_SIZE - 1) as usize))
&&& (paddr < MAX_PADDR && paddr % PAGE_SIZE == 0
==> Self::new_page(paddr, level, prop).paddr() == paddr)
&&& Self::new_page(paddr, level, prop).prop() == prop
&&& Self::new_page(paddr, level, prop).is_last(level)
}
},forall |paddr: Paddr| {
&&& Self::new_pt(paddr).is_present()
&&& (paddr < MAX_PADDR
==> Self::new_pt(paddr).paddr() == paddr & !((PAGE_SIZE - 1) as usize))
&&& (paddr < MAX_PADDR && paddr % PAGE_SIZE == 0
==> Self::new_pt(paddr).paddr() == paddr)
&&& forall |level: PagingLevel| !Self::new_pt(paddr).is_last(level)
},Absent (zero) PTE has well-formed paddr for match_pte.
Sourceproof fn lemma_paddr_is_page_aligned(self)
proof fn lemma_paddr_is_page_aligned(self)
self.paddr() % PAGE_SIZE == 0,Provided Methods§
Sourceexec fn as_usize(self) -> usize
exec fn as_usize(self) -> usize
self.as_usize(),Converts the PTE into a raw usize value.
Sourceexec fn from_usize(pte_raw: usize) -> Self
exec fn from_usize(pte_raw: usize) -> Self
Converts the raw usize value into a PTE.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.