From 17dc558977663433bd0181aa73ad131a1a265c1f Mon Sep 17 00:00:00 2001 From: MemoryShore <105195940+MemoryShore@users.noreply.github.com> Date: Wed, 1 May 2024 21:09:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dvma=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=A0=87=E5=BF=97=E9=94=99=E8=AF=AF=20(#801)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/mm/fault.rs | 25 +++++++++++++++++++------ kernel/src/mm/ucontext.rs | 28 ++++++++-------------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index 9f045ac5..71e0623a 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -75,6 +75,16 @@ impl PageFaultMessage { } } +impl Clone for PageFaultMessage { + fn clone(&self) -> Self { + Self { + vma: self.vma.clone(), + address: self.address, + flags: self.flags, + } + } +} + /// 缺页中断处理结构体 pub struct PageFaultHandler; @@ -167,27 +177,30 @@ impl PageFaultHandler { let address = pfm.address_aligned_down(); let flags = pfm.flags; let vma = pfm.vma.clone(); + let mut ret = VmFaultReason::VM_FAULT_COMPLETED; if let Some(mut entry) = mapper.get_entry(address, 0) { if !entry.present() { - return Self::do_swap_page(pfm, mapper); + ret = Self::do_swap_page(pfm.clone(), mapper); } if entry.protnone() && vma.is_accessible() { - return Self::do_numa_page(pfm, mapper); + ret = Self::do_numa_page(pfm.clone(), mapper); } if flags.intersects(FaultFlags::FAULT_FLAG_WRITE | FaultFlags::FAULT_FLAG_UNSHARE) { if !entry.write() { - return Self::do_wp_page(pfm, mapper); + ret = Self::do_wp_page(pfm.clone(), mapper); } else { entry.set_flags(PageFlags::from_data(MMArch::ENTRY_FLAG_DIRTY)); } } } else if vma.is_anonymous() { - return Self::do_anonymous_page(pfm, mapper); + ret = Self::do_anonymous_page(pfm.clone(), mapper); } else { - return Self::do_fault(pfm, mapper); + ret = Self::do_fault(pfm.clone(), mapper); } - VmFaultReason::VM_FAULT_COMPLETED + vma.lock().set_mapped(true); + + return ret; } /// 处理匿名映射页缺页异常 diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index 49c3408b..8d030e2b 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -299,18 +299,12 @@ impl InnerAddressSpace { prot_flags, map_flags, move |page, count, flags, _mapper, _flusher| { - Ok(LockedVMA::new(VMA { - region: VirtRegion::new( - page.virt_address(), - count.data() * MMArch::PAGE_SIZE, - ), + Ok(LockedVMA::new(VMA::new( + VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE), vm_flags, flags, - mapped: true, - user_address_space: None, - self_ref: Weak::default(), - provider: Provider::Allocated, - })) + false, + ))) }, )? }; @@ -1033,7 +1027,6 @@ impl LockedVMA { mut flusher: impl Flusher, ) -> Result<(), SystemError> { let mut guard = self.lock(); - assert!(guard.mapped); for page in guard.region.pages() { // 暂时要求所有的页帧都已经映射到页表 // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了 @@ -1052,7 +1045,6 @@ impl LockedVMA { // todo: 如果当前vma与文件相关,完善文件相关的逻辑 let mut guard = self.lock(); - assert!(guard.mapped); // 获取物理页的anon_vma的守卫 let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> = @@ -1347,7 +1339,6 @@ impl VMA { mapper: &mut PageMapper, mut flusher: impl Flusher, ) -> Result<(), SystemError> { - assert!(self.mapped); for page in self.region.pages() { // kdebug!("remap page {:?}", page.virt_address()); if mapper.translate(page.virt_address()).is_some() { @@ -1477,18 +1468,15 @@ impl VMA { flusher.consume(r); cur_dest = cur_dest.next(); } - let r = LockedVMA::new(VMA { - region: VirtRegion::new( + let r = LockedVMA::new(VMA::new( + VirtRegion::new( destination.virt_address(), page_count.data() * MMArch::PAGE_SIZE, ), vm_flags, flags, - mapped: true, - user_address_space: None, - self_ref: Weak::default(), - provider: Provider::Allocated, - }); + true, + )); drop(flusher); // kdebug!("VMA::zeroed: flusher dropped");