Browse Source

修复vma映射标志错误 (#801)

MemoryShore 10 months ago
parent
commit
17dc558977
2 changed files with 27 additions and 26 deletions
  1. 19 6
      kernel/src/mm/fault.rs
  2. 8 20
      kernel/src/mm/ucontext.rs

+ 19 - 6
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;
     }
 
     /// 处理匿名映射页缺页异常

+ 8 - 20
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<MMArch>,
     ) -> 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<MMArch>,
     ) -> 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");