Fix the linear mapping size if the IO range is high

This commit is contained in:
Zhang Junyang 2025-05-06 17:26:25 +08:00 committed by Ruihan Li
parent d0719efcb4
commit 18df0f6ec9
4 changed files with 16 additions and 12 deletions

View File

@ -206,7 +206,7 @@ pub(super) fn get_slot(paddr: Paddr) -> Result<&'static MetaSlot, GetFrameError>
if paddr % PAGE_SIZE != 0 {
return Err(GetFrameError::NotAligned);
}
if paddr >= super::MAX_PADDR.load(Ordering::Relaxed) as Paddr {
if paddr >= super::max_paddr() {
return Err(GetFrameError::OutOfBound);
}

View File

@ -57,6 +57,13 @@ use crate::mm::{Paddr, PagingConsts, Vaddr};
static MAX_PADDR: AtomicUsize = AtomicUsize::new(0);
/// Returns the maximum physical address that is tracked by frame metadata.
pub(in crate::mm) fn max_paddr() -> Paddr {
let max_paddr = MAX_PADDR.load(Ordering::Relaxed) as Paddr;
debug_assert_ne!(max_paddr, 0);
max_paddr
}
/// A smart pointer to a frame.
///
/// A frame is a contiguous range of bytes in physical memory. The [`Frame`]
@ -299,7 +306,7 @@ impl TryFrom<Frame<dyn AnyFrameMeta>> for UFrame {
/// 2. The caller must have already held a reference to the frame.
pub(in crate::mm) unsafe fn inc_frame_ref_count(paddr: Paddr) {
debug_assert!(paddr % PAGE_SIZE == 0);
debug_assert!(paddr < MAX_PADDR.load(Ordering::Relaxed) as Paddr);
debug_assert!(paddr < max_paddr());
let vaddr: Vaddr = mapping::frame_to_meta::<PagingConsts>(paddr);
// SAFETY: `vaddr` points to a valid `MetaSlot` that will never be mutably borrowed, so taking

View File

@ -2,7 +2,7 @@
//! A contiguous range of frames.
use core::{fmt::Debug, mem::ManuallyDrop, ops::Range, sync::atomic::Ordering};
use core::{fmt::Debug, mem::ManuallyDrop, ops::Range};
use super::{
inc_frame_ref_count,
@ -90,7 +90,7 @@ impl<M: AnyFrameMeta> Segment<M> {
if range.start % PAGE_SIZE != 0 || range.end % PAGE_SIZE != 0 {
return Err(GetFrameError::NotAligned);
}
if range.end > super::MAX_PADDR.load(Ordering::Relaxed) {
if range.end > super::max_paddr() {
return Err(GetFrameError::OutOfBound);
}
assert!(range.start < range.end);

View File

@ -40,7 +40,6 @@ pub(crate) mod kvirt_area;
use core::ops::Range;
use align_ext::AlignExt;
use log::info;
use spin::Once;
#[cfg(ktest)]
@ -134,9 +133,6 @@ pub static KERNEL_PAGE_TABLE: Once<PageTable<KernelMode, PageTableEntry, PagingC
pub fn init_kernel_page_table(meta_pages: Segment<MetaPageMeta>) {
info!("Initializing the kernel page table");
let regions = &crate::boot::EARLY_INFO.get().unwrap().memory_regions;
let phys_mem_cap = regions.iter().map(|r| r.base() + r.len()).max().unwrap();
// Start to initialize the kernel page table.
let kpt = PageTable::<KernelMode>::empty();
@ -148,8 +144,9 @@ pub fn init_kernel_page_table(meta_pages: Segment<MetaPageMeta>) {
// Do linear mappings for the kernel.
{
let from = LINEAR_MAPPING_BASE_VADDR..LINEAR_MAPPING_BASE_VADDR + phys_mem_cap;
let to = 0..phys_mem_cap;
let max_paddr = crate::mm::frame::max_paddr();
let from = LINEAR_MAPPING_BASE_VADDR..LINEAR_MAPPING_BASE_VADDR + max_paddr;
let to = 0..max_paddr;
let prop = PageProperty {
flags: PageFlags::RW,
cache: CachePolicy::Writeback,
@ -199,13 +196,13 @@ pub fn init_kernel_page_table(meta_pages: Segment<MetaPageMeta>) {
// Map for the kernel code itself.
// TODO: set separated permissions for each segments in the kernel.
{
let regions = &crate::boot::EARLY_INFO.get().unwrap().memory_regions;
let region = regions
.iter()
.find(|r| r.typ() == MemoryRegionType::Kernel)
.unwrap();
let offset = kernel_loaded_offset();
let to =
region.base().align_down(PAGE_SIZE)..(region.base() + region.len()).align_up(PAGE_SIZE);
let to = region.base()..region.end();
let from = to.start + offset..to.end + offset;
let prop = PageProperty {
flags: PageFlags::RWX,