1cf7f801eSMemoryShore use alloc::string::ToString; 240fe15e0SLoGin use core::{ 340fe15e0SLoGin fmt::{self, Debug, Error, Formatter}, 440fe15e0SLoGin marker::PhantomData, 540fe15e0SLoGin mem, 640fe15e0SLoGin ops::Add, 740fe15e0SLoGin sync::atomic::{compiler_fence, Ordering}, 840fe15e0SLoGin }; 9cf7f801eSMemoryShore use system_error::SystemError; 10cf7f801eSMemoryShore use unified_init::macros::unified_init; 1140fe15e0SLoGin 1256cc4dbeSJomo use alloc::sync::Arc; 1356cc4dbeSJomo use hashbrown::{HashMap, HashSet}; 142eab6dd7S曾俊 use log::{error, info}; 15cf7f801eSMemoryShore use lru::LruCache; 1656cc4dbeSJomo 1740fe15e0SLoGin use crate::{ 18cf7f801eSMemoryShore arch::{interrupt::ipi::send_ipi, mm::LockedFrameAllocator, MMArch}, 1940fe15e0SLoGin exception::ipi::{IpiKind, IpiTarget}, 20cf7f801eSMemoryShore filesystem::vfs::{file::PageCache, FilePrivateData}, 21cf7f801eSMemoryShore init::initcall::INITCALL_CORE, 226fc066acSJomo ipc::shm::ShmId, 23cf7f801eSMemoryShore libs::{ 24cf7f801eSMemoryShore rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, 25cf7f801eSMemoryShore spinlock::{SpinLock, SpinLockGuard}, 26cf7f801eSMemoryShore }, 27cf7f801eSMemoryShore process::{ProcessControlBlock, ProcessManager}, 28*2b7818e8SLoGin time::{sleep::nanosleep, PosixTimeSpec}, 2940fe15e0SLoGin }; 3040fe15e0SLoGin 3140fe15e0SLoGin use super::{ 32a17651b1SMemoryShore allocator::page_frame::{FrameAllocator, PageFrameCount}, 33a17651b1SMemoryShore syscall::ProtFlags, 34a17651b1SMemoryShore ucontext::LockedVMA, 3556cc4dbeSJomo MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, 3640fe15e0SLoGin }; 3740fe15e0SLoGin 3823ef2b33SLoGin pub const PAGE_4K_SHIFT: usize = 12; 3923ef2b33SLoGin #[allow(dead_code)] 4023ef2b33SLoGin pub const PAGE_2M_SHIFT: usize = 21; 4123ef2b33SLoGin pub const PAGE_1G_SHIFT: usize = 30; 4223ef2b33SLoGin 43370472f7SLoGin pub const PAGE_4K_SIZE: usize = 1 << PAGE_4K_SHIFT; 44370472f7SLoGin pub const PAGE_2M_SIZE: usize = 1 << PAGE_2M_SHIFT; 45370472f7SLoGin 4656cc4dbeSJomo /// 全局物理页信息管理器 4756cc4dbeSJomo pub static mut PAGE_MANAGER: Option<SpinLock<PageManager>> = None; 4856cc4dbeSJomo 4956cc4dbeSJomo /// 初始化PAGE_MANAGER 5056cc4dbeSJomo pub fn page_manager_init() { 512eab6dd7S曾俊 info!("page_manager_init"); 5256cc4dbeSJomo let page_manager = SpinLock::new(PageManager::new()); 5356cc4dbeSJomo 5456cc4dbeSJomo compiler_fence(Ordering::SeqCst); 5556cc4dbeSJomo unsafe { PAGE_MANAGER = Some(page_manager) }; 5656cc4dbeSJomo compiler_fence(Ordering::SeqCst); 5756cc4dbeSJomo 582eab6dd7S曾俊 info!("page_manager_init done"); 5956cc4dbeSJomo } 6056cc4dbeSJomo 616fc066acSJomo pub fn page_manager_lock_irqsave() -> SpinLockGuard<'static, PageManager> { 6256cc4dbeSJomo unsafe { PAGE_MANAGER.as_ref().unwrap().lock_irqsave() } 6356cc4dbeSJomo } 6456cc4dbeSJomo 6556cc4dbeSJomo // 物理页管理器 6656cc4dbeSJomo pub struct PageManager { 67cf7f801eSMemoryShore phys2page: HashMap<PhysAddr, Arc<Page>>, 6856cc4dbeSJomo } 6956cc4dbeSJomo 7056cc4dbeSJomo impl PageManager { 7156cc4dbeSJomo pub fn new() -> Self { 7256cc4dbeSJomo Self { 7356cc4dbeSJomo phys2page: HashMap::new(), 7456cc4dbeSJomo } 7556cc4dbeSJomo } 7656cc4dbeSJomo 776fc066acSJomo pub fn contains(&self, paddr: &PhysAddr) -> bool { 786fc066acSJomo self.phys2page.contains_key(paddr) 796fc066acSJomo } 806fc066acSJomo 81cf7f801eSMemoryShore pub fn get(&mut self, paddr: &PhysAddr) -> Option<Arc<Page>> { 82cf7f801eSMemoryShore page_reclaimer_lock_irqsave().get(paddr); 83cf7f801eSMemoryShore self.phys2page.get(paddr).cloned() 846fc066acSJomo } 856fc066acSJomo 86cf7f801eSMemoryShore pub fn get_unwrap(&mut self, paddr: &PhysAddr) -> Arc<Page> { 87cf7f801eSMemoryShore page_reclaimer_lock_irqsave().get(paddr); 88a17651b1SMemoryShore self.phys2page 89cf7f801eSMemoryShore .get(paddr) 90cf7f801eSMemoryShore .unwrap_or_else(|| panic!("Phys Page not found, {:?}", paddr)) 91cf7f801eSMemoryShore .clone() 9256cc4dbeSJomo } 9356cc4dbeSJomo 94cf7f801eSMemoryShore pub fn insert(&mut self, paddr: PhysAddr, page: &Arc<Page>) { 95cf7f801eSMemoryShore self.phys2page.insert(paddr, page.clone()); 9656cc4dbeSJomo } 9756cc4dbeSJomo 9856cc4dbeSJomo pub fn remove_page(&mut self, paddr: &PhysAddr) { 9956cc4dbeSJomo self.phys2page.remove(paddr); 10056cc4dbeSJomo } 10156cc4dbeSJomo } 10256cc4dbeSJomo 103cf7f801eSMemoryShore pub static mut PAGE_RECLAIMER: Option<SpinLock<PageReclaimer>> = None; 104cf7f801eSMemoryShore 105cf7f801eSMemoryShore pub fn page_reclaimer_init() { 106cf7f801eSMemoryShore info!("page_reclaimer_init"); 107cf7f801eSMemoryShore let page_reclaimer = SpinLock::new(PageReclaimer::new()); 108cf7f801eSMemoryShore 109cf7f801eSMemoryShore compiler_fence(Ordering::SeqCst); 110cf7f801eSMemoryShore unsafe { PAGE_RECLAIMER = Some(page_reclaimer) }; 111cf7f801eSMemoryShore compiler_fence(Ordering::SeqCst); 112cf7f801eSMemoryShore 113cf7f801eSMemoryShore info!("page_reclaimer_init done"); 114cf7f801eSMemoryShore } 115cf7f801eSMemoryShore 116cf7f801eSMemoryShore /// 页面回收线程 117cf7f801eSMemoryShore static mut PAGE_RECLAIMER_THREAD: Option<Arc<ProcessControlBlock>> = None; 118cf7f801eSMemoryShore 119cf7f801eSMemoryShore /// 页面回收线程初始化函数 120cf7f801eSMemoryShore #[unified_init(INITCALL_CORE)] 121cf7f801eSMemoryShore fn page_reclaimer_thread_init() -> Result<(), SystemError> { 122cf7f801eSMemoryShore let closure = crate::process::kthread::KernelThreadClosure::StaticEmptyClosure(( 123cf7f801eSMemoryShore &(page_reclaim_thread as fn() -> i32), 124cf7f801eSMemoryShore (), 125cf7f801eSMemoryShore )); 126cf7f801eSMemoryShore let pcb = crate::process::kthread::KernelThreadMechanism::create_and_run( 127cf7f801eSMemoryShore closure, 128cf7f801eSMemoryShore "page_reclaim".to_string(), 129cf7f801eSMemoryShore ) 130cf7f801eSMemoryShore .ok_or("") 131cf7f801eSMemoryShore .expect("create tty_refresh thread failed"); 132cf7f801eSMemoryShore unsafe { 133cf7f801eSMemoryShore PAGE_RECLAIMER_THREAD = Some(pcb); 134cf7f801eSMemoryShore } 135cf7f801eSMemoryShore Ok(()) 136cf7f801eSMemoryShore } 137cf7f801eSMemoryShore 138cf7f801eSMemoryShore /// 页面回收线程执行的函数 139cf7f801eSMemoryShore fn page_reclaim_thread() -> i32 { 140cf7f801eSMemoryShore loop { 141cf7f801eSMemoryShore let usage = unsafe { LockedFrameAllocator.usage() }; 142cf7f801eSMemoryShore // log::info!("usage{:?}", usage); 143cf7f801eSMemoryShore 144cf7f801eSMemoryShore // 保留4096个页面,总计16MB的空闲空间 145cf7f801eSMemoryShore if usage.free().data() < 4096 { 146cf7f801eSMemoryShore let page_to_free = 4096; 147cf7f801eSMemoryShore page_reclaimer_lock_irqsave().shrink_list(PageFrameCount::new(page_to_free)); 148cf7f801eSMemoryShore } else { 149cf7f801eSMemoryShore //TODO 暂时让页面回收线程负责脏页回写任务,后续需要分离 150cf7f801eSMemoryShore page_reclaimer_lock_irqsave().flush_dirty_pages(); 151cf7f801eSMemoryShore // 休眠5秒 152cf7f801eSMemoryShore // log::info!("sleep"); 153*2b7818e8SLoGin let _ = nanosleep(PosixTimeSpec::new(5, 0)); 154cf7f801eSMemoryShore } 155cf7f801eSMemoryShore } 156cf7f801eSMemoryShore } 157cf7f801eSMemoryShore 158cf7f801eSMemoryShore /// 获取页面回收器 159cf7f801eSMemoryShore pub fn page_reclaimer_lock_irqsave() -> SpinLockGuard<'static, PageReclaimer> { 160cf7f801eSMemoryShore unsafe { PAGE_RECLAIMER.as_ref().unwrap().lock_irqsave() } 161cf7f801eSMemoryShore } 162cf7f801eSMemoryShore 163cf7f801eSMemoryShore /// 页面回收器 164cf7f801eSMemoryShore pub struct PageReclaimer { 165cf7f801eSMemoryShore lru: LruCache<PhysAddr, Arc<Page>>, 166cf7f801eSMemoryShore } 167cf7f801eSMemoryShore 168cf7f801eSMemoryShore impl PageReclaimer { 169cf7f801eSMemoryShore pub fn new() -> Self { 170cf7f801eSMemoryShore Self { 171cf7f801eSMemoryShore lru: LruCache::unbounded(), 172cf7f801eSMemoryShore } 173cf7f801eSMemoryShore } 174cf7f801eSMemoryShore 175cf7f801eSMemoryShore pub fn get(&mut self, paddr: &PhysAddr) -> Option<Arc<Page>> { 176cf7f801eSMemoryShore self.lru.get(paddr).cloned() 177cf7f801eSMemoryShore } 178cf7f801eSMemoryShore 179cf7f801eSMemoryShore pub fn insert_page(&mut self, paddr: PhysAddr, page: &Arc<Page>) { 180cf7f801eSMemoryShore self.lru.put(paddr, page.clone()); 181cf7f801eSMemoryShore } 182cf7f801eSMemoryShore 183cf7f801eSMemoryShore /// lru链表缩减 184cf7f801eSMemoryShore /// ## 参数 185cf7f801eSMemoryShore /// 186cf7f801eSMemoryShore /// - `count`: 需要缩减的页面数量 187cf7f801eSMemoryShore pub fn shrink_list(&mut self, count: PageFrameCount) { 188cf7f801eSMemoryShore for _ in 0..count.data() { 189cf7f801eSMemoryShore let (paddr, page) = self.lru.pop_lru().expect("pagecache is empty"); 190cf7f801eSMemoryShore let page_cache = page.read_irqsave().page_cache().unwrap(); 191cf7f801eSMemoryShore for vma in page.read_irqsave().anon_vma() { 192cf7f801eSMemoryShore let address_space = vma.lock_irqsave().address_space().unwrap(); 193cf7f801eSMemoryShore let address_space = address_space.upgrade().unwrap(); 194cf7f801eSMemoryShore let mut guard = address_space.write(); 195cf7f801eSMemoryShore let mapper = &mut guard.user_mapper.utable; 196cf7f801eSMemoryShore let virt = vma.lock_irqsave().page_address(&page).unwrap(); 197cf7f801eSMemoryShore unsafe { 198cf7f801eSMemoryShore mapper.unmap(virt, false).unwrap().flush(); 199cf7f801eSMemoryShore } 200cf7f801eSMemoryShore } 201cf7f801eSMemoryShore page_cache.remove_page(page.read_irqsave().index().unwrap()); 202cf7f801eSMemoryShore page_manager_lock_irqsave().remove_page(&paddr); 203cf7f801eSMemoryShore if page.read_irqsave().flags.contains(PageFlags::PG_DIRTY) { 204cf7f801eSMemoryShore Self::page_writeback(&page, true); 205cf7f801eSMemoryShore } 206cf7f801eSMemoryShore } 207cf7f801eSMemoryShore } 208cf7f801eSMemoryShore 209cf7f801eSMemoryShore /// 唤醒页面回收线程 210cf7f801eSMemoryShore pub fn wakeup_claim_thread() { 211cf7f801eSMemoryShore // log::info!("wakeup_claim_thread"); 212cf7f801eSMemoryShore let _ = ProcessManager::wakeup(unsafe { PAGE_RECLAIMER_THREAD.as_ref().unwrap() }); 213cf7f801eSMemoryShore } 214cf7f801eSMemoryShore 215cf7f801eSMemoryShore /// 脏页回写函数 216cf7f801eSMemoryShore /// ## 参数 217cf7f801eSMemoryShore /// 218cf7f801eSMemoryShore /// - `page`: 需要回写的脏页 219cf7f801eSMemoryShore /// - `unmap`: 是否取消映射 220cf7f801eSMemoryShore /// 221cf7f801eSMemoryShore /// ## 返回值 222cf7f801eSMemoryShore /// - VmFaultReason: 页面错误处理信息标志 223cf7f801eSMemoryShore pub fn page_writeback(page: &Arc<Page>, unmap: bool) { 224cf7f801eSMemoryShore if !unmap { 225cf7f801eSMemoryShore page.write_irqsave().remove_flags(PageFlags::PG_DIRTY); 226cf7f801eSMemoryShore } 227cf7f801eSMemoryShore 228cf7f801eSMemoryShore for vma in page.read_irqsave().anon_vma() { 229cf7f801eSMemoryShore let address_space = vma.lock_irqsave().address_space().unwrap(); 230cf7f801eSMemoryShore let address_space = address_space.upgrade().unwrap(); 231cf7f801eSMemoryShore let mut guard = address_space.write(); 232cf7f801eSMemoryShore let mapper = &mut guard.user_mapper.utable; 233cf7f801eSMemoryShore let virt = vma.lock_irqsave().page_address(page).unwrap(); 234cf7f801eSMemoryShore if unmap { 235cf7f801eSMemoryShore unsafe { 236cf7f801eSMemoryShore mapper.unmap(virt, false).unwrap().flush(); 237cf7f801eSMemoryShore } 238cf7f801eSMemoryShore } else { 239cf7f801eSMemoryShore unsafe { 240cf7f801eSMemoryShore // 保护位设为只读 241cf7f801eSMemoryShore mapper.remap( 242cf7f801eSMemoryShore virt, 243cf7f801eSMemoryShore mapper.get_entry(virt, 0).unwrap().flags().set_write(false), 244cf7f801eSMemoryShore ) 245cf7f801eSMemoryShore }; 246cf7f801eSMemoryShore } 247cf7f801eSMemoryShore } 248cf7f801eSMemoryShore let inode = page 249cf7f801eSMemoryShore .read_irqsave() 250cf7f801eSMemoryShore .page_cache 251cf7f801eSMemoryShore .clone() 252cf7f801eSMemoryShore .unwrap() 253cf7f801eSMemoryShore .inode() 254cf7f801eSMemoryShore .clone() 255cf7f801eSMemoryShore .unwrap() 256cf7f801eSMemoryShore .upgrade() 257cf7f801eSMemoryShore .unwrap(); 258cf7f801eSMemoryShore inode 259cf7f801eSMemoryShore .write_at( 260cf7f801eSMemoryShore page.read_irqsave().index().unwrap(), 261cf7f801eSMemoryShore MMArch::PAGE_SIZE, 262cf7f801eSMemoryShore unsafe { 263cf7f801eSMemoryShore core::slice::from_raw_parts( 264cf7f801eSMemoryShore MMArch::phys_2_virt(page.read_irqsave().phys_addr) 265cf7f801eSMemoryShore .unwrap() 266cf7f801eSMemoryShore .data() as *mut u8, 267cf7f801eSMemoryShore MMArch::PAGE_SIZE, 268cf7f801eSMemoryShore ) 269cf7f801eSMemoryShore }, 270cf7f801eSMemoryShore SpinLock::new(FilePrivateData::Unused).lock(), 271cf7f801eSMemoryShore ) 272cf7f801eSMemoryShore .unwrap(); 273cf7f801eSMemoryShore } 274cf7f801eSMemoryShore 275cf7f801eSMemoryShore /// lru脏页刷新 276cf7f801eSMemoryShore pub fn flush_dirty_pages(&self) { 277cf7f801eSMemoryShore // log::info!("flush_dirty_pages"); 278cf7f801eSMemoryShore let iter = self.lru.iter(); 279cf7f801eSMemoryShore for (_, page) in iter { 280cf7f801eSMemoryShore if page.read_irqsave().flags().contains(PageFlags::PG_DIRTY) { 281cf7f801eSMemoryShore Self::page_writeback(page, false); 282cf7f801eSMemoryShore } 283cf7f801eSMemoryShore } 284cf7f801eSMemoryShore } 285cf7f801eSMemoryShore } 286cf7f801eSMemoryShore 287cf7f801eSMemoryShore bitflags! { 288cf7f801eSMemoryShore pub struct PageFlags: u64 { 289cf7f801eSMemoryShore const PG_LOCKED = 1 << 0; 290cf7f801eSMemoryShore const PG_WRITEBACK = 1 << 1; 291cf7f801eSMemoryShore const PG_REFERENCED = 1 << 2; 292cf7f801eSMemoryShore const PG_UPTODATE = 1 << 3; 293cf7f801eSMemoryShore const PG_DIRTY = 1 << 4; 294cf7f801eSMemoryShore const PG_LRU = 1 << 5; 295cf7f801eSMemoryShore const PG_HEAD = 1 << 6; 296cf7f801eSMemoryShore const PG_WAITERS = 1 << 7; 297cf7f801eSMemoryShore const PG_ACTIVE = 1 << 8; 298cf7f801eSMemoryShore const PG_WORKINGSET = 1 << 9; 299cf7f801eSMemoryShore const PG_ERROR = 1 << 10; 300cf7f801eSMemoryShore const PG_SLAB = 1 << 11; 301cf7f801eSMemoryShore const PG_RESERVED = 1 << 14; 302cf7f801eSMemoryShore const PG_PRIVATE = 1 << 15; 303cf7f801eSMemoryShore const PG_RECLAIM = 1 << 18; 304cf7f801eSMemoryShore const PG_SWAPBACKED = 1 << 19; 305cf7f801eSMemoryShore } 306cf7f801eSMemoryShore } 307cf7f801eSMemoryShore 308cf7f801eSMemoryShore #[derive(Debug)] 30956cc4dbeSJomo pub struct Page { 310cf7f801eSMemoryShore inner: RwLock<InnerPage>, 311cf7f801eSMemoryShore } 312cf7f801eSMemoryShore 313cf7f801eSMemoryShore impl Page { 314cf7f801eSMemoryShore pub fn new(shared: bool, phys_addr: PhysAddr) -> Self { 315cf7f801eSMemoryShore let inner = InnerPage::new(shared, phys_addr); 316cf7f801eSMemoryShore Self { 317cf7f801eSMemoryShore inner: RwLock::new(inner), 318cf7f801eSMemoryShore } 319cf7f801eSMemoryShore } 320cf7f801eSMemoryShore 321cf7f801eSMemoryShore pub fn read_irqsave(&self) -> RwLockReadGuard<InnerPage> { 322cf7f801eSMemoryShore self.inner.read_irqsave() 323cf7f801eSMemoryShore } 324cf7f801eSMemoryShore 325cf7f801eSMemoryShore pub fn write_irqsave(&self) -> RwLockWriteGuard<InnerPage> { 326cf7f801eSMemoryShore self.inner.write_irqsave() 327cf7f801eSMemoryShore } 328cf7f801eSMemoryShore } 329cf7f801eSMemoryShore 330cf7f801eSMemoryShore #[derive(Debug)] 331cf7f801eSMemoryShore /// 物理页面信息 332cf7f801eSMemoryShore pub struct InnerPage { 33356cc4dbeSJomo /// 映射计数 33456cc4dbeSJomo map_count: usize, 33556cc4dbeSJomo /// 是否为共享页 33656cc4dbeSJomo shared: bool, 3376fc066acSJomo /// 映射计数为0时,是否可回收 3386fc066acSJomo free_when_zero: bool, 3396fc066acSJomo /// 共享页id(如果是共享页) 3406fc066acSJomo shm_id: Option<ShmId>, 34156cc4dbeSJomo /// 映射到当前page的VMA 34256cc4dbeSJomo anon_vma: HashSet<Arc<LockedVMA>>, 343cf7f801eSMemoryShore /// 标志 344cf7f801eSMemoryShore flags: PageFlags, 345cf7f801eSMemoryShore /// 页所在的物理页帧号 346cf7f801eSMemoryShore phys_addr: PhysAddr, 347cf7f801eSMemoryShore /// 在pagecache中的偏移 348cf7f801eSMemoryShore index: Option<usize>, 349cf7f801eSMemoryShore page_cache: Option<Arc<PageCache>>, 35056cc4dbeSJomo } 35156cc4dbeSJomo 352cf7f801eSMemoryShore impl InnerPage { 353cf7f801eSMemoryShore pub fn new(shared: bool, phys_addr: PhysAddr) -> Self { 3546fc066acSJomo let dealloc_when_zero = !shared; 35556cc4dbeSJomo Self { 35656cc4dbeSJomo map_count: 0, 35756cc4dbeSJomo shared, 3586fc066acSJomo free_when_zero: dealloc_when_zero, 3596fc066acSJomo shm_id: None, 36056cc4dbeSJomo anon_vma: HashSet::new(), 361cf7f801eSMemoryShore flags: PageFlags::empty(), 362cf7f801eSMemoryShore phys_addr, 363cf7f801eSMemoryShore index: None, 364cf7f801eSMemoryShore page_cache: None, 36556cc4dbeSJomo } 36656cc4dbeSJomo } 36756cc4dbeSJomo 36856cc4dbeSJomo /// 将vma加入anon_vma 36956cc4dbeSJomo pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) { 37056cc4dbeSJomo self.anon_vma.insert(vma); 37156cc4dbeSJomo self.map_count += 1; 37256cc4dbeSJomo } 37356cc4dbeSJomo 37456cc4dbeSJomo /// 将vma从anon_vma中删去 37556cc4dbeSJomo pub fn remove_vma(&mut self, vma: &LockedVMA) { 37656cc4dbeSJomo self.anon_vma.remove(vma); 37756cc4dbeSJomo self.map_count -= 1; 37856cc4dbeSJomo } 37956cc4dbeSJomo 38056cc4dbeSJomo /// 判断当前物理页是否能被回 38156cc4dbeSJomo pub fn can_deallocate(&self) -> bool { 3826fc066acSJomo self.map_count == 0 && self.free_when_zero 3836fc066acSJomo } 3846fc066acSJomo 3856fc066acSJomo pub fn shared(&self) -> bool { 3866fc066acSJomo self.shared 3876fc066acSJomo } 3886fc066acSJomo 3896fc066acSJomo pub fn shm_id(&self) -> Option<ShmId> { 3906fc066acSJomo self.shm_id 3916fc066acSJomo } 3926fc066acSJomo 393cf7f801eSMemoryShore pub fn index(&self) -> Option<usize> { 394cf7f801eSMemoryShore self.index 395cf7f801eSMemoryShore } 396cf7f801eSMemoryShore 397cf7f801eSMemoryShore pub fn page_cache(&self) -> Option<Arc<PageCache>> { 398cf7f801eSMemoryShore self.page_cache.clone() 399cf7f801eSMemoryShore } 400cf7f801eSMemoryShore 401cf7f801eSMemoryShore pub fn set_page_cache(&mut self, page_cache: Option<Arc<PageCache>>) { 402cf7f801eSMemoryShore self.page_cache = page_cache; 403cf7f801eSMemoryShore } 404cf7f801eSMemoryShore 405cf7f801eSMemoryShore pub fn set_index(&mut self, index: Option<usize>) { 406cf7f801eSMemoryShore self.index = index; 407cf7f801eSMemoryShore } 408cf7f801eSMemoryShore 409cf7f801eSMemoryShore pub fn set_page_cache_index( 410cf7f801eSMemoryShore &mut self, 411cf7f801eSMemoryShore page_cache: Option<Arc<PageCache>>, 412cf7f801eSMemoryShore index: Option<usize>, 413cf7f801eSMemoryShore ) { 414cf7f801eSMemoryShore self.page_cache = page_cache; 415cf7f801eSMemoryShore self.index = index; 416cf7f801eSMemoryShore } 417cf7f801eSMemoryShore 4186fc066acSJomo pub fn set_shm_id(&mut self, shm_id: ShmId) { 4196fc066acSJomo self.shm_id = Some(shm_id); 4206fc066acSJomo } 4216fc066acSJomo 4226fc066acSJomo pub fn set_dealloc_when_zero(&mut self, dealloc_when_zero: bool) { 4236fc066acSJomo self.free_when_zero = dealloc_when_zero; 4246fc066acSJomo } 4256fc066acSJomo 426a17651b1SMemoryShore #[inline(always)] 4276fc066acSJomo pub fn anon_vma(&self) -> &HashSet<Arc<LockedVMA>> { 4286fc066acSJomo &self.anon_vma 42956cc4dbeSJomo } 430a17651b1SMemoryShore 431a17651b1SMemoryShore #[inline(always)] 432a17651b1SMemoryShore pub fn map_count(&self) -> usize { 433a17651b1SMemoryShore self.map_count 434a17651b1SMemoryShore } 435cf7f801eSMemoryShore 436cf7f801eSMemoryShore #[inline(always)] 437cf7f801eSMemoryShore pub fn flags(&self) -> &PageFlags { 438cf7f801eSMemoryShore &self.flags 439cf7f801eSMemoryShore } 440cf7f801eSMemoryShore 441cf7f801eSMemoryShore #[inline(always)] 442cf7f801eSMemoryShore pub fn set_flags(&mut self, flags: PageFlags) { 443cf7f801eSMemoryShore self.flags = flags 444cf7f801eSMemoryShore } 445cf7f801eSMemoryShore 446cf7f801eSMemoryShore #[inline(always)] 447cf7f801eSMemoryShore pub fn add_flags(&mut self, flags: PageFlags) { 448cf7f801eSMemoryShore self.flags = self.flags.union(flags); 449cf7f801eSMemoryShore } 450cf7f801eSMemoryShore 451cf7f801eSMemoryShore #[inline(always)] 452cf7f801eSMemoryShore pub fn remove_flags(&mut self, flags: PageFlags) { 453cf7f801eSMemoryShore self.flags = self.flags.difference(flags); 454cf7f801eSMemoryShore } 455cf7f801eSMemoryShore 456cf7f801eSMemoryShore #[inline(always)] 457cf7f801eSMemoryShore pub fn phys_address(&self) -> PhysAddr { 458cf7f801eSMemoryShore self.phys_addr 459cf7f801eSMemoryShore } 46056cc4dbeSJomo } 46156cc4dbeSJomo 46240fe15e0SLoGin #[derive(Debug)] 46340fe15e0SLoGin pub struct PageTable<Arch> { 46440fe15e0SLoGin /// 当前页表表示的虚拟地址空间的起始地址 46540fe15e0SLoGin base: VirtAddr, 46640fe15e0SLoGin /// 当前页表所在的物理地址 46740fe15e0SLoGin phys: PhysAddr, 46840fe15e0SLoGin /// 当前页表的层级(请注意,最顶级页表的level为[Arch::PAGE_LEVELS - 1]) 46940fe15e0SLoGin level: usize, 47040fe15e0SLoGin phantom: PhantomData<Arch>, 47140fe15e0SLoGin } 47240fe15e0SLoGin 47340fe15e0SLoGin #[allow(dead_code)] 47440fe15e0SLoGin impl<Arch: MemoryManagementArch> PageTable<Arch> { 47540fe15e0SLoGin pub unsafe fn new(base: VirtAddr, phys: PhysAddr, level: usize) -> Self { 47640fe15e0SLoGin Self { 47740fe15e0SLoGin base, 47840fe15e0SLoGin phys, 47940fe15e0SLoGin level, 48040fe15e0SLoGin phantom: PhantomData, 48140fe15e0SLoGin } 48240fe15e0SLoGin } 48340fe15e0SLoGin 48440fe15e0SLoGin /// 获取顶级页表 48540fe15e0SLoGin /// 48640fe15e0SLoGin /// ## 参数 48740fe15e0SLoGin /// 48840fe15e0SLoGin /// - table_kind 页表类型 48940fe15e0SLoGin /// 49040fe15e0SLoGin /// ## 返回值 49140fe15e0SLoGin /// 49240fe15e0SLoGin /// 返回顶级页表 49340fe15e0SLoGin pub unsafe fn top_level_table(table_kind: PageTableKind) -> Self { 49440fe15e0SLoGin return Self::new( 49540fe15e0SLoGin VirtAddr::new(0), 49640fe15e0SLoGin Arch::table(table_kind), 49740fe15e0SLoGin Arch::PAGE_LEVELS - 1, 49840fe15e0SLoGin ); 49940fe15e0SLoGin } 50040fe15e0SLoGin 50140fe15e0SLoGin /// 获取当前页表的物理地址 50240fe15e0SLoGin #[inline(always)] 50340fe15e0SLoGin pub fn phys(&self) -> PhysAddr { 50440fe15e0SLoGin self.phys 50540fe15e0SLoGin } 50640fe15e0SLoGin 50740fe15e0SLoGin /// 当前页表表示的虚拟地址空间的起始地址 50840fe15e0SLoGin #[inline(always)] 50940fe15e0SLoGin pub fn base(&self) -> VirtAddr { 51040fe15e0SLoGin self.base 51140fe15e0SLoGin } 51240fe15e0SLoGin 51340fe15e0SLoGin /// 获取当前页表的层级 51440fe15e0SLoGin #[inline(always)] 51540fe15e0SLoGin pub fn level(&self) -> usize { 51640fe15e0SLoGin self.level 51740fe15e0SLoGin } 51840fe15e0SLoGin 51940fe15e0SLoGin /// 获取当前页表自身所在的虚拟地址 52040fe15e0SLoGin #[inline(always)] 52140fe15e0SLoGin pub unsafe fn virt(&self) -> VirtAddr { 52240fe15e0SLoGin return Arch::phys_2_virt(self.phys).unwrap(); 52340fe15e0SLoGin } 52440fe15e0SLoGin 52540fe15e0SLoGin /// 获取第i个页表项所表示的虚拟内存空间的起始地址 52640fe15e0SLoGin pub fn entry_base(&self, i: usize) -> Option<VirtAddr> { 52740fe15e0SLoGin if i < Arch::PAGE_ENTRY_NUM { 52840fe15e0SLoGin let shift = self.level * Arch::PAGE_ENTRY_SHIFT + Arch::PAGE_SHIFT; 52940fe15e0SLoGin return Some(self.base.add(i << shift)); 53040fe15e0SLoGin } else { 53140fe15e0SLoGin return None; 53240fe15e0SLoGin } 53340fe15e0SLoGin } 53440fe15e0SLoGin 53540fe15e0SLoGin /// 获取当前页表的第i个页表项所在的虚拟地址(注意与entry_base进行区分) 53640fe15e0SLoGin pub unsafe fn entry_virt(&self, i: usize) -> Option<VirtAddr> { 53740fe15e0SLoGin if i < Arch::PAGE_ENTRY_NUM { 53840fe15e0SLoGin return Some(self.virt().add(i * Arch::PAGE_ENTRY_SIZE)); 53940fe15e0SLoGin } else { 54040fe15e0SLoGin return None; 54140fe15e0SLoGin } 54240fe15e0SLoGin } 54340fe15e0SLoGin 54440fe15e0SLoGin /// 获取当前页表的第i个页表项 54540fe15e0SLoGin pub unsafe fn entry(&self, i: usize) -> Option<PageEntry<Arch>> { 54640fe15e0SLoGin let entry_virt = self.entry_virt(i)?; 5477a29d4fcSLoGin return Some(PageEntry::from_usize(Arch::read::<usize>(entry_virt))); 54840fe15e0SLoGin } 54940fe15e0SLoGin 55040fe15e0SLoGin /// 设置当前页表的第i个页表项 55140fe15e0SLoGin pub unsafe fn set_entry(&self, i: usize, entry: PageEntry<Arch>) -> Option<()> { 55240fe15e0SLoGin let entry_virt = self.entry_virt(i)?; 55340fe15e0SLoGin Arch::write::<usize>(entry_virt, entry.data()); 55440fe15e0SLoGin return Some(()); 55540fe15e0SLoGin } 55640fe15e0SLoGin 55740fe15e0SLoGin /// 判断当前页表的第i个页表项是否已经填写了值 55840fe15e0SLoGin /// 55940fe15e0SLoGin /// ## 参数 56040fe15e0SLoGin /// - Some(true) 如果已经填写了值 56140fe15e0SLoGin /// - Some(false) 如果未填写值 56240fe15e0SLoGin /// - None 如果i超出了页表项的范围 56340fe15e0SLoGin pub fn entry_mapped(&self, i: usize) -> Option<bool> { 56440fe15e0SLoGin let etv = unsafe { self.entry_virt(i) }?; 56540fe15e0SLoGin if unsafe { Arch::read::<usize>(etv) } != 0 { 56640fe15e0SLoGin return Some(true); 56740fe15e0SLoGin } else { 56840fe15e0SLoGin return Some(false); 56940fe15e0SLoGin } 57040fe15e0SLoGin } 57140fe15e0SLoGin 57240fe15e0SLoGin /// 根据虚拟地址,获取对应的页表项在页表中的下标 57340fe15e0SLoGin /// 57440fe15e0SLoGin /// ## 参数 57540fe15e0SLoGin /// 57640fe15e0SLoGin /// - addr: 虚拟地址 57740fe15e0SLoGin /// 57840fe15e0SLoGin /// ## 返回值 57940fe15e0SLoGin /// 58040fe15e0SLoGin /// 页表项在页表中的下标。如果addr不在当前页表所表示的虚拟地址空间中,则返回None 581a17651b1SMemoryShore pub fn index_of(&self, addr: VirtAddr) -> Option<usize> { 58240fe15e0SLoGin let addr = VirtAddr::new(addr.data() & Arch::PAGE_ADDRESS_MASK); 58340fe15e0SLoGin let shift = self.level * Arch::PAGE_ENTRY_SHIFT + Arch::PAGE_SHIFT; 58440fe15e0SLoGin 58540fe15e0SLoGin let mask = (MMArch::PAGE_ENTRY_NUM << shift) - 1; 58640fe15e0SLoGin if addr < self.base || addr >= self.base.add(mask) { 58740fe15e0SLoGin return None; 58840fe15e0SLoGin } else { 58940fe15e0SLoGin return Some((addr.data() >> shift) & MMArch::PAGE_ENTRY_MASK); 59040fe15e0SLoGin } 59140fe15e0SLoGin } 59240fe15e0SLoGin 59340fe15e0SLoGin /// 获取第i个页表项指向的下一级页表 59440fe15e0SLoGin pub unsafe fn next_level_table(&self, index: usize) -> Option<Self> { 59540fe15e0SLoGin if self.level == 0 { 59640fe15e0SLoGin return None; 59740fe15e0SLoGin } 59840fe15e0SLoGin 59940fe15e0SLoGin // 返回下一级页表 60040fe15e0SLoGin return Some(PageTable::new( 60140fe15e0SLoGin self.entry_base(index)?, 60240fe15e0SLoGin self.entry(index)?.address().ok()?, 60340fe15e0SLoGin self.level - 1, 60440fe15e0SLoGin )); 60540fe15e0SLoGin } 606a17651b1SMemoryShore 607a17651b1SMemoryShore /// 拷贝页表 608a17651b1SMemoryShore /// ## 参数 609a17651b1SMemoryShore /// 610a17651b1SMemoryShore /// - `allocator`: 物理页框分配器 611a17651b1SMemoryShore /// - `copy_on_write`: 是否写时复制 612a17651b1SMemoryShore pub unsafe fn clone( 613a17651b1SMemoryShore &self, 614a17651b1SMemoryShore allocator: &mut impl FrameAllocator, 615a17651b1SMemoryShore copy_on_write: bool, 616a17651b1SMemoryShore ) -> Option<PageTable<Arch>> { 617a17651b1SMemoryShore // 分配新页面作为新的页表 618a17651b1SMemoryShore let phys = allocator.allocate_one()?; 619a17651b1SMemoryShore let frame = MMArch::phys_2_virt(phys).unwrap(); 620a17651b1SMemoryShore MMArch::write_bytes(frame, 0, MMArch::PAGE_SIZE); 621a17651b1SMemoryShore let new_table = PageTable::new(self.base, phys, self.level); 622a17651b1SMemoryShore if self.level == 0 { 623a17651b1SMemoryShore for i in 0..Arch::PAGE_ENTRY_NUM { 624a17651b1SMemoryShore if let Some(mut entry) = self.entry(i) { 625a17651b1SMemoryShore if entry.present() { 626a17651b1SMemoryShore if copy_on_write { 627a17651b1SMemoryShore let mut new_flags = entry.flags().set_write(false); 628a17651b1SMemoryShore entry.set_flags(new_flags); 629a17651b1SMemoryShore self.set_entry(i, entry); 630a17651b1SMemoryShore new_flags = new_flags.set_dirty(false); 631a17651b1SMemoryShore entry.set_flags(new_flags); 632a17651b1SMemoryShore new_table.set_entry(i, entry); 633a17651b1SMemoryShore } else { 634a17651b1SMemoryShore let phys = allocator.allocate_one()?; 635cf7f801eSMemoryShore let mut page_manager_guard = page_manager_lock_irqsave(); 636cf7f801eSMemoryShore let old_phys = entry.address().unwrap(); 637cf7f801eSMemoryShore let old_page = page_manager_guard.get_unwrap(&old_phys); 638cf7f801eSMemoryShore let new_page = 639cf7f801eSMemoryShore Arc::new(Page::new(old_page.read_irqsave().shared(), phys)); 640cf7f801eSMemoryShore if let Some(ref page_cache) = old_page.read_irqsave().page_cache() { 641cf7f801eSMemoryShore new_page.write_irqsave().set_page_cache_index( 642cf7f801eSMemoryShore Some(page_cache.clone()), 643cf7f801eSMemoryShore old_page.read_irqsave().index(), 644cf7f801eSMemoryShore ); 645cf7f801eSMemoryShore } 646cf7f801eSMemoryShore 647cf7f801eSMemoryShore page_manager_guard.insert(phys, &new_page); 648a17651b1SMemoryShore let old_phys = entry.address().unwrap(); 649a17651b1SMemoryShore let frame = MMArch::phys_2_virt(phys).unwrap().data() as *mut u8; 650a17651b1SMemoryShore frame.copy_from_nonoverlapping( 651a17651b1SMemoryShore MMArch::phys_2_virt(old_phys).unwrap().data() as *mut u8, 652a17651b1SMemoryShore MMArch::PAGE_SIZE, 653a17651b1SMemoryShore ); 654a17651b1SMemoryShore new_table.set_entry(i, PageEntry::new(phys, entry.flags())); 655a17651b1SMemoryShore } 656a17651b1SMemoryShore } 657a17651b1SMemoryShore } 658a17651b1SMemoryShore } 659a17651b1SMemoryShore } else { 660a17651b1SMemoryShore // 非一级页表拷贝时,对每个页表项对应的页表都进行拷贝 661a17651b1SMemoryShore for i in 0..MMArch::PAGE_ENTRY_NUM { 662a17651b1SMemoryShore if let Some(next_table) = self.next_level_table(i) { 663a17651b1SMemoryShore let table = next_table.clone(allocator, copy_on_write)?; 664a17651b1SMemoryShore let old_entry = self.entry(i).unwrap(); 665a17651b1SMemoryShore let entry = PageEntry::new(table.phys(), old_entry.flags()); 666a17651b1SMemoryShore new_table.set_entry(i, entry); 667a17651b1SMemoryShore } 668a17651b1SMemoryShore } 669a17651b1SMemoryShore } 670a17651b1SMemoryShore Some(new_table) 671a17651b1SMemoryShore } 67240fe15e0SLoGin } 67340fe15e0SLoGin 67440fe15e0SLoGin /// 页表项 67540fe15e0SLoGin #[derive(Copy, Clone)] 67640fe15e0SLoGin pub struct PageEntry<Arch> { 67740fe15e0SLoGin data: usize, 67840fe15e0SLoGin phantom: PhantomData<Arch>, 67940fe15e0SLoGin } 68040fe15e0SLoGin 68140fe15e0SLoGin impl<Arch> Debug for PageEntry<Arch> { 68240fe15e0SLoGin fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { 68340fe15e0SLoGin f.write_fmt(format_args!("PageEntry({:#x})", self.data)) 68440fe15e0SLoGin } 68540fe15e0SLoGin } 68640fe15e0SLoGin 68740fe15e0SLoGin impl<Arch: MemoryManagementArch> PageEntry<Arch> { 68840fe15e0SLoGin #[inline(always)] 689cf7f801eSMemoryShore pub fn new(paddr: PhysAddr, flags: EntryFlags<Arch>) -> Self { 6907a29d4fcSLoGin Self { 6917a29d4fcSLoGin data: MMArch::make_entry(paddr, flags.data()), 6927a29d4fcSLoGin phantom: PhantomData, 6937a29d4fcSLoGin } 6947a29d4fcSLoGin } 6957a29d4fcSLoGin #[inline(always)] 6967a29d4fcSLoGin pub fn from_usize(data: usize) -> Self { 69740fe15e0SLoGin Self { 69840fe15e0SLoGin data, 69940fe15e0SLoGin phantom: PhantomData, 70040fe15e0SLoGin } 70140fe15e0SLoGin } 70240fe15e0SLoGin 70340fe15e0SLoGin #[inline(always)] 70440fe15e0SLoGin pub fn data(&self) -> usize { 70540fe15e0SLoGin self.data 70640fe15e0SLoGin } 70740fe15e0SLoGin 70840fe15e0SLoGin /// 获取当前页表项指向的物理地址 70940fe15e0SLoGin /// 71040fe15e0SLoGin /// ## 返回值 71140fe15e0SLoGin /// 71240fe15e0SLoGin /// - Ok(PhysAddr) 如果当前页面存在于物理内存中, 返回物理地址 71340fe15e0SLoGin /// - Err(PhysAddr) 如果当前页表项不存在, 返回物理地址 71440fe15e0SLoGin #[inline(always)] 71540fe15e0SLoGin pub fn address(&self) -> Result<PhysAddr, PhysAddr> { 7167a29d4fcSLoGin let paddr: PhysAddr = { 7177a29d4fcSLoGin #[cfg(target_arch = "x86_64")] 7187a29d4fcSLoGin { 7197a29d4fcSLoGin PhysAddr::new(self.data & Arch::PAGE_ADDRESS_MASK) 7207a29d4fcSLoGin } 7217a29d4fcSLoGin 7227a29d4fcSLoGin #[cfg(target_arch = "riscv64")] 7237a29d4fcSLoGin { 724453452ccSLoGin let ppn = ((self.data & (!((1 << 10) - 1))) >> 10) & ((1 << 54) - 1); 7257a29d4fcSLoGin super::allocator::page_frame::PhysPageFrame::from_ppn(ppn).phys_address() 7267a29d4fcSLoGin } 7277a29d4fcSLoGin }; 72840fe15e0SLoGin 72940fe15e0SLoGin if self.present() { 73040fe15e0SLoGin Ok(paddr) 73140fe15e0SLoGin } else { 73240fe15e0SLoGin Err(paddr) 73340fe15e0SLoGin } 73440fe15e0SLoGin } 73540fe15e0SLoGin 73640fe15e0SLoGin #[inline(always)] 737cf7f801eSMemoryShore pub fn flags(&self) -> EntryFlags<Arch> { 738cf7f801eSMemoryShore unsafe { EntryFlags::from_data(self.data & Arch::ENTRY_FLAGS_MASK) } 73940fe15e0SLoGin } 74040fe15e0SLoGin 74140fe15e0SLoGin #[inline(always)] 742cf7f801eSMemoryShore pub fn set_flags(&mut self, flags: EntryFlags<Arch>) { 74340fe15e0SLoGin self.data = (self.data & !Arch::ENTRY_FLAGS_MASK) | flags.data(); 74440fe15e0SLoGin } 74540fe15e0SLoGin 74640fe15e0SLoGin #[inline(always)] 74740fe15e0SLoGin pub fn present(&self) -> bool { 74840fe15e0SLoGin return self.data & Arch::ENTRY_FLAG_PRESENT != 0; 74940fe15e0SLoGin } 750a17651b1SMemoryShore 751a17651b1SMemoryShore #[inline(always)] 752a17651b1SMemoryShore pub fn empty(&self) -> bool { 753a17651b1SMemoryShore self.data & !(Arch::ENTRY_FLAG_DIRTY & Arch::ENTRY_FLAG_ACCESSED) == 0 754a17651b1SMemoryShore } 755a17651b1SMemoryShore 756a17651b1SMemoryShore #[inline(always)] 757a17651b1SMemoryShore pub fn protnone(&self) -> bool { 758a17651b1SMemoryShore return self.data & (Arch::ENTRY_FLAG_PRESENT | Arch::ENTRY_FLAG_GLOBAL) 759a17651b1SMemoryShore == Arch::ENTRY_FLAG_GLOBAL; 760a17651b1SMemoryShore } 761a17651b1SMemoryShore 762a17651b1SMemoryShore #[inline(always)] 763a17651b1SMemoryShore pub fn write(&self) -> bool { 764a17651b1SMemoryShore return self.data & Arch::ENTRY_FLAG_READWRITE != 0; 765a17651b1SMemoryShore } 76640fe15e0SLoGin } 76740fe15e0SLoGin 76840fe15e0SLoGin /// 页表项的标志位 76940fe15e0SLoGin #[derive(Copy, Clone, Hash)] 770cf7f801eSMemoryShore pub struct EntryFlags<Arch> { 77140fe15e0SLoGin data: usize, 77240fe15e0SLoGin phantom: PhantomData<Arch>, 77340fe15e0SLoGin } 77440fe15e0SLoGin 775cf7f801eSMemoryShore impl<Arch: MemoryManagementArch> Default for EntryFlags<Arch> { 776dc9b4feaSLoGin fn default() -> Self { 777dc9b4feaSLoGin Self::new() 778dc9b4feaSLoGin } 779dc9b4feaSLoGin } 780dc9b4feaSLoGin 78140fe15e0SLoGin #[allow(dead_code)] 782cf7f801eSMemoryShore impl<Arch: MemoryManagementArch> EntryFlags<Arch> { 78340fe15e0SLoGin #[inline(always)] 78440fe15e0SLoGin pub fn new() -> Self { 78540fe15e0SLoGin let mut r = unsafe { 78640fe15e0SLoGin Self::from_data( 78740fe15e0SLoGin Arch::ENTRY_FLAG_DEFAULT_PAGE 78840fe15e0SLoGin | Arch::ENTRY_FLAG_READONLY 78940fe15e0SLoGin | Arch::ENTRY_FLAG_NO_EXEC, 79040fe15e0SLoGin ) 79140fe15e0SLoGin }; 79240fe15e0SLoGin 79340fe15e0SLoGin #[cfg(target_arch = "x86_64")] 79440fe15e0SLoGin { 79540fe15e0SLoGin if crate::arch::mm::X86_64MMArch::is_xd_reserved() { 79640fe15e0SLoGin r = r.set_execute(true); 79740fe15e0SLoGin } 79840fe15e0SLoGin } 79940fe15e0SLoGin 80040fe15e0SLoGin return r; 80140fe15e0SLoGin } 80240fe15e0SLoGin 803cf7f801eSMemoryShore /// 根据ProtFlags生成EntryFlags 80440fe15e0SLoGin /// 80540fe15e0SLoGin /// ## 参数 80640fe15e0SLoGin /// 80740fe15e0SLoGin /// - prot_flags: 页的保护标志 80840fe15e0SLoGin /// - user: 用户空间是否可访问 809cf7f801eSMemoryShore pub fn from_prot_flags(prot_flags: ProtFlags, user: bool) -> Self { 810cf7f801eSMemoryShore let vm_flags = super::VmFlags::from(prot_flags); 811cf7f801eSMemoryShore // let flags: EntryFlags<Arch> = EntryFlags::new() 812cf7f801eSMemoryShore // .set_user(user) 813cf7f801eSMemoryShore // .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC)) 814cf7f801eSMemoryShore // .set_write(prot_flags.contains(ProtFlags::PROT_WRITE)); 815cf7f801eSMemoryShore let flags = Arch::vm_get_page_prot(vm_flags).set_user(user); 81640fe15e0SLoGin return flags; 81740fe15e0SLoGin } 81840fe15e0SLoGin 81940fe15e0SLoGin #[inline(always)] 82040fe15e0SLoGin pub fn data(&self) -> usize { 82140fe15e0SLoGin self.data 82240fe15e0SLoGin } 82340fe15e0SLoGin 82440fe15e0SLoGin #[inline(always)] 82540fe15e0SLoGin pub const unsafe fn from_data(data: usize) -> Self { 82640fe15e0SLoGin return Self { 827b5b571e0SLoGin data, 82840fe15e0SLoGin phantom: PhantomData, 82940fe15e0SLoGin }; 83040fe15e0SLoGin } 83140fe15e0SLoGin 83240fe15e0SLoGin /// 为新页表的页表项设置默认值 83340fe15e0SLoGin /// 83440fe15e0SLoGin /// 默认值为: 83540fe15e0SLoGin /// - present 83640fe15e0SLoGin /// - read only 83740fe15e0SLoGin /// - kernel space 83840fe15e0SLoGin /// - no exec 83940fe15e0SLoGin #[inline(always)] 84040fe15e0SLoGin pub fn new_page_table(user: bool) -> Self { 84140fe15e0SLoGin return unsafe { 8427a29d4fcSLoGin let r = { 8437a29d4fcSLoGin #[cfg(target_arch = "x86_64")] 8447a29d4fcSLoGin { 8457a29d4fcSLoGin Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE | Arch::ENTRY_FLAG_READWRITE) 8467a29d4fcSLoGin } 8477a29d4fcSLoGin 8487a29d4fcSLoGin #[cfg(target_arch = "riscv64")] 8497a29d4fcSLoGin { 8507a29d4fcSLoGin // riscv64指向下一级页表的页表项,不应设置R/W/X权限位 8517a29d4fcSLoGin Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE) 8527a29d4fcSLoGin } 8537a29d4fcSLoGin }; 854471d65cfSLoGin 855471d65cfSLoGin #[cfg(target_arch = "x86_64")] 856471d65cfSLoGin { 85740fe15e0SLoGin if user { 85840fe15e0SLoGin r.set_user(true) 85940fe15e0SLoGin } else { 86040fe15e0SLoGin r 86140fe15e0SLoGin } 862471d65cfSLoGin } 863471d65cfSLoGin 864471d65cfSLoGin #[cfg(target_arch = "riscv64")] 865471d65cfSLoGin { 866471d65cfSLoGin r 867471d65cfSLoGin } 86840fe15e0SLoGin }; 86940fe15e0SLoGin } 87040fe15e0SLoGin 87140fe15e0SLoGin /// 取得当前页表项的所有权,更新当前页表项的标志位,并返回更新后的页表项。 87240fe15e0SLoGin /// 87340fe15e0SLoGin /// ## 参数 87440fe15e0SLoGin /// - flag 要更新的标志位的值 87540fe15e0SLoGin /// - value 如果为true,那么将flag对应的位设置为1,否则设置为0 87640fe15e0SLoGin /// 87740fe15e0SLoGin /// ## 返回值 87840fe15e0SLoGin /// 87940fe15e0SLoGin /// 更新后的页表项 88040fe15e0SLoGin #[inline(always)] 88140fe15e0SLoGin #[must_use] 88240fe15e0SLoGin pub fn update_flags(mut self, flag: usize, value: bool) -> Self { 88340fe15e0SLoGin if value { 88440fe15e0SLoGin self.data |= flag; 88540fe15e0SLoGin } else { 88640fe15e0SLoGin self.data &= !flag; 88740fe15e0SLoGin } 88840fe15e0SLoGin return self; 88940fe15e0SLoGin } 89040fe15e0SLoGin 89140fe15e0SLoGin /// 判断当前页表项是否存在指定的flag(只有全部flag都存在才返回true) 89240fe15e0SLoGin #[inline(always)] 89340fe15e0SLoGin pub fn has_flag(&self, flag: usize) -> bool { 89440fe15e0SLoGin return self.data & flag == flag; 89540fe15e0SLoGin } 89640fe15e0SLoGin 89740fe15e0SLoGin #[inline(always)] 89840fe15e0SLoGin pub fn present(&self) -> bool { 89940fe15e0SLoGin return self.has_flag(Arch::ENTRY_FLAG_PRESENT); 90040fe15e0SLoGin } 90140fe15e0SLoGin 90240fe15e0SLoGin /// 设置当前页表项的权限 90340fe15e0SLoGin /// 90440fe15e0SLoGin /// @param value 如果为true,那么将当前页表项的权限设置为用户态可访问 90540fe15e0SLoGin #[must_use] 90640fe15e0SLoGin #[inline(always)] 90740fe15e0SLoGin pub fn set_user(self, value: bool) -> Self { 90840fe15e0SLoGin return self.update_flags(Arch::ENTRY_FLAG_USER, value); 90940fe15e0SLoGin } 91040fe15e0SLoGin 91140fe15e0SLoGin /// 用户态是否可以访问当前页表项 91240fe15e0SLoGin #[inline(always)] 91340fe15e0SLoGin pub fn has_user(&self) -> bool { 91440fe15e0SLoGin return self.has_flag(Arch::ENTRY_FLAG_USER); 91540fe15e0SLoGin } 91640fe15e0SLoGin 91740fe15e0SLoGin /// 设置当前页表项的可写性, 如果为true,那么将当前页表项的权限设置为可写, 否则设置为只读 91840fe15e0SLoGin /// 91940fe15e0SLoGin /// ## 返回值 92040fe15e0SLoGin /// 92140fe15e0SLoGin /// 更新后的页表项. 92240fe15e0SLoGin /// 92340fe15e0SLoGin /// **请注意,**本函数会取得当前页表项的所有权,因此返回的页表项不是原来的页表项 92440fe15e0SLoGin #[must_use] 92540fe15e0SLoGin #[inline(always)] 92640fe15e0SLoGin pub fn set_write(self, value: bool) -> Self { 9277a29d4fcSLoGin #[cfg(target_arch = "x86_64")] 9287a29d4fcSLoGin { 92940fe15e0SLoGin // 有的架构同时具有可写和不可写的标志位,因此需要同时更新 93040fe15e0SLoGin return self 93140fe15e0SLoGin .update_flags(Arch::ENTRY_FLAG_READONLY, !value) 93240fe15e0SLoGin .update_flags(Arch::ENTRY_FLAG_READWRITE, value); 93340fe15e0SLoGin } 93440fe15e0SLoGin 9357a29d4fcSLoGin #[cfg(target_arch = "riscv64")] 9367a29d4fcSLoGin { 9377a29d4fcSLoGin if value { 9387a29d4fcSLoGin return self.update_flags(Arch::ENTRY_FLAG_READWRITE, true); 9397a29d4fcSLoGin } else { 940471d65cfSLoGin return self 941471d65cfSLoGin .update_flags(Arch::ENTRY_FLAG_READONLY, true) 942471d65cfSLoGin .update_flags(Arch::ENTRY_FLAG_WRITEABLE, false); 9437a29d4fcSLoGin } 9447a29d4fcSLoGin } 9457a29d4fcSLoGin } 9467a29d4fcSLoGin 94740fe15e0SLoGin /// 当前页表项是否可写 94840fe15e0SLoGin #[inline(always)] 94940fe15e0SLoGin pub fn has_write(&self) -> bool { 95040fe15e0SLoGin // 有的架构同时具有可写和不可写的标志位,因此需要同时判断 95140fe15e0SLoGin return self.data & (Arch::ENTRY_FLAG_READWRITE | Arch::ENTRY_FLAG_READONLY) 95240fe15e0SLoGin == Arch::ENTRY_FLAG_READWRITE; 95340fe15e0SLoGin } 95440fe15e0SLoGin 95540fe15e0SLoGin /// 设置当前页表项的可执行性, 如果为true,那么将当前页表项的权限设置为可执行, 否则设置为不可执行 95640fe15e0SLoGin #[must_use] 95740fe15e0SLoGin #[inline(always)] 95840fe15e0SLoGin pub fn set_execute(self, mut value: bool) -> Self { 95940fe15e0SLoGin #[cfg(target_arch = "x86_64")] 96040fe15e0SLoGin { 96140fe15e0SLoGin // 如果xd位被保留,那么将可执行性设置为true 96240fe15e0SLoGin if crate::arch::mm::X86_64MMArch::is_xd_reserved() { 96340fe15e0SLoGin value = true; 96440fe15e0SLoGin } 96540fe15e0SLoGin } 96640fe15e0SLoGin 96740fe15e0SLoGin // 有的架构同时具有可执行和不可执行的标志位,因此需要同时更新 96840fe15e0SLoGin return self 96940fe15e0SLoGin .update_flags(Arch::ENTRY_FLAG_NO_EXEC, !value) 97040fe15e0SLoGin .update_flags(Arch::ENTRY_FLAG_EXEC, value); 97140fe15e0SLoGin } 97240fe15e0SLoGin 97340fe15e0SLoGin /// 当前页表项是否可执行 97440fe15e0SLoGin #[inline(always)] 97540fe15e0SLoGin pub fn has_execute(&self) -> bool { 97640fe15e0SLoGin // 有的架构同时具有可执行和不可执行的标志位,因此需要同时判断 97740fe15e0SLoGin return self.data & (Arch::ENTRY_FLAG_EXEC | Arch::ENTRY_FLAG_NO_EXEC) 97840fe15e0SLoGin == Arch::ENTRY_FLAG_EXEC; 97940fe15e0SLoGin } 98040fe15e0SLoGin 98140fe15e0SLoGin /// 设置当前页表项的缓存策略 98240fe15e0SLoGin /// 98340fe15e0SLoGin /// ## 参数 98440fe15e0SLoGin /// 98540fe15e0SLoGin /// - value: 如果为true,那么将当前页表项的缓存策略设置为不缓存。 98640fe15e0SLoGin #[inline(always)] 98740fe15e0SLoGin pub fn set_page_cache_disable(self, value: bool) -> Self { 98840fe15e0SLoGin return self.update_flags(Arch::ENTRY_FLAG_CACHE_DISABLE, value); 98940fe15e0SLoGin } 99040fe15e0SLoGin 99140fe15e0SLoGin /// 获取当前页表项的缓存策略 99240fe15e0SLoGin /// 99340fe15e0SLoGin /// ## 返回值 99440fe15e0SLoGin /// 99540fe15e0SLoGin /// 如果当前页表项的缓存策略为不缓存,那么返回true,否则返回false。 99640fe15e0SLoGin #[inline(always)] 99740fe15e0SLoGin pub fn has_page_cache_disable(&self) -> bool { 99840fe15e0SLoGin return self.has_flag(Arch::ENTRY_FLAG_CACHE_DISABLE); 99940fe15e0SLoGin } 100040fe15e0SLoGin 100140fe15e0SLoGin /// 设置当前页表项的写穿策略 100240fe15e0SLoGin /// 100340fe15e0SLoGin /// ## 参数 100440fe15e0SLoGin /// 100540fe15e0SLoGin /// - value: 如果为true,那么将当前页表项的写穿策略设置为写穿。 100640fe15e0SLoGin #[inline(always)] 100740fe15e0SLoGin pub fn set_page_write_through(self, value: bool) -> Self { 100840fe15e0SLoGin return self.update_flags(Arch::ENTRY_FLAG_WRITE_THROUGH, value); 100940fe15e0SLoGin } 101040fe15e0SLoGin 1011731bc2b3SLoGin #[inline(always)] 1012731bc2b3SLoGin pub fn set_page_global(self, value: bool) -> Self { 1013731bc2b3SLoGin return self.update_flags(MMArch::ENTRY_FLAG_GLOBAL, value); 1014731bc2b3SLoGin } 1015731bc2b3SLoGin 101640fe15e0SLoGin /// 获取当前页表项的写穿策略 101740fe15e0SLoGin /// 101840fe15e0SLoGin /// ## 返回值 101940fe15e0SLoGin /// 102040fe15e0SLoGin /// 如果当前页表项的写穿策略为写穿,那么返回true,否则返回false。 102140fe15e0SLoGin #[inline(always)] 102240fe15e0SLoGin pub fn has_page_write_through(&self) -> bool { 102340fe15e0SLoGin return self.has_flag(Arch::ENTRY_FLAG_WRITE_THROUGH); 102440fe15e0SLoGin } 102540fe15e0SLoGin 1026a17651b1SMemoryShore /// 设置当前页表是否为脏页 1027a17651b1SMemoryShore /// 1028a17651b1SMemoryShore /// ## 参数 1029a17651b1SMemoryShore /// 1030a17651b1SMemoryShore /// - value: 如果为true,那么将当前页表项的写穿策略设置为写穿。 1031a17651b1SMemoryShore #[inline(always)] 1032a17651b1SMemoryShore pub fn set_dirty(self, value: bool) -> Self { 1033a17651b1SMemoryShore return self.update_flags(Arch::ENTRY_FLAG_DIRTY, value); 1034a17651b1SMemoryShore } 1035a17651b1SMemoryShore 1036a17651b1SMemoryShore /// 设置当前页表被访问 1037a17651b1SMemoryShore /// 1038a17651b1SMemoryShore /// ## 参数 1039a17651b1SMemoryShore /// 1040a17651b1SMemoryShore /// - value: 如果为true,那么将当前页表项的访问标志设置为已访问。 1041a17651b1SMemoryShore #[inline(always)] 1042a17651b1SMemoryShore pub fn set_access(self, value: bool) -> Self { 1043a17651b1SMemoryShore return self.update_flags(Arch::ENTRY_FLAG_ACCESSED, value); 1044a17651b1SMemoryShore } 1045a17651b1SMemoryShore 1046a17651b1SMemoryShore /// 设置指向的页是否为大页 1047a17651b1SMemoryShore /// 1048a17651b1SMemoryShore /// ## 参数 1049a17651b1SMemoryShore /// 1050a17651b1SMemoryShore /// - value: 如果为true,那么将当前页表项的访问标志设置为已访问。 1051a17651b1SMemoryShore #[inline(always)] 1052a17651b1SMemoryShore pub fn set_huge_page(self, value: bool) -> Self { 1053a17651b1SMemoryShore return self.update_flags(Arch::ENTRY_FLAG_HUGE_PAGE, value); 1054a17651b1SMemoryShore } 1055a17651b1SMemoryShore 105640fe15e0SLoGin /// MMIO内存的页表项标志 105740fe15e0SLoGin #[inline(always)] 105840fe15e0SLoGin pub fn mmio_flags() -> Self { 1059471d65cfSLoGin #[cfg(target_arch = "x86_64")] 1060471d65cfSLoGin { 1061471d65cfSLoGin Self::new() 106240fe15e0SLoGin .set_user(false) 106340fe15e0SLoGin .set_write(true) 106440fe15e0SLoGin .set_execute(true) 106540fe15e0SLoGin .set_page_cache_disable(true) 1066731bc2b3SLoGin .set_page_write_through(true) 1067471d65cfSLoGin .set_page_global(true) 1068471d65cfSLoGin } 1069471d65cfSLoGin 1070471d65cfSLoGin #[cfg(target_arch = "riscv64")] 1071471d65cfSLoGin { 1072471d65cfSLoGin Self::new() 1073471d65cfSLoGin .set_user(false) 1074471d65cfSLoGin .set_write(true) 1075471d65cfSLoGin .set_execute(true) 1076471d65cfSLoGin .set_page_global(true) 1077471d65cfSLoGin } 107840fe15e0SLoGin } 107940fe15e0SLoGin } 108040fe15e0SLoGin 1081cf7f801eSMemoryShore impl<Arch: MemoryManagementArch> fmt::Debug for EntryFlags<Arch> { 108240fe15e0SLoGin fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1083cf7f801eSMemoryShore f.debug_struct("EntryFlags") 108440fe15e0SLoGin .field("bits", &format_args!("{:#0x}", self.data)) 108540fe15e0SLoGin .field("present", &self.present()) 108640fe15e0SLoGin .field("has_write", &self.has_write()) 108740fe15e0SLoGin .field("has_execute", &self.has_execute()) 108840fe15e0SLoGin .field("has_user", &self.has_user()) 108940fe15e0SLoGin .finish() 109040fe15e0SLoGin } 109140fe15e0SLoGin } 109240fe15e0SLoGin 109340fe15e0SLoGin /// 页表映射器 109440fe15e0SLoGin #[derive(Hash)] 109540fe15e0SLoGin pub struct PageMapper<Arch, F> { 109640fe15e0SLoGin /// 页表类型 109740fe15e0SLoGin table_kind: PageTableKind, 109840fe15e0SLoGin /// 根页表物理地址 109940fe15e0SLoGin table_paddr: PhysAddr, 110040fe15e0SLoGin /// 页分配器 110140fe15e0SLoGin frame_allocator: F, 110240fe15e0SLoGin phantom: PhantomData<fn() -> Arch>, 110340fe15e0SLoGin } 110440fe15e0SLoGin 110540fe15e0SLoGin impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> { 110640fe15e0SLoGin /// 创建新的页面映射器 110740fe15e0SLoGin /// 110840fe15e0SLoGin /// ## 参数 110940fe15e0SLoGin /// - table_kind 页表类型 111040fe15e0SLoGin /// - table_paddr 根页表物理地址 111140fe15e0SLoGin /// - allocator 页分配器 111240fe15e0SLoGin /// 111340fe15e0SLoGin /// ## 返回值 111440fe15e0SLoGin /// 111540fe15e0SLoGin /// 页面映射器 111640fe15e0SLoGin pub unsafe fn new(table_kind: PageTableKind, table_paddr: PhysAddr, allocator: F) -> Self { 111740fe15e0SLoGin return Self { 111840fe15e0SLoGin table_kind, 111940fe15e0SLoGin table_paddr, 112040fe15e0SLoGin frame_allocator: allocator, 112140fe15e0SLoGin phantom: PhantomData, 112240fe15e0SLoGin }; 112340fe15e0SLoGin } 112440fe15e0SLoGin 112540fe15e0SLoGin /// 创建页表,并为这个页表创建页面映射器 112640fe15e0SLoGin pub unsafe fn create(table_kind: PageTableKind, mut allocator: F) -> Option<Self> { 112740fe15e0SLoGin let table_paddr = allocator.allocate_one()?; 112840fe15e0SLoGin // 清空页表 112940fe15e0SLoGin let table_vaddr = Arch::phys_2_virt(table_paddr)?; 113040fe15e0SLoGin Arch::write_bytes(table_vaddr, 0, Arch::PAGE_SIZE); 113140fe15e0SLoGin return Some(Self::new(table_kind, table_paddr, allocator)); 113240fe15e0SLoGin } 113340fe15e0SLoGin 113440fe15e0SLoGin /// 获取当前页表的页面映射器 113540fe15e0SLoGin #[inline(always)] 113640fe15e0SLoGin pub unsafe fn current(table_kind: PageTableKind, allocator: F) -> Self { 113740fe15e0SLoGin let table_paddr = Arch::table(table_kind); 113840fe15e0SLoGin return Self::new(table_kind, table_paddr, allocator); 113940fe15e0SLoGin } 114040fe15e0SLoGin 114140fe15e0SLoGin /// 判断当前页表分配器所属的页表是否是当前页表 114240fe15e0SLoGin #[inline(always)] 114340fe15e0SLoGin pub fn is_current(&self) -> bool { 114440fe15e0SLoGin return unsafe { self.table().phys() == Arch::table(self.table_kind) }; 114540fe15e0SLoGin } 114640fe15e0SLoGin 114740fe15e0SLoGin /// 将当前页表分配器所属的页表设置为当前页表 114840fe15e0SLoGin #[inline(always)] 114940fe15e0SLoGin pub unsafe fn make_current(&self) { 115040fe15e0SLoGin Arch::set_table(self.table_kind, self.table_paddr); 115140fe15e0SLoGin } 115240fe15e0SLoGin 115340fe15e0SLoGin /// 获取当前页表分配器所属的根页表的结构体 115440fe15e0SLoGin #[inline(always)] 115540fe15e0SLoGin pub fn table(&self) -> PageTable<Arch> { 115640fe15e0SLoGin // 由于只能通过new方法创建PageMapper,因此这里假定table_paddr是有效的 115740fe15e0SLoGin return unsafe { 115840fe15e0SLoGin PageTable::new(VirtAddr::new(0), self.table_paddr, Arch::PAGE_LEVELS - 1) 115940fe15e0SLoGin }; 116040fe15e0SLoGin } 116140fe15e0SLoGin 116240fe15e0SLoGin /// 获取当前PageMapper所对应的页分配器实例的引用 116340fe15e0SLoGin #[inline(always)] 116440fe15e0SLoGin #[allow(dead_code)] 116540fe15e0SLoGin pub fn allocator_ref(&self) -> &F { 116640fe15e0SLoGin return &self.frame_allocator; 116740fe15e0SLoGin } 116840fe15e0SLoGin 116940fe15e0SLoGin /// 获取当前PageMapper所对应的页分配器实例的可变引用 117040fe15e0SLoGin #[inline(always)] 117140fe15e0SLoGin pub fn allocator_mut(&mut self) -> &mut F { 117240fe15e0SLoGin return &mut self.frame_allocator; 117340fe15e0SLoGin } 117440fe15e0SLoGin 117540fe15e0SLoGin /// 从当前PageMapper的页分配器中分配一个物理页,并将其映射到指定的虚拟地址 117640fe15e0SLoGin pub unsafe fn map( 117740fe15e0SLoGin &mut self, 117840fe15e0SLoGin virt: VirtAddr, 1179cf7f801eSMemoryShore flags: EntryFlags<Arch>, 118040fe15e0SLoGin ) -> Option<PageFlush<Arch>> { 118140fe15e0SLoGin compiler_fence(Ordering::SeqCst); 118240fe15e0SLoGin let phys: PhysAddr = self.frame_allocator.allocate_one()?; 118340fe15e0SLoGin compiler_fence(Ordering::SeqCst); 118456cc4dbeSJomo 1185de199e3cSMemoryShore unsafe { 1186de199e3cSMemoryShore let vaddr = MMArch::phys_2_virt(phys).unwrap(); 1187de199e3cSMemoryShore MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE); 1188de199e3cSMemoryShore } 1189de199e3cSMemoryShore 11906fc066acSJomo let mut page_manager_guard: SpinLockGuard<'static, PageManager> = 11916fc066acSJomo page_manager_lock_irqsave(); 11926fc066acSJomo if !page_manager_guard.contains(&phys) { 1193cf7f801eSMemoryShore page_manager_guard.insert(phys, &Arc::new(Page::new(false, phys))) 11946fc066acSJomo } 1195cf7f801eSMemoryShore drop(page_manager_guard); 119640fe15e0SLoGin return self.map_phys(virt, phys, flags); 119740fe15e0SLoGin } 119840fe15e0SLoGin 119940fe15e0SLoGin /// 映射一个物理页到指定的虚拟地址 120040fe15e0SLoGin pub unsafe fn map_phys( 120140fe15e0SLoGin &mut self, 120240fe15e0SLoGin virt: VirtAddr, 120340fe15e0SLoGin phys: PhysAddr, 1204cf7f801eSMemoryShore flags: EntryFlags<Arch>, 120540fe15e0SLoGin ) -> Option<PageFlush<Arch>> { 120640fe15e0SLoGin // 验证虚拟地址和物理地址是否对齐 120740fe15e0SLoGin if !(virt.check_aligned(Arch::PAGE_SIZE) && phys.check_aligned(Arch::PAGE_SIZE)) { 12082eab6dd7S曾俊 error!( 120940fe15e0SLoGin "Try to map unaligned page: virt={:?}, phys={:?}", 12102eab6dd7S曾俊 virt, phys 121140fe15e0SLoGin ); 121240fe15e0SLoGin return None; 121340fe15e0SLoGin } 12147a29d4fcSLoGin 121540fe15e0SLoGin let virt = VirtAddr::new(virt.data() & (!Arch::PAGE_NEGATIVE_MASK)); 121640fe15e0SLoGin 121740fe15e0SLoGin // TODO: 验证flags是否合法 121840fe15e0SLoGin 121940fe15e0SLoGin // 创建页表项 12207a29d4fcSLoGin let entry = PageEntry::new(phys, flags); 122140fe15e0SLoGin let mut table = self.table(); 122240fe15e0SLoGin loop { 122340fe15e0SLoGin let i = table.index_of(virt)?; 1224471d65cfSLoGin 122540fe15e0SLoGin assert!(i < Arch::PAGE_ENTRY_NUM); 122640fe15e0SLoGin if table.level() == 0 { 122740fe15e0SLoGin compiler_fence(Ordering::SeqCst); 12287a29d4fcSLoGin 122940fe15e0SLoGin table.set_entry(i, entry); 123040fe15e0SLoGin compiler_fence(Ordering::SeqCst); 123140fe15e0SLoGin return Some(PageFlush::new(virt)); 123240fe15e0SLoGin } else { 123340fe15e0SLoGin let next_table = table.next_level_table(i); 123440fe15e0SLoGin if let Some(next_table) = next_table { 123540fe15e0SLoGin table = next_table; 12362eab6dd7S曾俊 // debug!("Mapping {:?} to next level table...", virt); 123740fe15e0SLoGin } else { 123840fe15e0SLoGin // 分配下一级页表 123940fe15e0SLoGin let frame = self.frame_allocator.allocate_one()?; 12407a29d4fcSLoGin 124140fe15e0SLoGin // 清空这个页帧 124240fe15e0SLoGin MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE); 124340fe15e0SLoGin // 设置页表项的flags 1244cf7f801eSMemoryShore let flags: EntryFlags<Arch> = 1245cf7f801eSMemoryShore EntryFlags::new_page_table(virt.kind() == PageTableKind::User); 124640fe15e0SLoGin 124740fe15e0SLoGin // 把新分配的页表映射到当前页表 12487a29d4fcSLoGin table.set_entry(i, PageEntry::new(frame, flags)); 124940fe15e0SLoGin 125040fe15e0SLoGin // 获取新分配的页表 125140fe15e0SLoGin table = table.next_level_table(i)?; 125240fe15e0SLoGin } 125340fe15e0SLoGin } 125440fe15e0SLoGin } 125540fe15e0SLoGin } 125640fe15e0SLoGin 1257a17651b1SMemoryShore /// 进行大页映射 1258a17651b1SMemoryShore pub unsafe fn map_huge_page( 1259a17651b1SMemoryShore &mut self, 1260a17651b1SMemoryShore virt: VirtAddr, 1261cf7f801eSMemoryShore flags: EntryFlags<Arch>, 1262a17651b1SMemoryShore ) -> Option<PageFlush<Arch>> { 1263a17651b1SMemoryShore // 验证虚拟地址是否对齐 1264a17651b1SMemoryShore if !(virt.check_aligned(Arch::PAGE_SIZE)) { 12652eab6dd7S曾俊 error!("Try to map unaligned page: virt={:?}", virt); 1266a17651b1SMemoryShore return None; 1267a17651b1SMemoryShore } 1268a17651b1SMemoryShore 1269a17651b1SMemoryShore let virt = VirtAddr::new(virt.data() & (!Arch::PAGE_NEGATIVE_MASK)); 1270a17651b1SMemoryShore 1271a17651b1SMemoryShore let mut table = self.table(); 1272a17651b1SMemoryShore loop { 1273a17651b1SMemoryShore let i = table.index_of(virt)?; 1274a17651b1SMemoryShore assert!(i < Arch::PAGE_ENTRY_NUM); 1275a17651b1SMemoryShore let next_table = table.next_level_table(i); 1276a17651b1SMemoryShore if let Some(next_table) = next_table { 1277a17651b1SMemoryShore table = next_table; 1278a17651b1SMemoryShore } else { 1279a17651b1SMemoryShore break; 1280a17651b1SMemoryShore } 1281a17651b1SMemoryShore } 1282a17651b1SMemoryShore 1283a17651b1SMemoryShore // 支持2M、1G大页,即页表层级为1、2级的页表可以映射大页 1284a17651b1SMemoryShore if table.level == 0 || table.level > 2 { 1285a17651b1SMemoryShore return None; 1286a17651b1SMemoryShore } 1287a17651b1SMemoryShore 1288a17651b1SMemoryShore let (phys, count) = self.frame_allocator.allocate(PageFrameCount::new( 1289a17651b1SMemoryShore Arch::PAGE_ENTRY_NUM.pow(table.level as u32), 1290a17651b1SMemoryShore ))?; 1291a17651b1SMemoryShore 1292a17651b1SMemoryShore MMArch::write_bytes( 1293a17651b1SMemoryShore MMArch::phys_2_virt(phys).unwrap(), 1294a17651b1SMemoryShore 0, 1295a17651b1SMemoryShore MMArch::PAGE_SIZE * count.data(), 1296a17651b1SMemoryShore ); 1297a17651b1SMemoryShore 1298a17651b1SMemoryShore table.set_entry( 1299a17651b1SMemoryShore table.index_of(virt)?, 1300a17651b1SMemoryShore PageEntry::new(phys, flags.set_huge_page(true)), 1301a17651b1SMemoryShore )?; 1302a17651b1SMemoryShore Some(PageFlush::new(virt)) 1303a17651b1SMemoryShore } 1304a17651b1SMemoryShore 1305a17651b1SMemoryShore /// 为虚拟地址分配指定层级的页表 1306a17651b1SMemoryShore /// ## 参数 1307a17651b1SMemoryShore /// 1308a17651b1SMemoryShore /// - `virt`: 虚拟地址 1309a17651b1SMemoryShore /// - `level`: 指定页表层级 1310a17651b1SMemoryShore /// 1311a17651b1SMemoryShore /// ## 返回值 1312a17651b1SMemoryShore /// - Some(PageTable<Arch>): 虚拟地址对应层级的页表 1313a17651b1SMemoryShore /// - None: 对应页表不存在 1314a17651b1SMemoryShore pub unsafe fn allocate_table( 1315a17651b1SMemoryShore &mut self, 1316a17651b1SMemoryShore virt: VirtAddr, 1317a17651b1SMemoryShore level: usize, 1318a17651b1SMemoryShore ) -> Option<PageTable<Arch>> { 1319a17651b1SMemoryShore let table = self.get_table(virt, level + 1)?; 1320a17651b1SMemoryShore let i = table.index_of(virt)?; 1321a17651b1SMemoryShore let frame = self.frame_allocator.allocate_one()?; 1322a17651b1SMemoryShore 1323a17651b1SMemoryShore // 清空这个页帧 1324a17651b1SMemoryShore MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE); 1325a17651b1SMemoryShore 1326a17651b1SMemoryShore // 设置页表项的flags 1327cf7f801eSMemoryShore let flags: EntryFlags<Arch> = 1328cf7f801eSMemoryShore EntryFlags::new_page_table(virt.kind() == PageTableKind::User); 1329a17651b1SMemoryShore 1330a17651b1SMemoryShore table.set_entry(i, PageEntry::new(frame, flags)); 1331a17651b1SMemoryShore table.next_level_table(i) 1332a17651b1SMemoryShore } 1333a17651b1SMemoryShore 1334a17651b1SMemoryShore /// 获取虚拟地址的指定层级页表 1335a17651b1SMemoryShore /// ## 参数 1336a17651b1SMemoryShore /// 1337a17651b1SMemoryShore /// - `virt`: 虚拟地址 1338a17651b1SMemoryShore /// - `level`: 指定页表层级 1339a17651b1SMemoryShore /// 1340a17651b1SMemoryShore /// ## 返回值 1341a17651b1SMemoryShore /// - Some(PageTable<Arch>): 虚拟地址对应层级的页表 1342a17651b1SMemoryShore /// - None: 对应页表不存在 1343a17651b1SMemoryShore pub fn get_table(&self, virt: VirtAddr, level: usize) -> Option<PageTable<Arch>> { 1344a17651b1SMemoryShore let mut table = self.table(); 1345a17651b1SMemoryShore if level > Arch::PAGE_LEVELS - 1 { 1346a17651b1SMemoryShore return None; 1347a17651b1SMemoryShore } 1348a17651b1SMemoryShore 1349a17651b1SMemoryShore unsafe { 1350a17651b1SMemoryShore loop { 1351a17651b1SMemoryShore if table.level == level { 1352a17651b1SMemoryShore return Some(table); 1353a17651b1SMemoryShore } 1354a17651b1SMemoryShore let i = table.index_of(virt)?; 1355a17651b1SMemoryShore assert!(i < Arch::PAGE_ENTRY_NUM); 1356a17651b1SMemoryShore 1357a17651b1SMemoryShore table = table.next_level_table(i)?; 1358a17651b1SMemoryShore } 1359a17651b1SMemoryShore } 1360a17651b1SMemoryShore } 1361a17651b1SMemoryShore 1362a17651b1SMemoryShore /// 获取虚拟地址在指定层级页表的PageEntry 1363a17651b1SMemoryShore /// ## 参数 1364a17651b1SMemoryShore /// 1365a17651b1SMemoryShore /// - `virt`: 虚拟地址 1366a17651b1SMemoryShore /// - `level`: 指定页表层级 1367a17651b1SMemoryShore /// 1368a17651b1SMemoryShore /// ## 返回值 1369a17651b1SMemoryShore /// - Some(PageEntry<Arch>): 虚拟地址在指定层级的页表的有效PageEntry 1370a17651b1SMemoryShore /// - None: 无对应的有效PageEntry 1371a17651b1SMemoryShore pub fn get_entry(&self, virt: VirtAddr, level: usize) -> Option<PageEntry<Arch>> { 1372a17651b1SMemoryShore let table = self.get_table(virt, level)?; 1373a17651b1SMemoryShore let i = table.index_of(virt)?; 1374a17651b1SMemoryShore let entry = unsafe { table.entry(i) }?; 1375a17651b1SMemoryShore 1376a17651b1SMemoryShore if !entry.empty() { 1377a17651b1SMemoryShore Some(entry) 1378a17651b1SMemoryShore } else { 1379a17651b1SMemoryShore None 1380a17651b1SMemoryShore } 1381a17651b1SMemoryShore 1382a17651b1SMemoryShore // let mut table = self.table(); 1383a17651b1SMemoryShore // if level > Arch::PAGE_LEVELS - 1 { 1384a17651b1SMemoryShore // return None; 1385a17651b1SMemoryShore // } 1386a17651b1SMemoryShore // unsafe { 1387a17651b1SMemoryShore // loop { 1388a17651b1SMemoryShore // let i = table.index_of(virt)?; 1389a17651b1SMemoryShore // assert!(i < Arch::PAGE_ENTRY_NUM); 1390a17651b1SMemoryShore 1391a17651b1SMemoryShore // if table.level == level { 1392a17651b1SMemoryShore // let entry = table.entry(i)?; 1393a17651b1SMemoryShore // if !entry.empty() { 1394a17651b1SMemoryShore // return Some(entry); 1395a17651b1SMemoryShore // } else { 1396a17651b1SMemoryShore // return None; 1397a17651b1SMemoryShore // } 1398a17651b1SMemoryShore // } 1399a17651b1SMemoryShore 1400a17651b1SMemoryShore // table = table.next_level_table(i)?; 1401a17651b1SMemoryShore // } 1402a17651b1SMemoryShore // } 1403a17651b1SMemoryShore } 1404a17651b1SMemoryShore 1405a17651b1SMemoryShore /// 拷贝用户空间映射 1406a17651b1SMemoryShore /// ## 参数 1407a17651b1SMemoryShore /// 1408a17651b1SMemoryShore /// - `umapper`: 要拷贝的用户空间 1409a17651b1SMemoryShore /// - `copy_on_write`: 是否写时复制 1410a17651b1SMemoryShore pub unsafe fn clone_user_mapping(&mut self, umapper: &mut Self, copy_on_write: bool) { 1411a17651b1SMemoryShore let old_table = umapper.table(); 1412a17651b1SMemoryShore let new_table = self.table(); 1413a17651b1SMemoryShore let allocator = self.allocator_mut(); 1414a17651b1SMemoryShore // 顶级页表的[0, PAGE_KERNEL_INDEX)项为用户空间映射 1415a17651b1SMemoryShore for entry_index in 0..Arch::PAGE_KERNEL_INDEX { 1416a17651b1SMemoryShore if let Some(next_table) = old_table.next_level_table(entry_index) { 1417a17651b1SMemoryShore let table = next_table.clone(allocator, copy_on_write).unwrap(); 1418a17651b1SMemoryShore let old_entry = old_table.entry(entry_index).unwrap(); 1419a17651b1SMemoryShore let entry = PageEntry::new(table.phys(), old_entry.flags()); 1420a17651b1SMemoryShore new_table.set_entry(entry_index, entry); 1421a17651b1SMemoryShore } 1422a17651b1SMemoryShore } 1423a17651b1SMemoryShore } 1424a17651b1SMemoryShore 142540fe15e0SLoGin /// 将物理地址映射到具有线性偏移量的虚拟地址 142640fe15e0SLoGin #[allow(dead_code)] 142740fe15e0SLoGin pub unsafe fn map_linearly( 142840fe15e0SLoGin &mut self, 142940fe15e0SLoGin phys: PhysAddr, 1430cf7f801eSMemoryShore flags: EntryFlags<Arch>, 143140fe15e0SLoGin ) -> Option<(VirtAddr, PageFlush<Arch>)> { 143240fe15e0SLoGin let virt: VirtAddr = Arch::phys_2_virt(phys)?; 143340fe15e0SLoGin return self.map_phys(virt, phys, flags).map(|flush| (virt, flush)); 143440fe15e0SLoGin } 143540fe15e0SLoGin 143640fe15e0SLoGin /// 修改虚拟地址的页表项的flags,并返回页表项刷新器 143740fe15e0SLoGin /// 143840fe15e0SLoGin /// 请注意,需要在修改完flags后,调用刷新器的flush方法,才能使修改生效 143940fe15e0SLoGin /// 144040fe15e0SLoGin /// ## 参数 144140fe15e0SLoGin /// - virt 虚拟地址 144240fe15e0SLoGin /// - flags 新的页表项的flags 144340fe15e0SLoGin /// 144440fe15e0SLoGin /// ## 返回值 144540fe15e0SLoGin /// 144640fe15e0SLoGin /// 如果修改成功,返回刷新器,否则返回None 144740fe15e0SLoGin pub unsafe fn remap( 144840fe15e0SLoGin &mut self, 144940fe15e0SLoGin virt: VirtAddr, 1450cf7f801eSMemoryShore flags: EntryFlags<Arch>, 145140fe15e0SLoGin ) -> Option<PageFlush<Arch>> { 145240fe15e0SLoGin return self 145340fe15e0SLoGin .visit(virt, |p1, i| { 145440fe15e0SLoGin let mut entry = p1.entry(i)?; 1455731bc2b3SLoGin 145640fe15e0SLoGin entry.set_flags(flags); 145740fe15e0SLoGin p1.set_entry(i, entry); 145840fe15e0SLoGin Some(PageFlush::new(virt)) 145940fe15e0SLoGin }) 146040fe15e0SLoGin .flatten(); 146140fe15e0SLoGin } 146240fe15e0SLoGin 146340fe15e0SLoGin /// 根据虚拟地址,查找页表,获取对应的物理地址和页表项的flags 146440fe15e0SLoGin /// 146540fe15e0SLoGin /// ## 参数 146640fe15e0SLoGin /// 146740fe15e0SLoGin /// - virt 虚拟地址 146840fe15e0SLoGin /// 146940fe15e0SLoGin /// ## 返回值 147040fe15e0SLoGin /// 147140fe15e0SLoGin /// 如果查找成功,返回物理地址和页表项的flags,否则返回None 1472cf7f801eSMemoryShore pub fn translate(&self, virt: VirtAddr) -> Option<(PhysAddr, EntryFlags<Arch>)> { 147340fe15e0SLoGin let entry: PageEntry<Arch> = self.visit(virt, |p1, i| unsafe { p1.entry(i) })??; 147440fe15e0SLoGin let paddr = entry.address().ok()?; 147540fe15e0SLoGin let flags = entry.flags(); 147640fe15e0SLoGin return Some((paddr, flags)); 147740fe15e0SLoGin } 147840fe15e0SLoGin 147940fe15e0SLoGin /// 取消虚拟地址的映射,释放页面,并返回页表项刷新器 148040fe15e0SLoGin /// 148140fe15e0SLoGin /// 请注意,需要在取消映射后,调用刷新器的flush方法,才能使修改生效 148240fe15e0SLoGin /// 148340fe15e0SLoGin /// ## 参数 148440fe15e0SLoGin /// 148540fe15e0SLoGin /// - virt 虚拟地址 148640fe15e0SLoGin /// - unmap_parents 是否在父页表内,取消空闲子页表的映射 148740fe15e0SLoGin /// 148840fe15e0SLoGin /// ## 返回值 148940fe15e0SLoGin /// 如果取消成功,返回刷新器,否则返回None 14902dd9f0c7SLoGin #[allow(dead_code)] 149140fe15e0SLoGin pub unsafe fn unmap(&mut self, virt: VirtAddr, unmap_parents: bool) -> Option<PageFlush<Arch>> { 149240fe15e0SLoGin let (paddr, _, flusher) = self.unmap_phys(virt, unmap_parents)?; 149340fe15e0SLoGin self.frame_allocator.free_one(paddr); 149440fe15e0SLoGin return Some(flusher); 149540fe15e0SLoGin } 149640fe15e0SLoGin 149740fe15e0SLoGin /// 取消虚拟地址的映射,并返回物理地址和页表项的flags 149840fe15e0SLoGin /// 149940fe15e0SLoGin /// ## 参数 150040fe15e0SLoGin /// 150140fe15e0SLoGin /// - vaddr 虚拟地址 150240fe15e0SLoGin /// - unmap_parents 是否在父页表内,取消空闲子页表的映射 150340fe15e0SLoGin /// 150440fe15e0SLoGin /// ## 返回值 150540fe15e0SLoGin /// 150640fe15e0SLoGin /// 如果取消成功,返回物理地址和页表项的flags,否则返回None 150740fe15e0SLoGin pub unsafe fn unmap_phys( 150840fe15e0SLoGin &mut self, 150940fe15e0SLoGin virt: VirtAddr, 151040fe15e0SLoGin unmap_parents: bool, 1511cf7f801eSMemoryShore ) -> Option<(PhysAddr, EntryFlags<Arch>, PageFlush<Arch>)> { 151240fe15e0SLoGin if !virt.check_aligned(Arch::PAGE_SIZE) { 15132eab6dd7S曾俊 error!("Try to unmap unaligned page: virt={:?}", virt); 151440fe15e0SLoGin return None; 151540fe15e0SLoGin } 151640fe15e0SLoGin 1517b5b571e0SLoGin let table = self.table(); 1518b5b571e0SLoGin return unmap_phys_inner(virt, &table, unmap_parents, self.allocator_mut()) 151940fe15e0SLoGin .map(|(paddr, flags)| (paddr, flags, PageFlush::<Arch>::new(virt))); 152040fe15e0SLoGin } 152140fe15e0SLoGin 152240fe15e0SLoGin /// 在页表中,访问虚拟地址对应的页表项,并调用传入的函数F 152340fe15e0SLoGin fn visit<T>( 152440fe15e0SLoGin &self, 152540fe15e0SLoGin virt: VirtAddr, 152640fe15e0SLoGin f: impl FnOnce(&mut PageTable<Arch>, usize) -> T, 152740fe15e0SLoGin ) -> Option<T> { 152840fe15e0SLoGin let mut table = self.table(); 152940fe15e0SLoGin unsafe { 153040fe15e0SLoGin loop { 153140fe15e0SLoGin let i = table.index_of(virt)?; 153240fe15e0SLoGin if table.level() == 0 { 153340fe15e0SLoGin return Some(f(&mut table, i)); 153440fe15e0SLoGin } else { 153540fe15e0SLoGin table = table.next_level_table(i)?; 153640fe15e0SLoGin } 153740fe15e0SLoGin } 153840fe15e0SLoGin } 153940fe15e0SLoGin } 154040fe15e0SLoGin } 154140fe15e0SLoGin 154240fe15e0SLoGin /// 取消页面映射,返回被取消映射的页表项的:【物理地址】和【flags】 154340fe15e0SLoGin /// 154440fe15e0SLoGin /// ## 参数 154540fe15e0SLoGin /// 154640fe15e0SLoGin /// - vaddr 虚拟地址 154740fe15e0SLoGin /// - table 页表 154840fe15e0SLoGin /// - unmap_parents 是否在父页表内,取消空闲子页表的映射 154940fe15e0SLoGin /// - allocator 页面分配器(如果页表从这个分配器分配,那么在取消映射时,也需要归还到这个分配器内) 155040fe15e0SLoGin /// 155140fe15e0SLoGin /// ## 返回值 155240fe15e0SLoGin /// 155340fe15e0SLoGin /// 如果取消成功,返回被取消映射的页表项的:【物理地址】和【flags】,否则返回None 155440fe15e0SLoGin unsafe fn unmap_phys_inner<Arch: MemoryManagementArch>( 155540fe15e0SLoGin vaddr: VirtAddr, 1556840045afSLoGin table: &PageTable<Arch>, 155740fe15e0SLoGin unmap_parents: bool, 155840fe15e0SLoGin allocator: &mut impl FrameAllocator, 1559cf7f801eSMemoryShore ) -> Option<(PhysAddr, EntryFlags<Arch>)> { 156040fe15e0SLoGin // 获取页表项的索引 156140fe15e0SLoGin let i = table.index_of(vaddr)?; 156240fe15e0SLoGin 156340fe15e0SLoGin // 如果当前是最后一级页表,直接取消页面映射 156440fe15e0SLoGin if table.level() == 0 { 156540fe15e0SLoGin let entry = table.entry(i)?; 15667a29d4fcSLoGin table.set_entry(i, PageEntry::from_usize(0)); 156740fe15e0SLoGin return Some((entry.address().ok()?, entry.flags())); 156840fe15e0SLoGin } 156940fe15e0SLoGin 1570b5b571e0SLoGin let subtable = table.next_level_table(i)?; 157140fe15e0SLoGin // 递归地取消映射 1572b5b571e0SLoGin let result = unmap_phys_inner(vaddr, &subtable, unmap_parents, allocator)?; 157340fe15e0SLoGin 157440fe15e0SLoGin // TODO: This is a bad idea for architectures where the kernel mappings are done in the process tables, 157540fe15e0SLoGin // as these mappings may become out of sync 157640fe15e0SLoGin if unmap_parents { 157740fe15e0SLoGin // 如果子页表已经没有映射的页面了,就取消子页表的映射 157840fe15e0SLoGin 157940fe15e0SLoGin // 检查子页表中是否还有映射的页面 158040fe15e0SLoGin let x = (0..Arch::PAGE_ENTRY_NUM) 158140fe15e0SLoGin .map(|k| subtable.entry(k).expect("invalid page entry")) 158240fe15e0SLoGin .any(|e| e.present()); 158340fe15e0SLoGin if !x { 158440fe15e0SLoGin // 如果没有,就取消子页表的映射 15857a29d4fcSLoGin table.set_entry(i, PageEntry::from_usize(0)); 158640fe15e0SLoGin // 释放子页表 158740fe15e0SLoGin allocator.free_one(subtable.phys()); 158840fe15e0SLoGin } 158940fe15e0SLoGin } 159040fe15e0SLoGin 159140fe15e0SLoGin return Some(result); 159240fe15e0SLoGin } 159340fe15e0SLoGin 159440fe15e0SLoGin impl<Arch, F: Debug> Debug for PageMapper<Arch, F> { 159540fe15e0SLoGin fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 159640fe15e0SLoGin f.debug_struct("PageMapper") 159740fe15e0SLoGin .field("table_paddr", &self.table_paddr) 159840fe15e0SLoGin .field("frame_allocator", &self.frame_allocator) 159940fe15e0SLoGin .finish() 160040fe15e0SLoGin } 160140fe15e0SLoGin } 160240fe15e0SLoGin 160340fe15e0SLoGin /// 页表刷新器的trait 16047ae679ddSLoGin pub trait Flusher<Arch: MemoryManagementArch> { 160540fe15e0SLoGin /// 取消对指定的page flusher的刷新 160640fe15e0SLoGin fn consume(&mut self, flush: PageFlush<Arch>); 160740fe15e0SLoGin } 160840fe15e0SLoGin 160940fe15e0SLoGin /// 用于刷新某个虚拟地址的刷新器。这个刷新器一经产生,就必须调用flush()方法, 161040fe15e0SLoGin /// 否则会造成对页表的更改被忽略,这是不安全的 161140fe15e0SLoGin #[must_use = "The flusher must call the 'flush()', or the changes to page table will be unsafely ignored."] 16127ae679ddSLoGin pub struct PageFlush<Arch: MemoryManagementArch> { 161340fe15e0SLoGin virt: VirtAddr, 161440fe15e0SLoGin phantom: PhantomData<Arch>, 161540fe15e0SLoGin } 161640fe15e0SLoGin 161740fe15e0SLoGin impl<Arch: MemoryManagementArch> PageFlush<Arch> { 161840fe15e0SLoGin pub fn new(virt: VirtAddr) -> Self { 161940fe15e0SLoGin return Self { 162040fe15e0SLoGin virt, 162140fe15e0SLoGin phantom: PhantomData, 162240fe15e0SLoGin }; 162340fe15e0SLoGin } 162440fe15e0SLoGin 162540fe15e0SLoGin pub fn flush(self) { 162640fe15e0SLoGin unsafe { Arch::invalidate_page(self.virt) }; 162740fe15e0SLoGin } 162840fe15e0SLoGin 162940fe15e0SLoGin /// 忽略掉这个刷新器 163040fe15e0SLoGin pub unsafe fn ignore(self) { 163140fe15e0SLoGin mem::forget(self); 163240fe15e0SLoGin } 163340fe15e0SLoGin } 163440fe15e0SLoGin 16357ae679ddSLoGin impl<Arch: MemoryManagementArch> Drop for PageFlush<Arch> { 16367ae679ddSLoGin fn drop(&mut self) { 16377ae679ddSLoGin unsafe { 16387ae679ddSLoGin MMArch::invalidate_page(self.virt); 16397ae679ddSLoGin } 16407ae679ddSLoGin } 16417ae679ddSLoGin } 16427ae679ddSLoGin 164340fe15e0SLoGin /// 用于刷新整个页表的刷新器。这个刷新器一经产生,就必须调用flush()方法, 164440fe15e0SLoGin /// 否则会造成对页表的更改被忽略,这是不安全的 164540fe15e0SLoGin #[must_use = "The flusher must call the 'flush()', or the changes to page table will be unsafely ignored."] 164640fe15e0SLoGin pub struct PageFlushAll<Arch: MemoryManagementArch> { 164740fe15e0SLoGin phantom: PhantomData<fn() -> Arch>, 164840fe15e0SLoGin } 164940fe15e0SLoGin 165040fe15e0SLoGin #[allow(dead_code)] 165140fe15e0SLoGin impl<Arch: MemoryManagementArch> PageFlushAll<Arch> { 165240fe15e0SLoGin pub fn new() -> Self { 165340fe15e0SLoGin return Self { 165440fe15e0SLoGin phantom: PhantomData, 165540fe15e0SLoGin }; 165640fe15e0SLoGin } 165740fe15e0SLoGin 165840fe15e0SLoGin pub fn flush(self) { 165940fe15e0SLoGin unsafe { Arch::invalidate_all() }; 166040fe15e0SLoGin } 166140fe15e0SLoGin 166240fe15e0SLoGin /// 忽略掉这个刷新器 166340fe15e0SLoGin pub unsafe fn ignore(self) { 166440fe15e0SLoGin mem::forget(self); 166540fe15e0SLoGin } 166640fe15e0SLoGin } 166740fe15e0SLoGin 166840fe15e0SLoGin impl<Arch: MemoryManagementArch> Flusher<Arch> for PageFlushAll<Arch> { 166940fe15e0SLoGin /// 为page flush all 实现consume,消除对单个页面的刷新。(刷新整个页表了就不需要刷新单个页面了) 167040fe15e0SLoGin fn consume(&mut self, flush: PageFlush<Arch>) { 167140fe15e0SLoGin unsafe { flush.ignore() }; 167240fe15e0SLoGin } 167340fe15e0SLoGin } 167440fe15e0SLoGin 167540fe15e0SLoGin impl<Arch: MemoryManagementArch, T: Flusher<Arch> + ?Sized> Flusher<Arch> for &mut T { 167640fe15e0SLoGin /// 允许一个flusher consume掉另一个flusher 167740fe15e0SLoGin fn consume(&mut self, flush: PageFlush<Arch>) { 167840fe15e0SLoGin <T as Flusher<Arch>>::consume(self, flush); 167940fe15e0SLoGin } 168040fe15e0SLoGin } 168140fe15e0SLoGin 168240fe15e0SLoGin impl<Arch: MemoryManagementArch> Flusher<Arch> for () { 168340fe15e0SLoGin fn consume(&mut self, _flush: PageFlush<Arch>) {} 168440fe15e0SLoGin } 168540fe15e0SLoGin 168640fe15e0SLoGin impl<Arch: MemoryManagementArch> Drop for PageFlushAll<Arch> { 168740fe15e0SLoGin fn drop(&mut self) { 168840fe15e0SLoGin unsafe { 168940fe15e0SLoGin Arch::invalidate_all(); 169040fe15e0SLoGin } 169140fe15e0SLoGin } 169240fe15e0SLoGin } 169340fe15e0SLoGin 169440fe15e0SLoGin /// 未在当前CPU上激活的页表的刷新器 169540fe15e0SLoGin /// 169640fe15e0SLoGin /// 如果页表没有在当前cpu上激活,那么需要发送ipi到其他核心,尝试在其他核心上刷新页表 169740fe15e0SLoGin /// 169840fe15e0SLoGin /// TODO: 这个方式很暴力,也许把它改成在指定的核心上刷新页表会更好。(可以测试一下开销) 169940fe15e0SLoGin #[derive(Debug)] 170040fe15e0SLoGin pub struct InactiveFlusher; 170140fe15e0SLoGin 170240fe15e0SLoGin impl InactiveFlusher { 170340fe15e0SLoGin pub fn new() -> Self { 170440fe15e0SLoGin return Self {}; 170540fe15e0SLoGin } 170640fe15e0SLoGin } 170740fe15e0SLoGin 170840fe15e0SLoGin impl Flusher<MMArch> for InactiveFlusher { 170940fe15e0SLoGin fn consume(&mut self, flush: PageFlush<MMArch>) { 171040fe15e0SLoGin unsafe { 171140fe15e0SLoGin flush.ignore(); 171240fe15e0SLoGin } 171340fe15e0SLoGin } 171440fe15e0SLoGin } 171540fe15e0SLoGin 171640fe15e0SLoGin impl Drop for InactiveFlusher { 171740fe15e0SLoGin fn drop(&mut self) { 171840fe15e0SLoGin // 发送刷新页表的IPI 171940fe15e0SLoGin send_ipi(IpiKind::FlushTLB, IpiTarget::Other); 172040fe15e0SLoGin } 172140fe15e0SLoGin } 172240fe15e0SLoGin 172340fe15e0SLoGin /// # 把一个地址向下对齐到页大小 172440fe15e0SLoGin pub fn round_down_to_page_size(addr: usize) -> usize { 172540fe15e0SLoGin addr & !(MMArch::PAGE_SIZE - 1) 172640fe15e0SLoGin } 172740fe15e0SLoGin 172840fe15e0SLoGin /// # 把一个地址向上对齐到页大小 172940fe15e0SLoGin pub fn round_up_to_page_size(addr: usize) -> usize { 173040fe15e0SLoGin round_down_to_page_size(addr + MMArch::PAGE_SIZE - 1) 173140fe15e0SLoGin } 1732