diff --git a/framework/aster-frame/Cargo.toml b/framework/aster-frame/Cargo.toml index 16c9b87b7..25b3601fc 100644 --- a/framework/aster-frame/Cargo.toml +++ b/framework/aster-frame/Cargo.toml @@ -47,6 +47,3 @@ iced-x86 = { version = "1.21.0", default-features = false, features = [ "no_std" [features] intel_tdx = ["dep:tdx-guest", "dep:iced-x86"] -# To actively recycle page table nodes while the `VmSpace` is alive, this saves -# memory but may lead to the page table free-reuse-then-read problem. -page_table_recycle = [] diff --git a/framework/aster-frame/src/mm/mod.rs b/framework/aster-frame/src/mm/mod.rs index e106ab0df..906898253 100644 --- a/framework/aster-frame/src/mm/mod.rs +++ b/framework/aster-frame/src/mm/mod.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(dead_code)] - //! Virtual memory (VM). /// Virtual addresses. @@ -85,6 +83,7 @@ pub(crate) const fn nr_subpage_per_huge() -> usize { } /// The number of base pages in a huge page at a given level. +#[allow(dead_code)] pub(crate) const fn nr_base_per_page(level: PagingLevel) -> usize { page_size::(level) / C::BASE_PAGE_SIZE } diff --git a/framework/aster-frame/src/mm/page/meta.rs b/framework/aster-frame/src/mm/page/meta.rs index 36986dbe9..27d25be82 100644 --- a/framework/aster-frame/src/mm/page/meta.rs +++ b/framework/aster-frame/src/mm/page/meta.rs @@ -1,8 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(dead_code)] -#![allow(unused_variables)] - //! Metadata management of pages. //! //! You can picture a globally shared, static, gigantic arrary of metadata initialized for each page. @@ -64,8 +61,10 @@ use crate::{ pub enum PageUsage { // The zero variant is reserved for the unused type. Only an unused page // can be designated for one of the other purposes. + #[allow(dead_code)] Unused = 0, /// The page is reserved or unusable. The kernel should not touch it. + #[allow(dead_code)] Reserved = 1, /// The page is used as a frame, i.e., a page of untyped memory. @@ -95,9 +94,9 @@ pub(in crate::mm) struct MetaSlot { } pub(super) union MetaSlotInner { - frame: ManuallyDrop, + _frame: ManuallyDrop, // Make sure the the generic parameters don't effect the memory layout. - pt: ManuallyDrop>, + _pt: ManuallyDrop>, } // Currently the sizes of the `MetaSlotInner` union variants are no larger @@ -166,7 +165,7 @@ pub struct MetaPageMeta {} impl Sealed for MetaPageMeta {} impl PageMeta for MetaPageMeta { const USAGE: PageUsage = PageUsage::Meta; - fn on_drop(page: &mut Page) { + fn on_drop(_page: &mut Page) { panic!("Meta pages are currently not allowed to be dropped"); } } @@ -178,7 +177,7 @@ pub struct KernelMeta {} impl Sealed for KernelMeta {} impl PageMeta for KernelMeta { const USAGE: PageUsage = PageUsage::Kernel; - fn on_drop(page: &mut Page) { + fn on_drop(_page: &mut Page) { panic!("Kernel pages are not allowed to be dropped"); } } diff --git a/framework/aster-frame/src/mm/page/mod.rs b/framework/aster-frame/src/mm/page/mod.rs index ae5a525ca..7480c9427 100644 --- a/framework/aster-frame/src/mm/page/mod.rs +++ b/framework/aster-frame/src/mm/page/mod.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(dead_code)] - //! Physical memory page management. //! //! A page is an aligned, contiguous range of bytes in physical memory. The sizes @@ -149,18 +147,6 @@ impl Page { mapping::meta_to_page::(self.ptr as Vaddr) } - /// Load the current reference count of this page. - /// - /// # Safety - /// - /// This method by itself is safe, but using it correctly requires extra care. - /// Another thread can change the reference count at any time, including - /// potentially between calling this method and the action depending on the - /// result. - pub fn count(&self) -> u32 { - self.get_ref_count().load(Ordering::Relaxed) - } - /// Get the metadata of this page. pub fn meta(&self) -> &M { unsafe { &*(self.ptr as *const M) } diff --git a/framework/aster-frame/src/mm/page_table/cursor.rs b/framework/aster-frame/src/mm/page_table/cursor.rs index 8af8b8250..4a2710157 100644 --- a/framework/aster-frame/src/mm/page_table/cursor.rs +++ b/framework/aster-frame/src/mm/page_table/cursor.rs @@ -1,8 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(dead_code)] -#![allow(unused_variables)] - //! The page table cursor for mapping and querying over the page table. //! //! ## The page table lock protocol @@ -53,7 +50,7 @@ //! required. The cursor unlock all locks, then lock all the way down to `B`, then //! check if `B` is empty, and finally recycle all the resources on the way back. -use core::{any::TypeId, ops::Range}; +use core::{any::TypeId, marker::PhantomData, ops::Range}; use align_ext::AlignExt; @@ -74,6 +71,7 @@ pub(crate) enum PageTableQueryResult { frame: Frame, prop: PageProperty, }, + #[allow(dead_code)] MappedUntracked { va: Vaddr, pa: Paddr, @@ -96,12 +94,12 @@ pub(crate) struct Cursor<'a, M: PageTableMode, E: PageTableEntryTrait, C: Paging where [(); C::NR_LEVELS as usize]:, { - pt: &'a PageTable, guards: [Option>; C::NR_LEVELS as usize], level: PagingLevel, // current level guard_level: PagingLevel, // from guard_level to level, the locks are held va: Vaddr, // current virtual address barrier_va: Range, // virtual address range that is locked + phantom: PhantomData<&'a PageTable>, } impl<'a, M: PageTableMode, E: PageTableEntryTrait, C: PagingConstsTrait> Cursor<'a, M, E, C> @@ -131,12 +129,12 @@ where } }); let mut cursor = Self { - pt, guards, level: C::NR_LEVELS, guard_level: C::NR_LEVELS, va: va.start, barrier_va: va.clone(), + phantom: PhantomData, }; // Go down and get proper locks. The cursor should hold a lock of a // page table node containing the virtual address range. @@ -221,26 +219,15 @@ where /// /// This method requires locks acquired before calling it. The discarded level will be unlocked. fn level_up(&mut self) { - #[cfg(feature = "page_table_recycle")] - let last_node_all_unmapped = self.cur_node().nr_valid_children() == 0; self.guards[(C::NR_LEVELS - self.level) as usize] = None; self.level += 1; - #[cfg(feature = "page_table_recycle")] - { - let can_release_child = - TypeId::of::() == TypeId::of::() && self.level < C::NR_LEVELS; - if can_release_child && last_node_all_unmapped { - let idx = self.cur_idx(); - let untracked = self.in_untracked_range(); - self.cur_node_mut().unset_child(idx, false, untracked); - } - } + + // TODO: Drop page tables if page tables become empty. } /// Goes down a level assuming a child page table exists. fn level_down(&mut self) { debug_assert!(self.level > 1); - let idx = pte_index::(self.va, self.level); if let Child::PageTable(nxt_lvl_frame) = self.cur_child() { self.level -= 1; self.guards[(C::NR_LEVELS - self.level) as usize] = Some(nxt_lvl_frame.lock()); @@ -298,40 +285,6 @@ where } } -#[cfg(feature = "page_table_recycle")] -impl Drop for Cursor<'_, M, E, C> -where - [(); C::NR_LEVELS as usize]:, -{ - fn drop(&mut self) { - // Recycle what we can recycle now. - while self.level < self.guard_level { - self.level_up(); - } - // No need to do further cleanup if it is the root node or - // there are mappings left. - if self.level == self.guard_level || self.cur_node().nr_valid_children() != 0 { - return; - } - // Drop the lock on the guard level. - self.guards[C::NR_LEVELS - self.guard_level] = None; - // Re-walk the page table to retreive the locks. - self.guards[0] = Some(self.pt.root.clone_shallow().lock()); - self.level = C::NR_LEVELS; - let cur_pte = self.read_cur_pte(); - let cur_child_is_pt = cur_pte.is_present() && !cur_pte.is_last(self.level); - // Another cursor can unmap the guard level node before this cursor - // is dropped, we can just do our best here when re-walking. - while self.level > self.guard_level && cur_child_is_pt { - self.level_down(); - } - // Doing final cleanup by [`CursorMut::level_up`] to the root. - while self.level < C::NR_LEVELS { - self.level_up(); - } - } -} - /// The cursor of a page table that is capable of map, unmap or protect pages. /// /// Also, it has all the capabilities of a [`Cursor`]. A virtual address range @@ -425,7 +378,6 @@ where debug_assert_eq!(self.0.level, frame.level()); // Map the current page. let idx = self.0.cur_idx(); - let level = self.0.level; self.cur_node_mut().set_child_frame(idx, frame, prop); self.0.move_forward(); } @@ -592,7 +544,6 @@ where return Err(PageTableError::ProtectingPartial); } let idx = self.0.cur_idx(); - let level = self.0.level; let mut pte_prop = cur_pte.prop(); op(&mut pte_prop); self.cur_node_mut().protect(idx, pte_prop); diff --git a/framework/aster-frame/src/mm/page_table/mod.rs b/framework/aster-frame/src/mm/page_table/mod.rs index 6801cbebf..d42cb1de1 100644 --- a/framework/aster-frame/src/mm/page_table/mod.rs +++ b/framework/aster-frame/src/mm/page_table/mod.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(dead_code)] - use core::{fmt::Debug, marker::PhantomData, ops::Range}; use pod::Pod; @@ -181,10 +179,6 @@ where } } - pub(crate) unsafe fn activate_unchecked(&self) { - self.root.activate(); - } - pub(in crate::mm) unsafe fn first_activate_unchecked(&self) { self.root.first_activate(); } diff --git a/framework/aster-frame/src/mm/page_table/node.rs b/framework/aster-frame/src/mm/page_table/node.rs index f16a3d2dd..071d1b0d0 100644 --- a/framework/aster-frame/src/mm/page_table/node.rs +++ b/framework/aster-frame/src/mm/page_table/node.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(dead_code)] - //! This module defines page table node abstractions and the handle. //! //! The page table node is also frequently referred to as a page table in many architectural @@ -101,15 +99,6 @@ where } } - pub(super) fn nr_valid_children(&self) -> u16 { - // SAFETY: The physical address in the raw handle is valid and we are - // accessing the page table node. We forget the handle when finished. - let page = unsafe { Page::>::from_raw(self.paddr()) }; - let nr = page.meta().nr_children; - core::mem::forget(page); - nr - } - /// Activates the page table assuming it is a root page table. /// /// Here we ensure not dropping an active page table by making a @@ -393,12 +382,6 @@ where self.overwrite_pte(idx, pte, true); } - /// The number of mapped frames or page tables. - /// This is to track if we can free itself. - pub(super) fn nr_valid_children(&self) -> u16 { - self.page.meta().nr_children - } - /// Reads the info from a page table entry at a given index. pub(super) fn read_pte_prop(&self, idx: usize) -> PageProperty { self.read_pte(idx).prop()