From 679e5dac68a669fbe5bc50fa0717c8db9c868d08 Mon Sep 17 00:00:00 2001 From: Zhang Junyang Date: Sun, 5 May 2024 22:51:01 +0800 Subject: [PATCH] Remove the VA to PA API and tidy up kernel space --- framework/aster-frame/src/io_mem.rs | 6 +-- framework/aster-frame/src/trap/handler.rs | 8 ++-- framework/aster-frame/src/vm/kspace.rs | 41 +++++++++++------ framework/aster-frame/src/vm/mod.rs | 46 ++----------------- .../aster-frame/src/vm/page_table/mod.rs | 2 +- 5 files changed, 40 insertions(+), 63 deletions(-) diff --git a/framework/aster-frame/src/io_mem.rs b/framework/aster-frame/src/io_mem.rs index 289013aa7..2c5b3b035 100644 --- a/framework/aster-frame/src/io_mem.rs +++ b/framework/aster-frame/src/io_mem.rs @@ -5,7 +5,7 @@ use core::{mem::size_of, ops::Range}; use pod::Pod; use crate::{ - vm::{paddr_to_vaddr, HasPaddr, Paddr, Vaddr, VmIo}, + vm::{kspace::LINEAR_MAPPING_BASE_VADDR, paddr_to_vaddr, HasPaddr, Paddr, Vaddr, VmIo}, Error, Result, }; @@ -54,7 +54,7 @@ impl VmIo for IoMem { impl HasPaddr for IoMem { fn paddr(&self) -> Paddr { - crate::vm::vaddr_to_paddr(self.virtual_address).unwrap() + self.virtual_address - LINEAR_MAPPING_BASE_VADDR } } @@ -70,7 +70,7 @@ impl IoMem { } pub fn paddr(&self) -> Paddr { - crate::vm::vaddr_to_paddr(self.virtual_address).unwrap() + self.virtual_address - LINEAR_MAPPING_BASE_VADDR } pub fn length(&self) -> usize { diff --git a/framework/aster-frame/src/trap/handler.rs b/framework/aster-frame/src/trap/handler.rs index d46090b67..2e1168876 100644 --- a/framework/aster-frame/src/trap/handler.rs +++ b/framework/aster-frame/src/trap/handler.rs @@ -19,9 +19,9 @@ use crate::{ cpu::{CpuException, PageFaultErrorCode, PAGE_FAULT}, cpu_local, vm::{ - kspace::{KERNEL_PAGE_TABLE, LINEAR_MAPPING_BASE_VADDR}, + kspace::{KERNEL_PAGE_TABLE, LINEAR_MAPPING_BASE_VADDR, LINEAR_MAPPING_VADDR_RANGE}, page_prop::{CachePolicy, PageProperty}, - PageFlags, PrivilegedPageFlags as PrivFlags, PAGE_SIZE, PHYS_MEM_VADDR_RANGE, + PageFlags, PrivilegedPageFlags as PrivFlags, PAGE_SIZE, }, }; @@ -192,8 +192,8 @@ fn handle_kernel_page_fault(f: &TrapFrame) { ); assert!( - PHYS_MEM_VADDR_RANGE.contains(&(page_fault_vaddr as usize)), - "kernel page fault: the address is outside the range of the direct mapping", + LINEAR_MAPPING_VADDR_RANGE.contains(&(page_fault_vaddr as usize)), + "kernel page fault: the address is outside the range of the linear mapping", ); const SUPPORTED_ERROR_CODES: PageFaultErrorCode = PageFaultErrorCode::PRESENT diff --git a/framework/aster-frame/src/vm/kspace.rs b/framework/aster-frame/src/vm/kspace.rs index b1ea83de2..255c7fc92 100644 --- a/framework/aster-frame/src/vm/kspace.rs +++ b/framework/aster-frame/src/vm/kspace.rs @@ -2,11 +2,13 @@ //! Kernel memory space management. +use core::ops::Range; + use align_ext::AlignExt; use spin::Once; use super::{ - page_table::{nr_ptes_per_node, page_walk, KernelMode, PageTable}, + page_table::{nr_ptes_per_node, KernelMode, PageTable}, CachePolicy, MemoryRegionType, Paddr, PageFlags, PageProperty, PrivilegedPageFlags, Vaddr, PAGE_SIZE, }; @@ -16,25 +18,38 @@ use crate::arch::mm::{PageTableEntry, PagingConsts}; /// memory in the kernel address space. pub(crate) const LINEAR_MAPPING_BASE_VADDR: Vaddr = 0xffff_8000_0000_0000; +/// The maximum size of the direct mapping of physical memory. +/// +/// This size acts as a cap. If the actual memory size exceeds this value, +/// the remaining memory cannot be included in the direct mapping because +/// the maximum size of the direct mapping is limited by this value. On +/// the other hand, if the actual memory size is smaller, the direct +/// mapping can shrink to save memory consumption due to the page table. +/// +/// We do not currently have APIs to manually map MMIO pages, so we have +/// to rely on the direct mapping to perform MMIO operations. Therefore, +/// we set the maximum size to 127 TiB, which makes some surprisingly +/// high MMIO addresses usable (e.g., `0x7000_0000_7004` for VirtIO +/// devices in the TDX environment) and leaves the last 1 TiB for other +/// uses (e.g., the kernel code starting at [`kernel_loaded_offset()`]). +pub(crate) const LINEAR_MAPPING_MAX_SIZE: usize = 127 << 40; + +/// The address range of the direct mapping of physical memory. +/// +/// This range is constructed based on [`PHYS_MEM_BASE_VADDR`] and +/// [`PHYS_MEM_MAPPING_MAX_SIZE`]. +pub(crate) const LINEAR_MAPPING_VADDR_RANGE: Range = + LINEAR_MAPPING_BASE_VADDR..(LINEAR_MAPPING_BASE_VADDR + LINEAR_MAPPING_MAX_SIZE); + /// The kernel code is linear mapped to this address. /// /// FIXME: This offset should be randomly chosen by the loader or the /// boot compatibility layer. But we disabled it because the framework /// doesn't support relocatable kernel yet. -pub fn kernel_loaded_offset() -> usize { +pub const fn kernel_loaded_offset() -> usize { 0xffff_ffff_8000_0000 } - -pub fn vaddr_to_paddr(va: Vaddr) -> Option { - if (LINEAR_MAPPING_BASE_VADDR..=kernel_loaded_offset()).contains(&va) { - // can use offset to get the physical address - Some(va - LINEAR_MAPPING_BASE_VADDR) - } else { - let root_paddr = crate::arch::mm::current_page_table_paddr(); - // Safety: the root page table is valid since we read it from the register. - unsafe { page_walk::(root_paddr, va).map(|(pa, _)| pa) } - } -} +const_assert!(LINEAR_MAPPING_VADDR_RANGE.end < kernel_loaded_offset()); /// Convert physical address to virtual address using offset, only available inside aster-frame pub(crate) fn paddr_to_vaddr(pa: Paddr) -> usize { diff --git a/framework/aster-frame/src/vm/mod.rs b/framework/aster-frame/src/vm/mod.rs index ad57cc19f..5a4f9fe84 100644 --- a/framework/aster-frame/src/vm/mod.rs +++ b/framework/aster-frame/src/vm/mod.rs @@ -29,7 +29,6 @@ pub use self::{ dma::{Daddr, DmaCoherent, DmaDirection, DmaStream, DmaStreamSlice, HasDaddr}, frame::{VmFrame, VmFrameVec, VmFrameVecIter, VmReader, VmSegment, VmWriter}, io::VmIo, - kspace::vaddr_to_paddr, options::VmAllocOptions, page_prop::{CachePolicy, PageFlags, PageProperty}, space::{VmMapOptions, VmSpace}, @@ -76,47 +75,10 @@ pub(crate) trait PagingConstsTrait: Debug + 'static { /// for the rationale. pub const MAX_USERSPACE_VADDR: Vaddr = 0x0000_8000_0000_0000 - PAGE_SIZE; -/// The base address of the direct mapping of physical memory. -pub(crate) const PHYS_MEM_BASE_VADDR: Vaddr = 0xffff_8000_0000_0000; - -/// The maximum size of the direct mapping of physical memory. -/// -/// This size acts as a cap. If the actual memory size exceeds this value, -/// the remaining memory cannot be included in the direct mapping because -/// the maximum size of the direct mapping is limited by this value. On -/// the other hand, if the actual memory size is smaller, the direct -/// mapping can shrink to save memory consumption due to the page table. -/// -/// We do not currently have APIs to manually map MMIO pages, so we have -/// to rely on the direct mapping to perform MMIO operations. Therefore, -/// we set the maximum size to 127 TiB, which makes some surprisingly -/// high MMIO addresses usable (e.g., `0x7000_0000_7004` for VirtIO -/// devices in the TDX environment) and leaves the last 1 TiB for other -/// uses (e.g., the kernel code starting at [`kernel_loaded_offset()`]). -pub(crate) const PHYS_MEM_MAPPING_MAX_SIZE: usize = 127 << 40; - -/// The address range of the direct mapping of physical memory. -/// -/// This range is constructed based on [`PHYS_MEM_BASE_VADDR`] and -/// [`PHYS_MEM_MAPPING_MAX_SIZE`]. -pub(crate) const PHYS_MEM_VADDR_RANGE: Range = - PHYS_MEM_BASE_VADDR..(PHYS_MEM_BASE_VADDR + PHYS_MEM_MAPPING_MAX_SIZE); - -/// The kernel code is linear mapped to this address. -/// -/// FIXME: This offset should be randomly chosen by the loader or the -/// boot compatibility layer. But we disabled it because the framework -/// doesn't support relocatable kernel yet. -pub const fn kernel_loaded_offset() -> usize { - 0xffff_ffff_8000_0000 -} -const_assert!(PHYS_MEM_VADDR_RANGE.end < kernel_loaded_offset()); - -/// Start of the kernel address space. -/// This is the _lowest_ address of the x86-64's _high_ canonical addresses. -pub(crate) const KERNEL_BASE_VADDR: Vaddr = 0xffff_8000_0000_0000; -/// End of the kernel address space (non inclusive). -pub(crate) const KERNEL_END_VADDR: Vaddr = 0xffff_ffff_ffff_0000; +/// The kernel address space. +/// There are the high canonical addresses defined in most 48-bit width +/// architectures. +pub(crate) const KERNEL_VADDR_RANGE: Range = 0xffff_8000_0000_0000..0xffff_ffff_ffff_0000; /// Get physical address trait pub trait HasPaddr { diff --git a/framework/aster-frame/src/vm/page_table/mod.rs b/framework/aster-frame/src/vm/page_table/mod.rs index e1d7ee890..36ff01e16 100644 --- a/framework/aster-frame/src/vm/page_table/mod.rs +++ b/framework/aster-frame/src/vm/page_table/mod.rs @@ -58,7 +58,7 @@ impl PageTableMode for UserMode { pub struct KernelMode {} impl PageTableMode for KernelMode { - const VADDR_RANGE: Range = super::KERNEL_BASE_VADDR..super::KERNEL_END_VADDR; + const VADDR_RANGE: Range = super::KERNEL_VADDR_RANGE; } // Here are some const values that are determined by the paging constants.