Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions ostd/specs/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub mod model;
pub use model::*;

// Compatibility re-exports for proof modules that still use `specs::arch`.
// The authoritative values live in the executable memory/architecture modules.
pub use crate::{
arch::mm::{NR_ENTRIES, NR_LEVELS},
mm::{MAX_NR_PAGES, MAX_PADDR},
};

mod x86;
pub use x86::*;
63 changes: 63 additions & 0 deletions ostd/specs/arch/model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use crate::mm::{Paddr, PagingConstsTrait, Vaddr};
use vstd::prelude::*;

verus! {

/// The paging-related part of an architecture contract.
///
/// The associated paging constants are still supplied by the existing
/// `PagingConstsTrait`; this trait only adds the architecture-wide physical
/// address bound and the proof that the two contracts are compatible.
pub trait ArchPagingModel {
type C: PagingConstsTrait;

/// The exclusive upper bound for physical frame addresses.
spec fn max_paddr_spec() -> Paddr;

proof fn lemma_paging_model_requirements()
ensures
0 < Self::max_paddr_spec(),
Self::C::BASE_PAGE_SIZE() <= Self::max_paddr_spec(),
Self::max_paddr_spec() % Self::C::BASE_PAGE_SIZE() == 0,
;
}

/// A physical address that can identify a base-page frame for architecture `A`.
pub open spec fn valid_frame_paddr_for<A: ArchPagingModel>(pa: Paddr) -> bool {
pa % A::C::BASE_PAGE_SIZE() == 0 && pa < A::max_paddr_spec()
}

/// The address-space part of an architecture contract.
pub trait ArchAddressSpaceModel: ArchPagingModel {
/// The base of the kernel's physical-to-virtual linear mapping.
spec fn linear_mapping_base_vaddr_spec() -> Vaddr;

/// The first virtual address reserved for vmalloc mappings.
spec fn vmalloc_base_vaddr_spec() -> Vaddr;

proof fn lemma_address_space_model_requirements()
ensures
Self::linear_mapping_base_vaddr_spec() % Self::C::BASE_PAGE_SIZE() == 0,
Self::linear_mapping_base_vaddr_spec() < Self::vmalloc_base_vaddr_spec(),
Self::max_paddr_spec() < Self::vmalloc_base_vaddr_spec()
- Self::linear_mapping_base_vaddr_spec(),
Self::max_paddr_spec() + Self::linear_mapping_base_vaddr_spec() < usize::MAX,
;
}

/// Convert a physical address through architecture `A`'s linear mapping.
pub open spec fn paddr_to_vaddr_for<A: ArchAddressSpaceModel>(pa: Paddr) -> Vaddr {
(pa + A::linear_mapping_base_vaddr_spec()) as usize
}

/// Convert a linear-mapped virtual address back to a physical address.
pub open spec fn vaddr_to_paddr_for<A: ArchAddressSpaceModel>(va: Vaddr) -> Paddr {
(va - A::linear_mapping_base_vaddr_spec()) as usize
}

/// The top-level contract used by architecture-independent specifications.
pub trait ArchTrait: ArchAddressSpaceModel {

}

} // verus!
86 changes: 63 additions & 23 deletions ostd/specs/arch/x86/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ use vstd::prelude::*;
use vstd::arithmetic::power2::{lemma_pow2_adds, lemma2_to64, lemma2_to64_rest, pow2};
use vstd_extra::prelude::*;

use super::model::{self, ArchAddressSpaceModel, ArchPagingModel, ArchTrait};

use crate::arch::mm::{NR_ENTRIES, NR_LEVELS};
use crate::specs::mm::{
frame::mapping::lemma_meta_to_frame_soundness,
page_table::{nr_pte_index_bits_spec, pte_index_bit_offset_spec},
};

use crate::mm::{
Paddr, PagingConstsTrait, Vaddr,
CurrentPagingConstsTrait, MAX_NR_PAGES, MAX_PADDR, Paddr, PagingConstsTrait, PagingLevel,
Vaddr,
frame::meta::{META_SLOT_SIZE, mapping::meta_to_frame},
kspace::{FRAME_METADATA_RANGE, LINEAR_MAPPING_BASE_VADDR, VMALLOC_BASE_VADDR, paddr_to_vaddr},
page_size,
Expand All @@ -22,37 +26,72 @@ global size_of usize == 8;

global size_of isize == 8;

// The following constants are the same as those defined in `ostd::arch::mm::x86_64`,
// but we record their actual values for better proof automation.
/// Page size.
pub const PAGE_SIZE: usize = 4096;
/// Page size used by the current verification target.
pub const PAGE_SIZE: usize = crate::arch::mm::x86_base_page_size!();

/// The maximum number of entries in a page table node
pub const NR_ENTRIES: usize = 512;
pub open spec fn valid_frame_paddr(paddr: Paddr) -> bool {
&&& paddr % PAGE_SIZE == 0
&&& paddr < MAX_PADDR
}

/// The maximum level of a page table node.
pub const NR_LEVELS: usize = 4;
/// The x86 instance of the architecture-wide specification contract.
pub struct X86Arch;

/// Parameterized maximum physical address.
pub const MAX_PADDR: usize = 0x8000_0000;
impl ArchPagingModel for X86Arch {
type C = crate::arch::mm::PagingConsts;

pub const MAX_NR_PAGES: u64 = (MAX_PADDR / PAGE_SIZE) as u64;
open spec fn max_paddr_spec() -> Paddr {
MAX_PADDR
}

pub open spec fn valid_frame_paddr(paddr: Paddr) -> bool {
&&& paddr % PAGE_SIZE == 0
&&& paddr < MAX_PADDR
proof fn lemma_paging_model_requirements() {
Self::C::lemma_paging_consts_requirements();

}
}

} // verus!
verus! {
impl ArchAddressSpaceModel for X86Arch {
open spec fn linear_mapping_base_vaddr_spec() -> Vaddr {
LINEAR_MAPPING_BASE_VADDR
}

open spec fn vmalloc_base_vaddr_spec() -> Vaddr {
VMALLOC_BASE_VADDR
}

proof fn lemma_address_space_model_requirements() {
Self::C::lemma_paging_consts_requirements();
Self::lemma_paging_model_requirements();
assert(Self::linear_mapping_base_vaddr_spec() % Self::C::BASE_PAGE_SIZE() == 0)
by (compute_only);

assert(Self::max_paddr_spec() < Self::vmalloc_base_vaddr_spec()
- Self::linear_mapping_base_vaddr_spec()) by (compute_only);

}
}

impl ArchTrait for X86Arch {

}

/// The architecture selected by the current verification target.
pub type CurrentArch = X86Arch;

pub proof fn lemma_valid_frame_paddr_model_equivalent(paddr: Paddr)
ensures
valid_frame_paddr(paddr) == model::valid_frame_paddr_for::<CurrentArch>(paddr),
{
CurrentArch::lemma_paging_model_requirements();
}

pub proof fn lemma_linear_mapping_base_vaddr_properties()
ensures
LINEAR_MAPPING_BASE_VADDR % PAGE_SIZE == 0,
LINEAR_MAPPING_BASE_VADDR < VMALLOC_BASE_VADDR,
{
assert(LINEAR_MAPPING_BASE_VADDR % PAGE_SIZE == 0) by (compute_only);
assert(LINEAR_MAPPING_BASE_VADDR < VMALLOC_BASE_VADDR) by (compute_only);
CurrentArch::lemma_address_space_model_requirements();

}

/// There is not an executable version in the source code.
Expand All @@ -61,7 +100,7 @@ pub open spec fn vaddr_to_paddr(va: Vaddr) -> usize
recommends
LINEAR_MAPPING_BASE_VADDR <= va < VMALLOC_BASE_VADDR,
{
(va - LINEAR_MAPPING_BASE_VADDR) as usize
model::vaddr_to_paddr_for::<CurrentArch>(va)
}

pub broadcast proof fn lemma_paddr_to_vaddr_properties(pa: Paddr)
Expand All @@ -87,8 +126,8 @@ pub proof fn lemma_max_paddr_range()
MAX_PADDR < VMALLOC_BASE_VADDR - LINEAR_MAPPING_BASE_VADDR,
MAX_PADDR + LINEAR_MAPPING_BASE_VADDR < usize::MAX,
{
assert(MAX_PADDR < VMALLOC_BASE_VADDR - LINEAR_MAPPING_BASE_VADDR) by (compute_only);
assert(MAX_PADDR + LINEAR_MAPPING_BASE_VADDR < usize::MAX) by (compute_only);
CurrentArch::lemma_address_space_model_requirements();

}

pub broadcast proof fn lemma_meta_frame_vaddr_properties(meta: Vaddr)
Expand All @@ -113,7 +152,7 @@ pub broadcast proof fn lemma_meta_frame_vaddr_properties(meta: Vaddr)

// Here are some architecture-specific const value properties.
// Any use of this lemma in architecture-independent code should be removed.
pub(crate) proof fn lemma_arch_specific_consts_properties<C: PagingConstsTrait>()
pub(crate) proof fn lemma_arch_specific_consts_properties<C: CurrentPagingConstsTrait>()
ensures
C::BASE_PAGE_SIZE().ilog2() == 12u32,
nr_pte_index_bits_spec::<C>() == 9usize,
Expand All @@ -127,6 +166,7 @@ pub(crate) proof fn lemma_arch_specific_consts_properties<C: PagingConstsTrait>(
0xffff_int * 0x1_0000_0000_0000int + pow2(48) - 1 == 0xffff_ffff_ffff_ffffint,
{
C::lemma_paging_consts_properties();
C::lemma_current_paging_consts_requirements();
lemma2_to64();
lemma2_to64_rest();
lemma_usize_pow2_ilog2(12);
Expand Down
3 changes: 2 additions & 1 deletion ostd/specs/mm/page_table/cursor/owners.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::specs::{

use crate::arch::mm::PagingConsts;
use crate::mm::{
MAX_USERSPACE_VADDR, Paddr, PagingConstsTrait, PagingLevel, Vaddr,
CurrentPagingConstsTrait, MAX_USERSPACE_VADDR, Paddr, PagingConstsTrait, PagingLevel, Vaddr,
frame::meta::{REF_COUNT_MAX, REF_COUNT_UNIQUE, REF_COUNT_UNUSED},
kspace::KernelPtConfig,
nr_subpage_per_huge,
Expand Down Expand Up @@ -2369,6 +2369,7 @@ pub proof fn lemma_view_in_vaddr_range<'rcu, C: PageTableConfig>(owner: &CursorO
},
{
C::lemma_paging_consts_properties();
C::lemma_current_paging_consts_requirements();
C::lemma_page_table_config_constant_properties();
lemma_arch_specific_consts_properties::<C>();

Expand Down
1 change: 0 additions & 1 deletion ostd/specs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#[allow(unused_braces)]
#[allow(rustdoc::invalid_rust_codeblocks)]
#[allow(rustdoc::invalid_html_tags)]
#[path = "arch/x86/mod.rs"]
pub mod arch;
#[allow(unused_parens)]
#[allow(unused_braces)]
Expand Down
Loading