Regulate the mapping tracking status of page tables

This commit is contained in:
Zhang Junyang
2024-09-24 16:13:40 +08:00
committed by Tate, Hongliang Tian
parent 909fb23f8c
commit 5bdf85b5f0
6 changed files with 321 additions and 201 deletions

View File

@ -3,8 +3,8 @@
use core::{fmt::Debug, marker::PhantomData, ops::Range};
use super::{
nr_subpage_per_huge, page_prop::PageProperty, page_size, Paddr, PagingConstsTrait, PagingLevel,
Vaddr,
nr_subpage_per_huge, page::meta::MapTrackingStatus, page_prop::PageProperty, page_size, Paddr,
PagingConstsTrait, PagingLevel, Vaddr,
};
use crate::{
arch::mm::{PageTableEntry, PagingConsts},
@ -101,15 +101,16 @@ impl PageTable<KernelMode> {
/// duplicate the kernel page table with all the kernel mappings shared.
pub fn create_user_page_table(&self) -> PageTable<UserMode> {
let root_node = self.root.clone_shallow().lock();
let mut new_node = PageTableNode::alloc(PagingConsts::NR_LEVELS);
let mut new_node =
PageTableNode::alloc(PagingConsts::NR_LEVELS, MapTrackingStatus::NotApplicable);
// Make a shallow copy of the root node in the kernel space range.
// The user space range is not copied.
const NR_PTES_PER_NODE: usize = nr_subpage_per_huge::<PagingConsts>();
for i in NR_PTES_PER_NODE / 2..NR_PTES_PER_NODE {
let child = root_node.child(i, /* meaningless */ true);
let child = root_node.child(i);
if !child.is_none() {
let _ = new_node.replace_child(i, child, /* meaningless */ true);
let _ = new_node.replace_child(i, child);
}
}
@ -137,12 +138,16 @@ impl PageTable<KernelMode> {
let mut root_node = self.root.clone_shallow().lock();
for i in start..end {
if !root_node.read_pte(i).is_present() {
let node = PageTableNode::alloc(PagingConsts::NR_LEVELS - 1);
let _ = root_node.replace_child(
i,
Child::PageTable(node.into_raw()),
i < NR_PTES_PER_NODE * 3 / 4,
);
let nxt_level = PagingConsts::NR_LEVELS - 1;
let is_tracked = if super::kspace::should_map_as_tracked(
i * page_size::<PagingConsts>(nxt_level),
) {
MapTrackingStatus::Tracked
} else {
MapTrackingStatus::Untracked
};
let node = PageTableNode::alloc(nxt_level, is_tracked);
let _ = root_node.replace_child(i, Child::PageTable(node.into_raw()));
}
}
}
@ -175,7 +180,8 @@ where
/// Create a new empty page table. Useful for the kernel page table and IOMMU page tables only.
pub fn empty() -> Self {
PageTable {
root: PageTableNode::<E, C>::alloc(C::NR_LEVELS).into_raw(),
root: PageTableNode::<E, C>::alloc(C::NR_LEVELS, MapTrackingStatus::NotApplicable)
.into_raw(),
_phantom: PhantomData,
}
}