1*cf7f801eSMemoryShore use core::{ 2*cf7f801eSMemoryShore alloc::Layout, 3*cf7f801eSMemoryShore cmp::{max, min}, 4*cf7f801eSMemoryShore intrinsics::unlikely, 5*cf7f801eSMemoryShore panic, 6*cf7f801eSMemoryShore }; 7a17651b1SMemoryShore 8a17651b1SMemoryShore use alloc::sync::Arc; 9a17651b1SMemoryShore 10a17651b1SMemoryShore use crate::{ 11a17651b1SMemoryShore arch::{mm::PageMapper, MMArch}, 12*cf7f801eSMemoryShore libs::align::align_down, 13a17651b1SMemoryShore mm::{ 14*cf7f801eSMemoryShore page::{page_manager_lock_irqsave, EntryFlags}, 15a17651b1SMemoryShore ucontext::LockedVMA, 16a17651b1SMemoryShore VirtAddr, VmFaultReason, VmFlags, 17a17651b1SMemoryShore }, 18a17651b1SMemoryShore process::{ProcessManager, ProcessState}, 19a17651b1SMemoryShore }; 20a17651b1SMemoryShore 21a17651b1SMemoryShore use crate::mm::MemoryManagementArch; 22a17651b1SMemoryShore 23*cf7f801eSMemoryShore use super::{ 24*cf7f801eSMemoryShore allocator::page_frame::FrameAllocator, 25*cf7f801eSMemoryShore page::{page_reclaimer_lock_irqsave, Page, PageFlags}, 26*cf7f801eSMemoryShore }; 27*cf7f801eSMemoryShore 28a17651b1SMemoryShore bitflags! { 29a17651b1SMemoryShore pub struct FaultFlags: u64{ 30a17651b1SMemoryShore const FAULT_FLAG_WRITE = 1 << 0; 31a17651b1SMemoryShore const FAULT_FLAG_MKWRITE = 1 << 1; 32a17651b1SMemoryShore const FAULT_FLAG_ALLOW_RETRY = 1 << 2; 33a17651b1SMemoryShore const FAULT_FLAG_RETRY_NOWAIT = 1 << 3; 34a17651b1SMemoryShore const FAULT_FLAG_KILLABLE = 1 << 4; 35a17651b1SMemoryShore const FAULT_FLAG_TRIED = 1 << 5; 36a17651b1SMemoryShore const FAULT_FLAG_USER = 1 << 6; 37a17651b1SMemoryShore const FAULT_FLAG_REMOTE = 1 << 7; 38a17651b1SMemoryShore const FAULT_FLAG_INSTRUCTION = 1 << 8; 39a17651b1SMemoryShore const FAULT_FLAG_INTERRUPTIBLE =1 << 9; 40a17651b1SMemoryShore const FAULT_FLAG_UNSHARE = 1 << 10; 41a17651b1SMemoryShore const FAULT_FLAG_ORIG_PTE_VALID = 1 << 11; 42a17651b1SMemoryShore const FAULT_FLAG_VMA_LOCK = 1 << 12; 43a17651b1SMemoryShore } 44a17651b1SMemoryShore } 45a17651b1SMemoryShore 46a17651b1SMemoryShore /// # 缺页异常信息结构体 47a17651b1SMemoryShore /// 包含了页面错误处理的相关信息,例如出错的地址、VMA等 48a17651b1SMemoryShore #[derive(Debug)] 49*cf7f801eSMemoryShore pub struct PageFaultMessage<'a> { 50*cf7f801eSMemoryShore /// 产生缺页的VMA结构体 51*cf7f801eSMemoryShore vma: Arc<LockedVMA>, 52*cf7f801eSMemoryShore /// 缺页地址 53*cf7f801eSMemoryShore address: VirtAddr, 54*cf7f801eSMemoryShore /// 异常处理标志 55*cf7f801eSMemoryShore flags: FaultFlags, 56*cf7f801eSMemoryShore /// 页表映射器 57*cf7f801eSMemoryShore mapper: &'a mut PageMapper, 58*cf7f801eSMemoryShore /// 缺页的文件页在文件中的偏移量 59*cf7f801eSMemoryShore file_pgoff: Option<usize>, 60*cf7f801eSMemoryShore /// 缺页对应PageCache中的文件页 61*cf7f801eSMemoryShore page: Option<Arc<Page>>, 62*cf7f801eSMemoryShore /// 写时拷贝需要的页面 63*cf7f801eSMemoryShore cow_page: Option<Arc<Page>>, 64*cf7f801eSMemoryShore } 65*cf7f801eSMemoryShore 66*cf7f801eSMemoryShore impl<'a> PageFaultMessage<'a> { new( vma: Arc<LockedVMA>, address: VirtAddr, flags: FaultFlags, mapper: &'a mut PageMapper, ) -> Self67*cf7f801eSMemoryShore pub fn new( 68a17651b1SMemoryShore vma: Arc<LockedVMA>, 69a17651b1SMemoryShore address: VirtAddr, 70a17651b1SMemoryShore flags: FaultFlags, 71*cf7f801eSMemoryShore mapper: &'a mut PageMapper, 72*cf7f801eSMemoryShore ) -> Self { 73*cf7f801eSMemoryShore let guard = vma.lock_irqsave(); 74*cf7f801eSMemoryShore let file_pgoff = guard.file_page_offset().map(|file_page_offset| { 75*cf7f801eSMemoryShore ((address - guard.region().start()) >> MMArch::PAGE_SHIFT) + file_page_offset 76*cf7f801eSMemoryShore }); 77a17651b1SMemoryShore Self { 78a17651b1SMemoryShore vma: vma.clone(), 79*cf7f801eSMemoryShore address: VirtAddr::new(crate::libs::align::page_align_down(address.data())), 80a17651b1SMemoryShore flags, 81*cf7f801eSMemoryShore file_pgoff, 82*cf7f801eSMemoryShore page: None, 83*cf7f801eSMemoryShore mapper, 84*cf7f801eSMemoryShore cow_page: None, 85a17651b1SMemoryShore } 86a17651b1SMemoryShore } 87a17651b1SMemoryShore 88a17651b1SMemoryShore #[inline(always)] 89a17651b1SMemoryShore #[allow(dead_code)] vma(&self) -> Arc<LockedVMA>90a17651b1SMemoryShore pub fn vma(&self) -> Arc<LockedVMA> { 91a17651b1SMemoryShore self.vma.clone() 92a17651b1SMemoryShore } 93a17651b1SMemoryShore 94a17651b1SMemoryShore #[inline(always)] 95a17651b1SMemoryShore #[allow(dead_code)] address(&self) -> VirtAddr96a17651b1SMemoryShore pub fn address(&self) -> VirtAddr { 97a17651b1SMemoryShore self.address 98a17651b1SMemoryShore } 99a17651b1SMemoryShore 100a17651b1SMemoryShore #[inline(always)] 101a17651b1SMemoryShore #[allow(dead_code)] address_aligned_down(&self) -> VirtAddr102a17651b1SMemoryShore pub fn address_aligned_down(&self) -> VirtAddr { 103a17651b1SMemoryShore VirtAddr::new(crate::libs::align::page_align_down(self.address.data())) 104a17651b1SMemoryShore } 105a17651b1SMemoryShore 106a17651b1SMemoryShore #[inline(always)] 107a17651b1SMemoryShore #[allow(dead_code)] flags(&self) -> FaultFlags108a17651b1SMemoryShore pub fn flags(&self) -> FaultFlags { 109a17651b1SMemoryShore self.flags 110a17651b1SMemoryShore } 111a17651b1SMemoryShore } 112a17651b1SMemoryShore 113a17651b1SMemoryShore /// 缺页中断处理结构体 114a17651b1SMemoryShore pub struct PageFaultHandler; 115a17651b1SMemoryShore 116a17651b1SMemoryShore impl PageFaultHandler { 117a17651b1SMemoryShore /// 处理缺页异常 118a17651b1SMemoryShore /// ## 参数 119a17651b1SMemoryShore /// 120a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 121a17651b1SMemoryShore /// - `mapper`: 页表映射器 122a17651b1SMemoryShore /// 123a17651b1SMemoryShore /// ## 返回值 124a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 handle_mm_fault(mut pfm: PageFaultMessage) -> VmFaultReason125*cf7f801eSMemoryShore pub unsafe fn handle_mm_fault(mut pfm: PageFaultMessage) -> VmFaultReason { 126a17651b1SMemoryShore let flags = pfm.flags(); 127a17651b1SMemoryShore let vma = pfm.vma(); 128a17651b1SMemoryShore let current_pcb = ProcessManager::current_pcb(); 129a17651b1SMemoryShore let mut guard = current_pcb.sched_info().inner_lock_write_irqsave(); 130a17651b1SMemoryShore guard.set_state(ProcessState::Runnable); 131a17651b1SMemoryShore 132a17651b1SMemoryShore if !MMArch::vma_access_permitted( 133a17651b1SMemoryShore vma.clone(), 134a17651b1SMemoryShore flags.contains(FaultFlags::FAULT_FLAG_WRITE), 135a17651b1SMemoryShore flags.contains(FaultFlags::FAULT_FLAG_INSTRUCTION), 136a17651b1SMemoryShore flags.contains(FaultFlags::FAULT_FLAG_REMOTE), 137a17651b1SMemoryShore ) { 138a17651b1SMemoryShore return VmFaultReason::VM_FAULT_SIGSEGV; 139a17651b1SMemoryShore } 140a17651b1SMemoryShore 141*cf7f801eSMemoryShore let guard = vma.lock_irqsave(); 142a17651b1SMemoryShore let vm_flags = *guard.vm_flags(); 143a17651b1SMemoryShore drop(guard); 144a17651b1SMemoryShore if unlikely(vm_flags.contains(VmFlags::VM_HUGETLB)) { 145a17651b1SMemoryShore //TODO: 添加handle_hugetlb_fault处理大页缺页异常 146a17651b1SMemoryShore } else { 147*cf7f801eSMemoryShore Self::handle_normal_fault(&mut pfm); 148a17651b1SMemoryShore } 149a17651b1SMemoryShore 150a17651b1SMemoryShore VmFaultReason::VM_FAULT_COMPLETED 151a17651b1SMemoryShore } 152a17651b1SMemoryShore 153a17651b1SMemoryShore /// 处理普通页缺页异常 154a17651b1SMemoryShore /// ## 参数 155a17651b1SMemoryShore /// 156a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 157a17651b1SMemoryShore /// - `mapper`: 页表映射器 158a17651b1SMemoryShore /// 159a17651b1SMemoryShore /// ## 返回值 160a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 handle_normal_fault(pfm: &mut PageFaultMessage) -> VmFaultReason161*cf7f801eSMemoryShore pub unsafe fn handle_normal_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 162a17651b1SMemoryShore let address = pfm.address_aligned_down(); 163a17651b1SMemoryShore let vma = pfm.vma.clone(); 164*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 165a17651b1SMemoryShore if mapper.get_entry(address, 3).is_none() { 166a17651b1SMemoryShore mapper 167a17651b1SMemoryShore .allocate_table(address, 2) 168a17651b1SMemoryShore .expect("failed to allocate PUD table"); 169a17651b1SMemoryShore } 170*cf7f801eSMemoryShore let page_flags = vma.lock_irqsave().flags(); 171a17651b1SMemoryShore 172a17651b1SMemoryShore for level in 2..=3 { 173a17651b1SMemoryShore let level = MMArch::PAGE_LEVELS - level; 174a17651b1SMemoryShore if mapper.get_entry(address, level).is_none() { 175a17651b1SMemoryShore if vma.is_hugepage() { 176a17651b1SMemoryShore if vma.is_anonymous() { 177a17651b1SMemoryShore mapper.map_huge_page(address, page_flags); 178a17651b1SMemoryShore } 179a17651b1SMemoryShore } else if mapper.allocate_table(address, level - 1).is_none() { 180a17651b1SMemoryShore return VmFaultReason::VM_FAULT_OOM; 181a17651b1SMemoryShore } 182a17651b1SMemoryShore } 183a17651b1SMemoryShore } 184a17651b1SMemoryShore 185*cf7f801eSMemoryShore Self::handle_pte_fault(pfm) 186a17651b1SMemoryShore } 187a17651b1SMemoryShore 188a17651b1SMemoryShore /// 处理页表项异常 189a17651b1SMemoryShore /// ## 参数 190a17651b1SMemoryShore /// 191a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 192a17651b1SMemoryShore /// - `mapper`: 页表映射器 193a17651b1SMemoryShore /// 194a17651b1SMemoryShore /// ## 返回值 195a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 handle_pte_fault(pfm: &mut PageFaultMessage) -> VmFaultReason196*cf7f801eSMemoryShore pub unsafe fn handle_pte_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 197a17651b1SMemoryShore let address = pfm.address_aligned_down(); 198a17651b1SMemoryShore let flags = pfm.flags; 199a17651b1SMemoryShore let vma = pfm.vma.clone(); 20017dc5589SMemoryShore let mut ret = VmFaultReason::VM_FAULT_COMPLETED; 201*cf7f801eSMemoryShore let mapper = &pfm.mapper; 202*cf7f801eSMemoryShore 203*cf7f801eSMemoryShore // pte存在 204a17651b1SMemoryShore if let Some(mut entry) = mapper.get_entry(address, 0) { 205a17651b1SMemoryShore if !entry.present() { 206*cf7f801eSMemoryShore ret = Self::do_swap_page(pfm); 207a17651b1SMemoryShore } 208*cf7f801eSMemoryShore 209a17651b1SMemoryShore if entry.protnone() && vma.is_accessible() { 210*cf7f801eSMemoryShore ret = Self::do_numa_page(pfm); 211a17651b1SMemoryShore } 212*cf7f801eSMemoryShore 213a17651b1SMemoryShore if flags.intersects(FaultFlags::FAULT_FLAG_WRITE | FaultFlags::FAULT_FLAG_UNSHARE) { 214a17651b1SMemoryShore if !entry.write() { 215*cf7f801eSMemoryShore ret = Self::do_wp_page(pfm); 216a17651b1SMemoryShore } else { 217*cf7f801eSMemoryShore entry.set_flags(EntryFlags::from_data(MMArch::ENTRY_FLAG_DIRTY)); 218a17651b1SMemoryShore } 219a17651b1SMemoryShore } 220a17651b1SMemoryShore } else if vma.is_anonymous() { 221*cf7f801eSMemoryShore ret = Self::do_anonymous_page(pfm); 222a17651b1SMemoryShore } else { 223*cf7f801eSMemoryShore ret = Self::do_fault(pfm); 224a17651b1SMemoryShore } 225a17651b1SMemoryShore 226*cf7f801eSMemoryShore vma.lock_irqsave().set_mapped(true); 22717dc5589SMemoryShore 22817dc5589SMemoryShore return ret; 229a17651b1SMemoryShore } 230a17651b1SMemoryShore 231a17651b1SMemoryShore /// 处理匿名映射页缺页异常 232a17651b1SMemoryShore /// ## 参数 233a17651b1SMemoryShore /// 234a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 235a17651b1SMemoryShore /// - `mapper`: 页表映射器 236a17651b1SMemoryShore /// 237a17651b1SMemoryShore /// ## 返回值 238a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 do_anonymous_page(pfm: &mut PageFaultMessage) -> VmFaultReason239*cf7f801eSMemoryShore pub unsafe fn do_anonymous_page(pfm: &mut PageFaultMessage) -> VmFaultReason { 240a17651b1SMemoryShore let address = pfm.address_aligned_down(); 241a17651b1SMemoryShore let vma = pfm.vma.clone(); 242*cf7f801eSMemoryShore let guard = vma.lock_irqsave(); 243*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 244*cf7f801eSMemoryShore 245a17651b1SMemoryShore if let Some(flush) = mapper.map(address, guard.flags()) { 246a17651b1SMemoryShore flush.flush(); 247a17651b1SMemoryShore crate::debug::klog::mm::mm_debug_log( 248a17651b1SMemoryShore klog_types::AllocatorLogType::LazyAlloc(klog_types::AllocLogItem::new( 249a17651b1SMemoryShore Layout::from_size_align(MMArch::PAGE_SIZE, MMArch::PAGE_SIZE).unwrap(), 250a17651b1SMemoryShore Some(address.data()), 251a17651b1SMemoryShore Some(mapper.translate(address).unwrap().0.data()), 252a17651b1SMemoryShore )), 253a17651b1SMemoryShore klog_types::LogSource::Buddy, 254a17651b1SMemoryShore ); 255a17651b1SMemoryShore let paddr = mapper.translate(address).unwrap().0; 256*cf7f801eSMemoryShore let mut page_manager_guard = page_manager_lock_irqsave(); 257*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 258*cf7f801eSMemoryShore page.write_irqsave().insert_vma(vma.clone()); 259a17651b1SMemoryShore VmFaultReason::VM_FAULT_COMPLETED 260a17651b1SMemoryShore } else { 261a17651b1SMemoryShore VmFaultReason::VM_FAULT_OOM 262a17651b1SMemoryShore } 263a17651b1SMemoryShore } 264a17651b1SMemoryShore 265a17651b1SMemoryShore /// 处理文件映射页的缺页异常 266a17651b1SMemoryShore /// ## 参数 267a17651b1SMemoryShore /// 268a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 269a17651b1SMemoryShore /// - `mapper`: 页表映射器 270a17651b1SMemoryShore /// 271a17651b1SMemoryShore /// ## 返回值 272a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 do_fault(pfm: &mut PageFaultMessage) -> VmFaultReason273*cf7f801eSMemoryShore pub unsafe fn do_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 274*cf7f801eSMemoryShore if !pfm.flags().contains(FaultFlags::FAULT_FLAG_WRITE) { 275*cf7f801eSMemoryShore return Self::do_read_fault(pfm); 276*cf7f801eSMemoryShore } else if !pfm 277*cf7f801eSMemoryShore .vma() 278*cf7f801eSMemoryShore .lock_irqsave() 279*cf7f801eSMemoryShore .vm_flags() 280*cf7f801eSMemoryShore .contains(VmFlags::VM_SHARED) 281*cf7f801eSMemoryShore { 282*cf7f801eSMemoryShore return Self::do_cow_fault(pfm); 283*cf7f801eSMemoryShore } else { 284*cf7f801eSMemoryShore return Self::do_shared_fault(pfm); 285*cf7f801eSMemoryShore } 286a17651b1SMemoryShore } 287a17651b1SMemoryShore 288a17651b1SMemoryShore /// 处理私有文件映射的写时复制 289a17651b1SMemoryShore /// ## 参数 290a17651b1SMemoryShore /// 291a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 292a17651b1SMemoryShore /// - `mapper`: 页表映射器 293a17651b1SMemoryShore /// 294a17651b1SMemoryShore /// ## 返回值 295a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 do_cow_fault(pfm: &mut PageFaultMessage) -> VmFaultReason296*cf7f801eSMemoryShore pub unsafe fn do_cow_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 297*cf7f801eSMemoryShore let mut ret = Self::filemap_fault(pfm); 298*cf7f801eSMemoryShore 299*cf7f801eSMemoryShore if unlikely(ret.intersects( 300*cf7f801eSMemoryShore VmFaultReason::VM_FAULT_ERROR 301*cf7f801eSMemoryShore | VmFaultReason::VM_FAULT_NOPAGE 302*cf7f801eSMemoryShore | VmFaultReason::VM_FAULT_RETRY 303*cf7f801eSMemoryShore | VmFaultReason::VM_FAULT_DONE_COW, 304*cf7f801eSMemoryShore )) { 305*cf7f801eSMemoryShore return ret; 306*cf7f801eSMemoryShore } 307*cf7f801eSMemoryShore 308*cf7f801eSMemoryShore let cache_page = pfm.page.clone().unwrap(); 309*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 310*cf7f801eSMemoryShore 311*cf7f801eSMemoryShore let cow_page_phys = mapper.allocator_mut().allocate_one(); 312*cf7f801eSMemoryShore if cow_page_phys.is_none() { 313*cf7f801eSMemoryShore return VmFaultReason::VM_FAULT_OOM; 314*cf7f801eSMemoryShore } 315*cf7f801eSMemoryShore let cow_page_phys = cow_page_phys.unwrap(); 316*cf7f801eSMemoryShore 317*cf7f801eSMemoryShore let cow_page = Arc::new(Page::new(false, cow_page_phys)); 318*cf7f801eSMemoryShore pfm.cow_page = Some(cow_page.clone()); 319*cf7f801eSMemoryShore 320*cf7f801eSMemoryShore //复制PageCache内容到新的页内 321*cf7f801eSMemoryShore let new_frame = MMArch::phys_2_virt(cow_page_phys).unwrap(); 322*cf7f801eSMemoryShore (new_frame.data() as *mut u8).copy_from_nonoverlapping( 323*cf7f801eSMemoryShore MMArch::phys_2_virt(cache_page.read_irqsave().phys_address()) 324*cf7f801eSMemoryShore .unwrap() 325*cf7f801eSMemoryShore .data() as *mut u8, 326*cf7f801eSMemoryShore MMArch::PAGE_SIZE, 327a17651b1SMemoryShore ); 328*cf7f801eSMemoryShore 329*cf7f801eSMemoryShore let mut page_manager_guard = page_manager_lock_irqsave(); 330*cf7f801eSMemoryShore 331*cf7f801eSMemoryShore // 新页加入页管理器中 332*cf7f801eSMemoryShore page_manager_guard.insert(cow_page_phys, &cow_page); 333*cf7f801eSMemoryShore cow_page.write_irqsave().set_page_cache_index( 334*cf7f801eSMemoryShore cache_page.read_irqsave().page_cache(), 335*cf7f801eSMemoryShore cache_page.read_irqsave().index(), 336*cf7f801eSMemoryShore ); 337*cf7f801eSMemoryShore 338*cf7f801eSMemoryShore ret = ret.union(Self::finish_fault(pfm)); 339*cf7f801eSMemoryShore 340*cf7f801eSMemoryShore ret 341a17651b1SMemoryShore } 342a17651b1SMemoryShore 343a17651b1SMemoryShore /// 处理文件映射页的缺页异常 344a17651b1SMemoryShore /// ## 参数 345a17651b1SMemoryShore /// 346a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 347a17651b1SMemoryShore /// - `mapper`: 页表映射器 348a17651b1SMemoryShore /// 349a17651b1SMemoryShore /// ## 返回值 350a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 do_read_fault(pfm: &mut PageFaultMessage) -> VmFaultReason351*cf7f801eSMemoryShore pub unsafe fn do_read_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 352*cf7f801eSMemoryShore let fs = pfm.vma().lock_irqsave().vm_file().unwrap().inode().fs(); 353*cf7f801eSMemoryShore 354*cf7f801eSMemoryShore let mut ret = Self::do_fault_around(pfm); 355*cf7f801eSMemoryShore if !ret.is_empty() { 356*cf7f801eSMemoryShore return ret; 357*cf7f801eSMemoryShore } 358*cf7f801eSMemoryShore 359*cf7f801eSMemoryShore ret = fs.fault(pfm); 360*cf7f801eSMemoryShore 361*cf7f801eSMemoryShore ret = ret.union(Self::finish_fault(pfm)); 362*cf7f801eSMemoryShore 363*cf7f801eSMemoryShore ret 364a17651b1SMemoryShore } 365a17651b1SMemoryShore 366a17651b1SMemoryShore /// 处理对共享文件映射区写入引起的缺页 367a17651b1SMemoryShore /// ## 参数 368a17651b1SMemoryShore /// 369a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 370a17651b1SMemoryShore /// - `mapper`: 页表映射器 371a17651b1SMemoryShore /// 372a17651b1SMemoryShore /// ## 返回值 373a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 do_shared_fault(pfm: &mut PageFaultMessage) -> VmFaultReason374*cf7f801eSMemoryShore pub unsafe fn do_shared_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 375*cf7f801eSMemoryShore let mut ret = Self::filemap_fault(pfm); 376*cf7f801eSMemoryShore 377*cf7f801eSMemoryShore let cache_page = pfm.page.clone().expect("no cache_page in PageFaultMessage"); 378*cf7f801eSMemoryShore 379*cf7f801eSMemoryShore // 将pagecache页设为脏页,以便回收时能够回写 380*cf7f801eSMemoryShore cache_page.write_irqsave().add_flags(PageFlags::PG_DIRTY); 381*cf7f801eSMemoryShore ret = ret.union(Self::finish_fault(pfm)); 382*cf7f801eSMemoryShore 383*cf7f801eSMemoryShore ret 384a17651b1SMemoryShore } 385a17651b1SMemoryShore 386a17651b1SMemoryShore /// 处理被置换页面的缺页异常 387a17651b1SMemoryShore /// ## 参数 388a17651b1SMemoryShore /// 389a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 390a17651b1SMemoryShore /// - `mapper`: 页表映射器 391a17651b1SMemoryShore /// 392a17651b1SMemoryShore /// ## 返回值 393a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 394a17651b1SMemoryShore #[allow(unused_variables)] do_swap_page(pfm: &mut PageFaultMessage) -> VmFaultReason395*cf7f801eSMemoryShore pub unsafe fn do_swap_page(pfm: &mut PageFaultMessage) -> VmFaultReason { 396a17651b1SMemoryShore panic!( 397a17651b1SMemoryShore "do_swap_page has not yet been implemented, 398a17651b1SMemoryShore fault message: {:?}, 399a17651b1SMemoryShore pid: {}\n", 400a17651b1SMemoryShore pfm, 401a17651b1SMemoryShore crate::process::ProcessManager::current_pid().data() 402a17651b1SMemoryShore ); 403a17651b1SMemoryShore // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_swap_page 404a17651b1SMemoryShore } 405a17651b1SMemoryShore 406a17651b1SMemoryShore /// 处理NUMA的缺页异常 407a17651b1SMemoryShore /// ## 参数 408a17651b1SMemoryShore /// 409a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 410a17651b1SMemoryShore /// - `mapper`: 页表映射器 411a17651b1SMemoryShore /// 412a17651b1SMemoryShore /// ## 返回值 413a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 414a17651b1SMemoryShore #[allow(unused_variables)] do_numa_page(pfm: &mut PageFaultMessage) -> VmFaultReason415*cf7f801eSMemoryShore pub unsafe fn do_numa_page(pfm: &mut PageFaultMessage) -> VmFaultReason { 416a17651b1SMemoryShore panic!( 417a17651b1SMemoryShore "do_numa_page has not yet been implemented, 418a17651b1SMemoryShore fault message: {:?}, 419a17651b1SMemoryShore pid: {}\n", 420a17651b1SMemoryShore pfm, 421a17651b1SMemoryShore crate::process::ProcessManager::current_pid().data() 422a17651b1SMemoryShore ); 423a17651b1SMemoryShore // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_numa_page 424a17651b1SMemoryShore } 425a17651b1SMemoryShore 426a17651b1SMemoryShore /// 处理写保护页面的写保护异常 427a17651b1SMemoryShore /// ## 参数 428a17651b1SMemoryShore /// 429a17651b1SMemoryShore /// - `pfm`: 缺页异常信息 430a17651b1SMemoryShore /// - `mapper`: 页表映射器 431a17651b1SMemoryShore /// 432a17651b1SMemoryShore /// ## 返回值 433a17651b1SMemoryShore /// - VmFaultReason: 页面错误处理信息标志 do_wp_page(pfm: &mut PageFaultMessage) -> VmFaultReason434*cf7f801eSMemoryShore pub unsafe fn do_wp_page(pfm: &mut PageFaultMessage) -> VmFaultReason { 435a17651b1SMemoryShore let address = pfm.address_aligned_down(); 436a17651b1SMemoryShore let vma = pfm.vma.clone(); 437*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 438*cf7f801eSMemoryShore 439a17651b1SMemoryShore let old_paddr = mapper.translate(address).unwrap().0; 440a17651b1SMemoryShore let mut page_manager = page_manager_lock_irqsave(); 441*cf7f801eSMemoryShore let old_page = page_manager.get_unwrap(&old_paddr); 442*cf7f801eSMemoryShore let map_count = old_page.read_irqsave().map_count(); 443a17651b1SMemoryShore drop(page_manager); 444a17651b1SMemoryShore 445a17651b1SMemoryShore let mut entry = mapper.get_entry(address, 0).unwrap(); 446*cf7f801eSMemoryShore let new_flags = entry.flags().set_write(true).set_dirty(true); 447a17651b1SMemoryShore 448*cf7f801eSMemoryShore if vma.lock().vm_flags().contains(VmFlags::VM_SHARED) { 449*cf7f801eSMemoryShore // 共享映射,直接修改页表项保护位,标记为脏页 450*cf7f801eSMemoryShore let table = mapper.get_table(address, 0).unwrap(); 451*cf7f801eSMemoryShore let i = table.index_of(address).unwrap(); 452*cf7f801eSMemoryShore entry.set_flags(new_flags); 453*cf7f801eSMemoryShore table.set_entry(i, entry); 454*cf7f801eSMemoryShore 455*cf7f801eSMemoryShore old_page.write_irqsave().add_flags(PageFlags::PG_DIRTY); 456*cf7f801eSMemoryShore 457*cf7f801eSMemoryShore VmFaultReason::VM_FAULT_COMPLETED 458*cf7f801eSMemoryShore } else if vma.is_anonymous() { 459*cf7f801eSMemoryShore // 私有匿名映射,根据引用计数判断是否拷贝页面 460a17651b1SMemoryShore if map_count == 1 { 461a17651b1SMemoryShore let table = mapper.get_table(address, 0).unwrap(); 462a17651b1SMemoryShore let i = table.index_of(address).unwrap(); 463a17651b1SMemoryShore entry.set_flags(new_flags); 464a17651b1SMemoryShore table.set_entry(i, entry); 465a17651b1SMemoryShore VmFaultReason::VM_FAULT_COMPLETED 466a17651b1SMemoryShore } else if let Some(flush) = mapper.map(address, new_flags) { 467*cf7f801eSMemoryShore let mut page_manager_guard = page_manager_lock_irqsave(); 468*cf7f801eSMemoryShore let old_page = page_manager_guard.get_unwrap(&old_paddr); 469*cf7f801eSMemoryShore old_page.write_irqsave().remove_vma(&vma); 470*cf7f801eSMemoryShore // drop(page_manager_guard); 471a17651b1SMemoryShore 472a17651b1SMemoryShore flush.flush(); 473a17651b1SMemoryShore let paddr = mapper.translate(address).unwrap().0; 474*cf7f801eSMemoryShore // let mut page_manager_guard = page_manager_lock_irqsave(); 475*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 476*cf7f801eSMemoryShore page.write_irqsave().insert_vma(vma.clone()); 477a17651b1SMemoryShore 478a17651b1SMemoryShore (MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8).copy_from_nonoverlapping( 479a17651b1SMemoryShore MMArch::phys_2_virt(old_paddr).unwrap().data() as *mut u8, 480a17651b1SMemoryShore MMArch::PAGE_SIZE, 481a17651b1SMemoryShore ); 482a17651b1SMemoryShore 483a17651b1SMemoryShore VmFaultReason::VM_FAULT_COMPLETED 484a17651b1SMemoryShore } else { 485a17651b1SMemoryShore VmFaultReason::VM_FAULT_OOM 486a17651b1SMemoryShore } 487*cf7f801eSMemoryShore } else { 488*cf7f801eSMemoryShore // 私有文件映射,必须拷贝页面 489*cf7f801eSMemoryShore if let Some(flush) = mapper.map(address, new_flags) { 490*cf7f801eSMemoryShore let mut page_manager_guard = page_manager_lock_irqsave(); 491*cf7f801eSMemoryShore let old_page = page_manager_guard.get_unwrap(&old_paddr); 492*cf7f801eSMemoryShore old_page.write_irqsave().remove_vma(&vma); 493*cf7f801eSMemoryShore // drop(page_manager_guard); 494*cf7f801eSMemoryShore 495*cf7f801eSMemoryShore flush.flush(); 496*cf7f801eSMemoryShore let paddr = mapper.translate(address).unwrap().0; 497*cf7f801eSMemoryShore // let mut page_manager_guard = page_manager_lock_irqsave(); 498*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 499*cf7f801eSMemoryShore page.write_irqsave().insert_vma(vma.clone()); 500*cf7f801eSMemoryShore 501*cf7f801eSMemoryShore (MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8).copy_from_nonoverlapping( 502*cf7f801eSMemoryShore MMArch::phys_2_virt(old_paddr).unwrap().data() as *mut u8, 503*cf7f801eSMemoryShore MMArch::PAGE_SIZE, 504*cf7f801eSMemoryShore ); 505*cf7f801eSMemoryShore 506*cf7f801eSMemoryShore VmFaultReason::VM_FAULT_COMPLETED 507*cf7f801eSMemoryShore } else { 508*cf7f801eSMemoryShore VmFaultReason::VM_FAULT_OOM 509*cf7f801eSMemoryShore } 510*cf7f801eSMemoryShore } 511*cf7f801eSMemoryShore } 512*cf7f801eSMemoryShore 513*cf7f801eSMemoryShore /// 缺页附近页预读 514*cf7f801eSMemoryShore /// ## 参数 515*cf7f801eSMemoryShore /// 516*cf7f801eSMemoryShore /// - `pfm`: 缺页异常信息 517*cf7f801eSMemoryShore /// - `mapper`: 页表映射器 518*cf7f801eSMemoryShore /// 519*cf7f801eSMemoryShore /// ## 返回值 520*cf7f801eSMemoryShore /// - VmFaultReason: 页面错误处理信息标志 do_fault_around(pfm: &mut PageFaultMessage) -> VmFaultReason521*cf7f801eSMemoryShore pub unsafe fn do_fault_around(pfm: &mut PageFaultMessage) -> VmFaultReason { 522*cf7f801eSMemoryShore let vma = pfm.vma(); 523*cf7f801eSMemoryShore let address = pfm.address(); 524*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 525*cf7f801eSMemoryShore 526*cf7f801eSMemoryShore if mapper.get_table(address, 0).is_none() { 527*cf7f801eSMemoryShore mapper 528*cf7f801eSMemoryShore .allocate_table(address, 0) 529*cf7f801eSMemoryShore .expect("failed to allocate pte table"); 530*cf7f801eSMemoryShore } 531*cf7f801eSMemoryShore let vma_guard = vma.lock_irqsave(); 532*cf7f801eSMemoryShore let vma_region = *vma_guard.region(); 533*cf7f801eSMemoryShore drop(vma_guard); 534*cf7f801eSMemoryShore 535*cf7f801eSMemoryShore // 缺页在VMA中的偏移量 536*cf7f801eSMemoryShore let vm_pgoff = (address - vma_region.start()) >> MMArch::PAGE_SHIFT; 537*cf7f801eSMemoryShore 538*cf7f801eSMemoryShore // 缺页在PTE中的偏移量 539*cf7f801eSMemoryShore let pte_pgoff = (address.data() >> MMArch::PAGE_SHIFT) & (1 << MMArch::PAGE_ENTRY_SHIFT); 540*cf7f801eSMemoryShore 541*cf7f801eSMemoryShore // 缺页在文件中的偏移量 542*cf7f801eSMemoryShore let file_pgoff = pfm.file_pgoff.expect("no file_pgoff"); 543*cf7f801eSMemoryShore 544*cf7f801eSMemoryShore let vma_pages_count = (vma_region.end() - vma_region.start()) >> MMArch::PAGE_SHIFT; 545*cf7f801eSMemoryShore 546*cf7f801eSMemoryShore let fault_around_page_number = 16; 547*cf7f801eSMemoryShore 548*cf7f801eSMemoryShore // 开始位置不能超出当前pte和vma头部 549*cf7f801eSMemoryShore let from_pte = max( 550*cf7f801eSMemoryShore align_down(pte_pgoff, fault_around_page_number), 551*cf7f801eSMemoryShore pte_pgoff - min(vm_pgoff, pte_pgoff), 552*cf7f801eSMemoryShore ); 553*cf7f801eSMemoryShore 554*cf7f801eSMemoryShore // pte结束位置不能超过: 555*cf7f801eSMemoryShore // 1.最大预读上限(默认16) 556*cf7f801eSMemoryShore // 2.最大pte(512) 557*cf7f801eSMemoryShore // 3.vma结束位置(pte_pgoff + (vma_pages_count - vm_pgoff)计算出vma结束页号对当前pte开头的偏移) 558*cf7f801eSMemoryShore let to_pte = min( 559*cf7f801eSMemoryShore from_pte + fault_around_page_number, 560*cf7f801eSMemoryShore min( 561*cf7f801eSMemoryShore 1 << MMArch::PAGE_SHIFT, 562*cf7f801eSMemoryShore pte_pgoff + (vma_pages_count - vm_pgoff), 563*cf7f801eSMemoryShore ), 564*cf7f801eSMemoryShore ); 565*cf7f801eSMemoryShore 566*cf7f801eSMemoryShore // 预先分配pte页表(如果不存在) 567*cf7f801eSMemoryShore if mapper.get_table(address, 0).is_none() && mapper.allocate_table(address, 0).is_none() { 568*cf7f801eSMemoryShore return VmFaultReason::VM_FAULT_OOM; 569*cf7f801eSMemoryShore } 570*cf7f801eSMemoryShore 571*cf7f801eSMemoryShore let fs = pfm.vma().lock_irqsave().vm_file().unwrap().inode().fs(); 572*cf7f801eSMemoryShore // from_pte - pte_pgoff得出预读起始pte相对缺失页的偏移,加上pfm.file_pgoff(缺失页在文件中的偏移)得出起始页在文件中的偏移,结束pte同理 573*cf7f801eSMemoryShore fs.map_pages( 574*cf7f801eSMemoryShore pfm, 575*cf7f801eSMemoryShore file_pgoff + (from_pte - pte_pgoff), 576*cf7f801eSMemoryShore file_pgoff + (to_pte - pte_pgoff), 577*cf7f801eSMemoryShore ); 578*cf7f801eSMemoryShore 579*cf7f801eSMemoryShore VmFaultReason::empty() 580*cf7f801eSMemoryShore } 581*cf7f801eSMemoryShore 582*cf7f801eSMemoryShore /// 通用的VMA文件映射页面映射函数,将PageCache中的页面映射到进程空间 583*cf7f801eSMemoryShore /// ## 参数 584*cf7f801eSMemoryShore /// 585*cf7f801eSMemoryShore /// - `pfm`: 缺页异常信息 586*cf7f801eSMemoryShore /// - `mapper`: 页表映射器 587*cf7f801eSMemoryShore /// 588*cf7f801eSMemoryShore /// ## 返回值 589*cf7f801eSMemoryShore /// - VmFaultReason: 页面错误处理信息标志 filemap_map_pages( pfm: &mut PageFaultMessage, start_pgoff: usize, end_pgoff: usize, ) -> VmFaultReason590*cf7f801eSMemoryShore pub unsafe fn filemap_map_pages( 591*cf7f801eSMemoryShore pfm: &mut PageFaultMessage, 592*cf7f801eSMemoryShore 593*cf7f801eSMemoryShore start_pgoff: usize, 594*cf7f801eSMemoryShore end_pgoff: usize, 595*cf7f801eSMemoryShore ) -> VmFaultReason { 596*cf7f801eSMemoryShore let vma = pfm.vma(); 597*cf7f801eSMemoryShore let vma_guard = vma.lock_irqsave(); 598*cf7f801eSMemoryShore let file = vma_guard.vm_file().expect("no vm_file in vma"); 599*cf7f801eSMemoryShore let page_cache = file.inode().page_cache().unwrap(); 600*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 601*cf7f801eSMemoryShore 602*cf7f801eSMemoryShore // 起始页地址 603*cf7f801eSMemoryShore let addr = vma_guard.region().start 604*cf7f801eSMemoryShore + ((start_pgoff 605*cf7f801eSMemoryShore - vma_guard 606*cf7f801eSMemoryShore .file_page_offset() 607*cf7f801eSMemoryShore .expect("file_page_offset is none")) 608*cf7f801eSMemoryShore << MMArch::PAGE_SHIFT); 609*cf7f801eSMemoryShore 610*cf7f801eSMemoryShore for pgoff in start_pgoff..=end_pgoff { 611*cf7f801eSMemoryShore if let Some(page) = page_cache.get_page(pgoff) { 612*cf7f801eSMemoryShore let page_guard = page.read_irqsave(); 613*cf7f801eSMemoryShore if page_guard.flags().contains(PageFlags::PG_UPTODATE) { 614*cf7f801eSMemoryShore let phys = page_guard.phys_address(); 615*cf7f801eSMemoryShore 616*cf7f801eSMemoryShore let address = 617*cf7f801eSMemoryShore VirtAddr::new(addr.data() + ((pgoff - start_pgoff) << MMArch::PAGE_SHIFT)); 618*cf7f801eSMemoryShore mapper 619*cf7f801eSMemoryShore .map_phys(address, phys, vma_guard.flags()) 620*cf7f801eSMemoryShore .unwrap() 621*cf7f801eSMemoryShore .flush(); 622*cf7f801eSMemoryShore } 623*cf7f801eSMemoryShore } 624*cf7f801eSMemoryShore } 625*cf7f801eSMemoryShore VmFaultReason::empty() 626*cf7f801eSMemoryShore } 627*cf7f801eSMemoryShore 628*cf7f801eSMemoryShore /// 通用的VMA文件映射错误处理函数 629*cf7f801eSMemoryShore /// ## 参数 630*cf7f801eSMemoryShore /// 631*cf7f801eSMemoryShore /// - `pfm`: 缺页异常信息 632*cf7f801eSMemoryShore /// - `mapper`: 页表映射器 633*cf7f801eSMemoryShore /// 634*cf7f801eSMemoryShore /// ## 返回值 635*cf7f801eSMemoryShore /// - VmFaultReason: 页面错误处理信息标志 filemap_fault(pfm: &mut PageFaultMessage) -> VmFaultReason636*cf7f801eSMemoryShore pub unsafe fn filemap_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 637*cf7f801eSMemoryShore let vma = pfm.vma(); 638*cf7f801eSMemoryShore let vma_guard = vma.lock_irqsave(); 639*cf7f801eSMemoryShore let file = vma_guard.vm_file().expect("no vm_file in vma"); 640*cf7f801eSMemoryShore let page_cache = file.inode().page_cache().unwrap(); 641*cf7f801eSMemoryShore let file_pgoff = pfm.file_pgoff.expect("no file_pgoff"); 642*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 643*cf7f801eSMemoryShore let mut ret = VmFaultReason::empty(); 644*cf7f801eSMemoryShore 645*cf7f801eSMemoryShore if let Some(page) = page_cache.get_page(file_pgoff) { 646*cf7f801eSMemoryShore // TODO 异步从磁盘中预读页面进PageCache 647*cf7f801eSMemoryShore 648*cf7f801eSMemoryShore // 直接将PageCache中的页面作为要映射的页面 649*cf7f801eSMemoryShore pfm.page = Some(page.clone()); 650*cf7f801eSMemoryShore } else { 651*cf7f801eSMemoryShore // TODO 同步预读 652*cf7f801eSMemoryShore //涉及磁盘IO,返回标志为VM_FAULT_MAJOR 653*cf7f801eSMemoryShore ret = VmFaultReason::VM_FAULT_MAJOR; 654*cf7f801eSMemoryShore // let mut buf: Vec<u8> = vec![0; MMArch::PAGE_SIZE]; 655*cf7f801eSMemoryShore 656*cf7f801eSMemoryShore let allocator = mapper.allocator_mut(); 657*cf7f801eSMemoryShore 658*cf7f801eSMemoryShore // 分配一个物理页面作为加入PageCache的新页 659*cf7f801eSMemoryShore let new_cache_page = allocator.allocate_one().unwrap(); 660*cf7f801eSMemoryShore // (MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8) 661*cf7f801eSMemoryShore // .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE); 662*cf7f801eSMemoryShore file.pread( 663*cf7f801eSMemoryShore file_pgoff * MMArch::PAGE_SIZE, 664*cf7f801eSMemoryShore MMArch::PAGE_SIZE, 665*cf7f801eSMemoryShore core::slice::from_raw_parts_mut( 666*cf7f801eSMemoryShore MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8, 667*cf7f801eSMemoryShore MMArch::PAGE_SIZE, 668*cf7f801eSMemoryShore ), 669*cf7f801eSMemoryShore ) 670*cf7f801eSMemoryShore .expect("failed to read file to create pagecache page"); 671*cf7f801eSMemoryShore 672*cf7f801eSMemoryShore let page = Arc::new(Page::new(true, new_cache_page)); 673*cf7f801eSMemoryShore pfm.page = Some(page.clone()); 674*cf7f801eSMemoryShore 675*cf7f801eSMemoryShore page.write_irqsave().add_flags(PageFlags::PG_LRU); 676*cf7f801eSMemoryShore page_manager_lock_irqsave().insert(new_cache_page, &page); 677*cf7f801eSMemoryShore page_reclaimer_lock_irqsave().insert_page(new_cache_page, &page); 678*cf7f801eSMemoryShore page_cache.add_page(file_pgoff, &page); 679*cf7f801eSMemoryShore 680*cf7f801eSMemoryShore page.write_irqsave() 681*cf7f801eSMemoryShore .set_page_cache_index(Some(page_cache), Some(file_pgoff)); 682*cf7f801eSMemoryShore } 683*cf7f801eSMemoryShore ret 684*cf7f801eSMemoryShore } 685*cf7f801eSMemoryShore 686*cf7f801eSMemoryShore /// 将文件页映射到缺页地址 687*cf7f801eSMemoryShore /// ## 参数 688*cf7f801eSMemoryShore /// 689*cf7f801eSMemoryShore /// - `pfm`: 缺页异常信息 690*cf7f801eSMemoryShore /// - `mapper`: 页表映射器 691*cf7f801eSMemoryShore /// 692*cf7f801eSMemoryShore /// ## 返回值 693*cf7f801eSMemoryShore /// - VmFaultReason: 页面错误处理信息标志 finish_fault(pfm: &mut PageFaultMessage) -> VmFaultReason694*cf7f801eSMemoryShore pub unsafe fn finish_fault(pfm: &mut PageFaultMessage) -> VmFaultReason { 695*cf7f801eSMemoryShore let vma = pfm.vma(); 696*cf7f801eSMemoryShore let vma_guard = vma.lock_irqsave(); 697*cf7f801eSMemoryShore let flags = pfm.flags(); 698*cf7f801eSMemoryShore let cache_page = pfm.page.clone(); 699*cf7f801eSMemoryShore let cow_page = pfm.cow_page.clone(); 700*cf7f801eSMemoryShore let address = pfm.address(); 701*cf7f801eSMemoryShore let mapper = &mut pfm.mapper; 702*cf7f801eSMemoryShore 703*cf7f801eSMemoryShore let page_to_map = if flags.contains(FaultFlags::FAULT_FLAG_WRITE) 704*cf7f801eSMemoryShore && !vma_guard.vm_flags().contains(VmFlags::VM_SHARED) 705*cf7f801eSMemoryShore { 706*cf7f801eSMemoryShore // 私有文件映射的写时复制 707*cf7f801eSMemoryShore cow_page.expect("no cow_page in PageFaultMessage") 708*cf7f801eSMemoryShore } else { 709*cf7f801eSMemoryShore // 直接映射到PageCache 710*cf7f801eSMemoryShore cache_page.expect("no cache_page in PageFaultMessage") 711*cf7f801eSMemoryShore }; 712*cf7f801eSMemoryShore 713*cf7f801eSMemoryShore let page_phys = page_to_map.read_irqsave().phys_address(); 714*cf7f801eSMemoryShore 715*cf7f801eSMemoryShore mapper.map_phys(address, page_phys, vma_guard.flags()); 716*cf7f801eSMemoryShore page_to_map.write_irqsave().insert_vma(pfm.vma()); 717*cf7f801eSMemoryShore VmFaultReason::VM_FAULT_COMPLETED 718a17651b1SMemoryShore } 719a17651b1SMemoryShore } 720