From bdc3217ddc3a90ceb8ffedc723ce2a72d70a5152 Mon Sep 17 00:00:00 2001 From: zdivelbiss <8019570+zdivelbiss@users.noreply.github.com> Date: Mon, 11 Aug 2025 10:56:56 -0500 Subject: [PATCH 1/3] read paging level directly --- src/constants/mod.rs | 34 --------------------------------- src/constants/x86_64.rs | 42 +++++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/constants/mod.rs b/src/constants/mod.rs index 711428a..4bd2cbd 100644 --- a/src/constants/mod.rs +++ b/src/constants/mod.rs @@ -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> = 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) { - PAGING_DEPTH.call_once(|| paging_depth); -} - -pub fn get_paging_depth() -> NonZero { - cfg_select! { - test => { - // Safety: Value is non-zero. - unsafe { NonZero::new_unchecked(4) } - } - - _ => { *PAGING_DEPTH.get().expect("paging depth has not been set") } - } -} diff --git a/src/constants/x86_64.rs b/src/constants/x86_64.rs index 385f71b..e70e662 100644 --- a/src/constants/x86_64.rs +++ b/src/constants/x86_64.rs @@ -1,6 +1,36 @@ -use crate::constants::get_paging_depth; use core::num::NonZero; +#[cfg(test)] +#[must_use] +pub fn get_paging_depth() -> NonZero { + // Safety: Value is non-zero. + unsafe { NonZero::new_unchecked(4) } +} + +#[cfg(not(test))] +#[must_use] +pub fn get_paging_depth() -> NonZero { + 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 { @@ -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 { - 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::::new(total_shift.get()).unwrap() + // Safety: Operations cannot overflow with the provided constants. + unsafe { NonZero::::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) } From 1fc38c44cff6192c7901f408082e38ac073a7886 Mon Sep 17 00:00:00 2001 From: zdivelbiss <8019570+zdivelbiss@users.noreply.github.com> Date: Mon, 11 Aug 2025 10:59:18 -0500 Subject: [PATCH 2/3] bump version --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43ebc21..6b79447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "libsys" -version = "0.3.3" +version = "0.3.4" dependencies = [ "num_enum", "spin", @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "beef09f85ae72cea1ef96ba6870c51e6382ebfa4f0e85b643459331f3daa5be0" dependencies = [ "unicode-ident", ] @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "spin" diff --git a/Cargo.toml b/Cargo.toml index 19c87b7..cb6051e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsys" -version = "0.3.3" +version = "0.3.4" edition = "2024" [dependencies] From d85a052f0c118c14dbd56c0f2455c68b79ec7f7b Mon Sep 17 00:00:00 2001 From: zdivelbiss <8019570+zdivelbiss@users.noreply.github.com> Date: Mon, 11 Aug 2025 11:01:20 -0500 Subject: [PATCH 3/3] bump nightly --- .github/workflows/post-commit-workflow.yaml | 2 +- rust-toolchain.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/post-commit-workflow.yaml b/.github/workflows/post-commit-workflow.yaml index e440c87..69d6188 100644 --- a/.github/workflows/post-commit-workflow.yaml +++ b/.github/workflows/post-commit-workflow.yaml @@ -4,7 +4,7 @@ on: - pull_request env: - NIGHTLY_VERSION: nightly-2025-07-25 + NIGHTLY_VERSION: nightly-2025-08-10 defaults: run: diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 90cf573..24b35e1 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-07-25" +channel = "nightly-2025-08-10" components = ["rust-src", "rustfmt", "clippy"] profile = "minimal"