Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 1 addition & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ jobs:
run: cargo build --target ${{ matrix.targets }} --all-features
- name: Unit test
if: ${{ matrix.targets == 'x86_64-unknown-linux-gnu' }}
env:
RUSTFLAGS: --cfg doc
run: cargo test --target ${{ matrix.targets }} -- --nocapture
run: cargo test --target ${{ matrix.targets }} --all-features -- --nocapture

doc:
runs-on: ubuntu-latest
Expand All @@ -39,13 +37,11 @@ jobs:
contents: write
env:
default-branch: ${{ format('refs/heads/{0}', github.event.repository.default_branch) }}
RUSTFLAGS: --cfg doc
RUSTDOCFLAGS: -Zunstable-options --enable-index-page -D rustdoc::broken_intra_doc_links -D missing-docs
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- name: Build docs
continue-on-error: ${{ github.ref != env.default-branch && github.event_name != 'pull_request' }}
run: cargo doc --no-deps --all-features
- name: Deploy to Github Pages
if: ${{ github.ref == env.default-branch }}
Expand Down
25 changes: 0 additions & 25 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions page_table_entry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ rust-version.workspace = true
[features]
arm-el2 = []

all = []

[dependencies]
bitflags = "2.9"
memory_addr.workspace = true

[target.'cfg(any(target_arch = "aarch64", doc))'.dependencies]
[dev-dependencies]
aarch64-cpu = "10.0"

[target.'cfg(any(target_arch = "x86_64", doc))'.dependencies]
x86_64 = "0.15.2"

[package.metadata.docs.rs]
rustc-args = ["--cfg", "doc"]
all-features = true
1 change: 0 additions & 1 deletion page_table_entry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ methods for manipulating various page table entries.

```rust
use memory_addr::PhysAddr;
use x86_64::structures::paging::page_table::PageTableFlags;
use page_table_entry::{GenericPTE, MappingFlags, x86_64::X64PTE};

let paddr = PhysAddr::from(0x233000);
Expand Down
25 changes: 14 additions & 11 deletions page_table_entry/src/arch/aarch64.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! AArch64 VMSAv8-64 translation table format descriptors.

use aarch64_cpu::registers::MAIR_EL1;
use core::fmt;
use memory_addr::PhysAddr;

Expand Down Expand Up @@ -99,16 +98,20 @@ impl DescriptorAttr {
impl MemAttr {
/// The MAIR_ELx register should be set to this value to match the memory
/// attributes in the descriptors.
pub const MAIR_VALUE: u64 = {
// Device-nGnRE memory
let attr0 = MAIR_EL1::Attr0_Device::nonGathering_nonReordering_EarlyWriteAck.value;
// Normal memory
let attr1 = MAIR_EL1::Attr1_Normal_Inner::WriteBack_NonTransient_ReadWriteAlloc.value
| MAIR_EL1::Attr1_Normal_Outer::WriteBack_NonTransient_ReadWriteAlloc.value;
let attr2 = MAIR_EL1::Attr2_Normal_Inner::NonCacheable.value
+ MAIR_EL1::Attr2_Normal_Outer::NonCacheable.value;
attr0 | attr1 | attr2 // 0x44_ff_04
};
///
/// ```
/// # use aarch64_cpu::registers::MAIR_EL1;
/// # use page_table_entry::aarch64::MemAttr;
/// // Device-nGnRE memory
/// let attr0 = MAIR_EL1::Attr0_Device::nonGathering_nonReordering_EarlyWriteAck.value;
/// // Normal memory
/// let attr1 = MAIR_EL1::Attr1_Normal_Inner::WriteBack_NonTransient_ReadWriteAlloc.value
/// | MAIR_EL1::Attr1_Normal_Outer::WriteBack_NonTransient_ReadWriteAlloc.value;
/// let attr2 = MAIR_EL1::Attr2_Normal_Inner::NonCacheable.value
/// + MAIR_EL1::Attr2_Normal_Outer::NonCacheable.value;
/// assert_eq!(MemAttr::MAIR_VALUE, attr0 | attr1 | attr2);
/// ```
pub const MAIR_VALUE: u64 = 0x44_ff_04;
}

impl From<DescriptorAttr> for MappingFlags {
Expand Down
8 changes: 4 additions & 4 deletions page_table_entry/src/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#[cfg(any(target_arch = "x86_64", doc))]
#[cfg(any(target_arch = "x86_64", feature = "all"))]
pub mod x86_64;

#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", doc))]
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", feature = "all"))]
pub mod riscv;

#[cfg(any(target_arch = "aarch64", doc))]
#[cfg(any(target_arch = "aarch64", feature = "all"))]
pub mod aarch64;

#[cfg(any(target_arch = "loongarch64", doc))]
#[cfg(any(target_arch = "loongarch64", feature = "all"))]
pub mod loongarch64;
69 changes: 67 additions & 2 deletions page_table_entry/src/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,75 @@
use core::fmt;
use memory_addr::PhysAddr;

pub use x86_64::structures::paging::page_table::PageTableFlags as PTF;

use crate::{GenericPTE, MappingFlags};

bitflags::bitflags! {
/// Possible flags for a page table entry.
///
/// Reference: https://docs.rs/crate/x86_64/0.15.2/source/src/structures/paging/page_table.rs
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct PTF: u64 {
/// Specifies whether the mapped frame or page table is loaded in memory.
const PRESENT = 1;
/// Controls whether writes to the mapped frames are allowed.
///
/// If this bit is unset in a level 1 page table entry, the mapped frame is read-only.
/// If this bit is unset in a higher level page table entry the complete range of mapped
/// pages is read-only.
const WRITABLE = 1 << 1;
/// Controls whether accesses from userspace (i.e. ring 3) are permitted.
const USER_ACCESSIBLE = 1 << 2;
/// If this bit is set, a “write-through” policy is used for the cache, else a “write-back”
/// policy is used.
const WRITE_THROUGH = 1 << 3;
/// Disables caching for the pointed entry is cacheable.
const NO_CACHE = 1 << 4;
/// Set by the CPU when the mapped frame or page table is accessed.
const ACCESSED = 1 << 5;
/// Set by the CPU on a write to the mapped frame.
const DIRTY = 1 << 6;
/// Specifies that the entry maps a huge frame instead of a page table. Only allowed in
/// P2 or P3 tables.
const HUGE_PAGE = 1 << 7;
/// Indicates that the mapping is present in all address spaces, so it isn't flushed from
/// the TLB on an address space switch.
const GLOBAL = 1 << 8;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_9 = 1 << 9;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_10 = 1 << 10;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_11 = 1 << 11;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_52 = 1 << 52;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_53 = 1 << 53;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_54 = 1 << 54;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_55 = 1 << 55;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_56 = 1 << 56;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_57 = 1 << 57;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_58 = 1 << 58;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_59 = 1 << 59;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_60 = 1 << 60;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_61 = 1 << 61;
/// Available to the OS, can be used to store additional data, e.g. custom flags.
const BIT_62 = 1 << 62;
/// Forbid code execution from the mapped frames.
///
/// Can be only used when the no-execute page protection feature is enabled in the EFER
/// register.
const NO_EXECUTE = 1 << 63;
}
}

impl From<PTF> for MappingFlags {
fn from(f: PTF) -> Self {
if !f.contains(PTF::PRESENT) {
Expand Down
12 changes: 7 additions & 5 deletions page_table_multiarch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,22 @@ rust-version.workspace = true
default = []
copy-from = ["dep:bitmaps"]

all = ["page_table_entry/all"]

[dependencies]
log = "0.4"
memory_addr.workspace = true
page_table_entry.workspace = true
bitmaps = { version = "3.2", default-features = false, optional = true }

[target.'cfg(any(target_arch = "x86_64", doc))'.dependencies]
[target.'cfg(target_arch = "x86_64")'.dependencies]
x86 = "0.52"

[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64", doc))'.dependencies]
[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies]
riscv = { version = "0.14", default-features = false }

[package.metadata.docs.rs]
rustc-args = ["--cfg", "doc"]

[dev-dependencies]
rand = { version = "0.9.1", default-features = false, features = ["small_rng"] }

[package.metadata.docs.rs]
all-features = true
8 changes: 4 additions & 4 deletions page_table_multiarch/src/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#[cfg(any(target_arch = "x86_64", doc))]
#[cfg(any(target_arch = "x86_64", feature = "all"))]
pub mod x86_64;

#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", doc))]
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", feature = "all"))]
pub mod riscv;

#[cfg(any(target_arch = "aarch64", doc))]
#[cfg(any(target_arch = "aarch64", feature = "all"))]
pub mod aarch64;

#[cfg(any(target_arch = "loongarch64", doc))]
#[cfg(any(target_arch = "loongarch64", feature = "all"))]
pub mod loongarch64;
18 changes: 8 additions & 10 deletions page_table_multiarch/src/arch/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@
use crate::{PageTable64, PagingMetaData};
use page_table_entry::riscv::Rv64PTE;

#[inline]
fn riscv_flush_tlb(vaddr: Option<memory_addr::VirtAddr>) {
if let Some(vaddr) = vaddr {
riscv::asm::sfence_vma(0, vaddr.as_usize())
} else {
riscv::asm::sfence_vma_all();
}
}

/// A virtual address that can be used in RISC-V Sv39 and Sv48 page tables.
pub trait SvVirtAddr: memory_addr::MemoryAddr + Send + Sync {
/// Flush the TLB.
Expand All @@ -21,7 +12,14 @@ pub trait SvVirtAddr: memory_addr::MemoryAddr + Send + Sync {
impl SvVirtAddr for memory_addr::VirtAddr {
#[inline]
fn flush_tlb(vaddr: Option<Self>) {
riscv_flush_tlb(vaddr.map(|vaddr| vaddr.into()))
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
if let Some(vaddr) = vaddr {
riscv::asm::sfence_vma(0, vaddr.as_usize())
} else {
riscv::asm::sfence_vma_all();
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
let _ = vaddr;
}
}

Expand Down
3 changes: 3 additions & 0 deletions page_table_multiarch/src/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ impl PagingMetaData for X64PagingMetaData {

#[inline]
fn flush_tlb(vaddr: Option<memory_addr::VirtAddr>) {
#[cfg(target_arch = "x86_64")]
unsafe {
if let Some(vaddr) = vaddr {
x86::tlb::flush(vaddr.into());
} else {
x86::tlb::flush_all();
}
}
#[cfg(not(target_arch = "x86_64"))]
let _ = vaddr;
}
}

Expand Down
4 changes: 4 additions & 0 deletions page_table_multiarch/tests/alloc_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ fn run_test_for<M: PagingMetaData<VirtAddr = VirtAddr>, PTE: GenericPTE>() -> Pa
}

#[test]
#[cfg(any(target_arch = "x86_64", feature = "all"))]
fn test_dealloc_x86() -> PagingResult<()> {
run_test_for::<
page_table_multiarch::x86_64::X64PagingMetaData,
Expand All @@ -100,6 +101,7 @@ fn test_dealloc_x86() -> PagingResult<()> {
}

#[test]
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", feature = "all"))]
fn test_dealloc_riscv() -> PagingResult<()> {
run_test_for::<
page_table_multiarch::riscv::Sv39MetaData<VirtAddr>,
Expand All @@ -113,6 +115,7 @@ fn test_dealloc_riscv() -> PagingResult<()> {
}

#[test]
#[cfg(any(target_arch = "aarch64", feature = "all"))]
fn test_dealloc_aarch64() -> PagingResult<()> {
run_test_for::<
page_table_multiarch::aarch64::A64PagingMetaData,
Expand All @@ -122,6 +125,7 @@ fn test_dealloc_aarch64() -> PagingResult<()> {
}

#[test]
#[cfg(any(target_arch = "loongarch64", feature = "all"))]
fn test_dealloc_loongarch64() -> PagingResult<()> {
run_test_for::<
page_table_multiarch::loongarch64::LA64MetaData,
Expand Down