KVirtArea

Struct KVirtArea 

Source
pub struct KVirtArea {
    pub range: Range<Vaddr>,
}
Expand description

Kernel virtual area.

A kernel virtual area manages a range of memory in VMALLOC_VADDR_RANGE. It can map a portion or the entirety of its virtual memory pages to physical memory, whether tracked with metadata or not.

It is the caller’s responsibility to ensure TLB coherence before using the mapped virtual address on a certain CPU.

Fields§

§range: Range<Vaddr>

Implementations§

Source§

impl KVirtArea

Source

pub exec fn start(&self) -> Vaddr

Source

pub exec fn end(&self) -> Vaddr

Source

pub exec fn range(&self) -> Range<Vaddr>

Source

pub open spec fn query_some_condition(self, owner: KVirtAreaOwner, addr: Vaddr) -> bool

{ owner.cursor_view_at(addr).present() }

Whether there is a mapped item at the page containing the address.

Source

pub open spec fn query_some_ensures( self, owner: KVirtAreaOwner, addr: Vaddr, r: Option<MappedItem>, ) -> bool

{ r is Some && owner.cursor_view_at(addr).query_item_spec(r.unwrap()) is Some }

Postcondition when a mapping exists at the page.

The returned item corresponds to the abstract mapping given by query_item_spec.

Source

pub open spec fn query_none_ensures(r: Option<MappedItem>) -> bool

{ r is None }

Postcondition when no mapping exists at the page.

Source

pub exec fn query<A: InAtomicMode>(&self, addr: Vaddr) -> r : Option<MappedItem>

with
Tracked(owner): Tracked<KVirtAreaOwner>,
requires
self.inv(),
self.range.start <= addr && addr < self.range.end,
ensures
self.query_some_condition(owner, addr) ==> self.query_some_ensures(owner, addr, r),
!self.query_some_condition(owner, addr) ==> Self::query_none_ensures(r),

Queries the mapping at the given virtual address.

Returns the mapped item at the page containing addr, or None if there is no mapping.

§Preconditions
  • The kernel virtual area invariant holds (inv).
  • The address is within the virtual area’s range.
§Postconditions
  • If there is a mapped item at the page containing the address ([query_some_condition]), it is returned ([query_some_ensures]).
  • If there is no mapping at that page, None is returned ([query_none_ensures]).
Source

pub exec fn map_frames<'a, T: AnyUFrameMeta, A: InAtomicMode + 'a>( area_size: usize, map_offset: usize, frames: Vec<Frame<T>>, prop: PageProperty, ) -> Self

with
Tracked(owner): Tracked<KVirtAreaOwner>,
Tracked(entry_owners): Tracked<&mut Seq<EntryOwner<KernelPtConfig>>>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(guards): Tracked<&mut Guards<'a, KernelPtConfig>>,
Tracked(guard_perm): Tracked<GuardPerm<'a, KernelPtConfig>>,
requires
0 < area_size,
map_offset < area_size,
map_offset % PAGE_SIZE == 0,
area_size <= usize::MAX / 2,
old(entry_owners).len() == frames.len(),
frames.len() as int * PAGE_SIZE as int + map_offset as int <= area_size as int,
forall |i: int| {
    0 <= i < old(entry_owners).len() ==> (#[trigger] old(entry_owners)[i]).inv()
},
forall |i: int| {
    0 <= i < frames.len()
        ==> frame_entry_wf(frames[i], prop, #[trigger] old(entry_owners)[i])
},
forall |i: int| {
    0 <= i < frames.len()
        ==> CursorMut::<
            'a,
            KernelPtConfig,
            A,
        >::item_not_mapped(
            MappedItem::Tracked(frame_as_dynframe(#[trigger] frames[i]), prop),
            *old(regions),
        )
},
forall |i: int, j: int| {
    0 <= i < j < frames.len()
        ==> (#[trigger] old(entry_owners)[i]).frame.unwrap().mapped_pa
            != (#[trigger] old(entry_owners)[j]).frame.unwrap().mapped_pa
},

Create a kernel virtual area and map tracked pages into it.

The created virtual area will have a size of area_size, and the pages will be mapped starting from map_offset in the area.

§Panics

This function panics if

  • the area size is not a multiple of PAGE_SIZE;
  • the map offset is not aligned to PAGE_SIZE;
  • the map offset plus the size of the pages exceeds the area size.
Source

pub unsafe exec fn map_untracked_frames<'a, A: InAtomicMode + 'a>( area_size: usize, map_offset: usize, pa_range: Range<Paddr>, prop: PageProperty, ) -> Self

with
Tracked(owner): Tracked<KVirtAreaOwner>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(guards): Tracked<&mut Guards<'a, KernelPtConfig>>,
Tracked(guard_perm): Tracked<GuardPerm<'a, KernelPtConfig>>,
requires
0 < area_size,
area_size <= usize::MAX / 2,
map_offset % PAGE_SIZE == 0,
map_offset < area_size,
pa_range.end as nat - pa_range.start as nat <= area_size as nat - map_offset as nat,
pa_range.end <= MAX_PADDR,
pa_range.start % PAGE_SIZE == 0,
pa_range.end % PAGE_SIZE == 0,
old(regions).paddr_range_not_mapped(pa_range),

Creates a kernel virtual area and maps untracked frames into it.

The created virtual area will have a size of area_size, and the physical addresses will be mapped starting from map_offset in the area.

You can provide a 0..0 physical range to create a virtual area without mapping any physical memory.

§Panics

This function panics if

  • the area size is not a multiple of PAGE_SIZE;
  • the map offset is not aligned to PAGE_SIZE;
  • the provided physical range is not aligned to PAGE_SIZE;
  • the map offset plus the length of the physical range exceeds the area size;
  • the provided physical range contains tracked physical addresses.

Trait Implementations§

Source§

impl Debug for KVirtArea

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Inv for KVirtArea

Source§

open spec fn inv(self) -> bool

{
    &&& KERNEL_BASE_VADDR <= self.range.start
    &&& self.range.end <= KERNEL_END_VADDR

}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: From<T>,

§

fn obeys_from_spec() -> bool

§

fn from_spec(v: T) -> VERUS_SPEC__A

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: Into<T>,

§

fn obeys_into_spec() -> bool

§

fn into_spec(self) -> T

§

impl<T, U> IntoSpecImpl<U> for T
where U: From<T>,

§

fn obeys_into_spec() -> bool

§

fn into_spec(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, VERUS_SPEC__A> TryFromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryFrom<T>,

§

fn obeys_try_from_spec() -> bool

§

fn try_from_spec( v: T, ) -> Result<VERUS_SPEC__A, <VERUS_SPEC__A as TryFrom<T>>::Error>

Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T, VERUS_SPEC__A> TryIntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryInto<T>,

§

fn obeys_try_into_spec() -> bool

§

fn try_into_spec(self) -> Result<T, <VERUS_SPEC__A as TryInto<T>>::Error>

§

impl<T, U> TryIntoSpecImpl<U> for T
where U: TryFrom<T>,

§

fn obeys_try_into_spec() -> bool

§

fn try_into_spec(self) -> Result<U, <U as TryFrom<T>>::Error>