Skip to content
This repository was archived by the owner on Apr 24, 2026. It is now read-only.
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/post-commit-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
- pull_request

env:
NIGHTLY_VERSION: nightly-2025-07-25
NIGHTLY_VERSION: nightly-2025-08-10

defaults:
run:
Expand Down
10 changes: 5 additions & 5 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "libsys"
version = "0.3.3"
version = "0.3.4"
edition = "2024"

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2025-07-25"
channel = "nightly-2025-08-10"
components = ["rust-src", "rustfmt", "clippy"]
profile = "minimal"
34 changes: 0 additions & 34 deletions src/constants/mod.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,4 @@
#![allow(clippy::missing_panics_doc)]

use core::num::NonZero;

#[cfg(target_arch = "x86_64")]
mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::*;

#[cfg(not(test))]
static PAGING_DEPTH: spin::Once<NonZero<u32>> = spin::Once::new();

/// Sets the current paging depth.
///
/// # Safety
///
/// - `value` must be the current paging depth.
///
/// # Remarks
///
/// If `value` is *not* the current paging depth, it will be possible to
/// construct invalid [`Address`][crate::address::Address] kinds that rely on
/// checking the current paging depth to ensure canonicality.
#[cfg(not(test))]
pub unsafe fn set_paging_depth(paging_depth: NonZero<u32>) {
PAGING_DEPTH.call_once(|| paging_depth);
}

pub fn get_paging_depth() -> NonZero<u32> {
cfg_select! {
test => {
// Safety: Value is non-zero.
unsafe { NonZero::new_unchecked(4) }
}

_ => { *PAGING_DEPTH.get().expect("paging depth has not been set") }
}
}
42 changes: 36 additions & 6 deletions src/constants/x86_64.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
use crate::constants::get_paging_depth;
use core::num::NonZero;

#[cfg(test)]
#[must_use]
pub fn get_paging_depth() -> NonZero<u32> {
// Safety: Value is non-zero.
unsafe { NonZero::new_unchecked(4) }
}

#[cfg(not(test))]
#[must_use]
pub fn get_paging_depth() -> NonZero<u32> {
const CR4_LA57_BIT: usize = 1 << 12;

let cr4: usize;

unsafe {
core::arch::asm!(
"mov {}, cr4",
out(reg) cr4,
options(nostack, nomem, preserves_flags)
);
}

if (cr4 & CR4_LA57_BIT) == 0 {
// Safety: Value is non-zero.
unsafe { NonZero::new_unchecked(4) }
} else {
// Safety: Value is non-zero.
unsafe { NonZero::new_unchecked(5) }
}
}

/// Bit shift required to offset page indexes.
#[must_use]
pub const fn page_bits() -> NonZero<u32> {
Expand Down Expand Up @@ -105,17 +135,17 @@ pub const fn is_physical_address_canonical(physical_address: usize) -> bool {
/// Bit-shift to reach non-canonical bits of a virtual address.
#[must_use]
pub fn virtual_address_bits() -> NonZero<u32> {
let table_indexes_shift = table_index_bits().checked_mul(get_paging_depth()).unwrap();
let total_shift = table_indexes_shift.checked_add(page_bits().get()).unwrap();
let table_indexes_shift = table_index_bits().get() * get_paging_depth().get();
let total_shift = table_indexes_shift + page_bits().get();

NonZero::<u32>::new(total_shift.get()).unwrap()
// Safety: Operations cannot overflow with the provided constants.
unsafe { NonZero::<u32>::new_unchecked(total_shift) }
}

/// Checks whether a provided address has only the canonical virtual bits.
#[must_use]
pub fn is_virtual_address_canonical(virtual_address: usize) -> bool {
let sign_extension_check_shift = virtual_address_bits().get().checked_sub(1).unwrap();

let sign_extension_check_shift = virtual_address_bits().get() - 1;
matches!(virtual_address >> sign_extension_check_shift, 0 | 0x1FFFF)
}

Expand Down